Wrap text, hide popover
This commit is contained in:
		
							parent
							
								
									0b2fc12c4e
								
							
						
					
					
						commit
						83061366dd
					
				| @ -9,19 +9,17 @@ use cairo; | |||||||
| 
 | 
 | ||||||
| use neovim_lib::Value; | use neovim_lib::Value; | ||||||
| 
 | 
 | ||||||
| use ui_model::{UiModel, Attrs}; | use ui_model::{Attrs, ModelLayout}; | ||||||
| use ui::UiMutex; | use ui::UiMutex; | ||||||
| use render; | use render; | ||||||
| use shell; | use shell; | ||||||
| use cursor; | use cursor; | ||||||
| 
 | 
 | ||||||
| pub struct Level { | pub struct Level { | ||||||
|     model: UiModel, |     model_layout: ModelLayout, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Level { | impl Level { | ||||||
|     const COLUMNS_STEP: u64 = 50; |  | ||||||
|     const ROWS_STEP: u64 = 10; |  | ||||||
| 
 | 
 | ||||||
|     pub fn from( |     pub fn from( | ||||||
|         content: Vec<(HashMap<String, Value>, String)>, |         content: Vec<(HashMap<String, Value>, String)>, | ||||||
| @ -33,57 +31,41 @@ impl Level { | |||||||
|         //TODO: double width chars
 |         //TODO: double width chars
 | ||||||
|         //TODO: im
 |         //TODO: im
 | ||||||
| 
 | 
 | ||||||
|         let prompt = prompt_lines(firstc, prompt, indent); |         let content_line: Vec<(Option<Attrs>, Vec<char>)> = content | ||||||
|         let content: Vec<(Attrs, Vec<char>)> = content |  | ||||||
|             .iter() |             .iter() | ||||||
|             .map(|c| (Attrs::from_value_map(&c.0), c.1.chars().collect())) |             .map(|c| (Some(Attrs::from_value_map(&c.0)), c.1.chars().collect())) | ||||||
|             .collect(); |             .collect(); | ||||||
|  |         let prompt_lines = prompt_lines(firstc, prompt, indent); | ||||||
| 
 | 
 | ||||||
|         let width = (content.iter().map(|c| c.1.len()).count() + |         let mut content: Vec<_> = prompt_lines.into_iter().map(|line| vec![line]).collect(); | ||||||
|                          prompt.last().map_or(0, |p| p.len())) as u64; |  | ||||||
|         let columns = ((width / Level::COLUMNS_STEP) + 1) * Level::COLUMNS_STEP; |  | ||||||
|         let rows = ((prompt.len() as u64 / Level::ROWS_STEP) + 1) * Level::ROWS_STEP; |  | ||||||
| 
 | 
 | ||||||
|         let mut model = UiModel::new(rows, columns); |         if content.is_empty() { | ||||||
| 
 |             content.push(content_line); | ||||||
|         for (row_idx, prompt_line) in prompt.iter().enumerate() { |  | ||||||
|             for (col_idx, &ch) in prompt_line.iter().enumerate() { |  | ||||||
|                 model.set_cursor(row_idx, col_idx); |  | ||||||
|                 model.put(ch, false, None); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let mut col_idx = 0; |  | ||||||
|         let row_idx = if prompt.len() > 0 { |  | ||||||
|             prompt.len() - 1 |  | ||||||
|         } else { |         } else { | ||||||
|             0 |             content.last_mut().map(|line| line.extend(content_line)); | ||||||
|         }; |  | ||||||
|         for (attr, ch_list) in content { |  | ||||||
|             for ch in ch_list { |  | ||||||
|                 model.set_cursor(row_idx, col_idx); |  | ||||||
|                 model.put(ch, false, Some(&attr)); |  | ||||||
|                 col_idx += 1; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Level { model } |         let mut model_layout = ModelLayout::new(); | ||||||
|  |         // TODO: calculate width
 | ||||||
|  |         model_layout.layout(content, 5); | ||||||
|  | 
 | ||||||
|  |         Level { model_layout } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn update_cache(&mut self, render_state: &shell::RenderState) { |     fn update_cache(&mut self, render_state: &shell::RenderState) { | ||||||
|         render::shape_dirty( |         render::shape_dirty( | ||||||
|             &render_state.font_ctx, |             &render_state.font_ctx, | ||||||
|             &mut self.model, |             &mut self.model_layout.model, | ||||||
|             &render_state.color_model, |             &render_state.color_model, | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn prompt_lines(firstc: String, prompt: String, indent: u64) -> Vec<Vec<char>> { | fn prompt_lines(firstc: String, prompt: String, indent: u64) -> Vec<(Option<Attrs>, Vec<char>)> { | ||||||
|     if !firstc.is_empty() { |     if !firstc.is_empty() { | ||||||
|         vec![firstc.chars().chain((0..indent).map(|_| ' ')).collect()] |         vec![(None, firstc.chars().chain((0..indent).map(|_| ' ')).collect())] | ||||||
|     } else if !prompt.is_empty() { |     } else if !prompt.is_empty() { | ||||||
|         prompt.lines().map(|l| l.chars().collect()).collect() |         prompt.lines().map(|l| (None, l.chars().collect())).collect() | ||||||
|     } else { |     } else { | ||||||
|         vec![] |         vec![] | ||||||
|     } |     } | ||||||
| @ -121,10 +103,12 @@ impl CmdLine { | |||||||
|     pub fn new(drawing: >k::DrawingArea, render_state: Rc<RefCell<shell::RenderState>>) -> Self { |     pub fn new(drawing: >k::DrawingArea, render_state: Rc<RefCell<shell::RenderState>>) -> Self { | ||||||
|         let popover = gtk::Popover::new(Some(drawing)); |         let popover = gtk::Popover::new(Some(drawing)); | ||||||
|         popover.set_modal(false); |         popover.set_modal(false); | ||||||
|  |         popover.set_position(gtk::PositionType::Top); | ||||||
|  | 
 | ||||||
|         let edit_frame = gtk::Frame::new(None); |         let edit_frame = gtk::Frame::new(None); | ||||||
|         edit_frame.set_shadow_type(gtk::ShadowType::In); |         edit_frame.set_shadow_type(gtk::ShadowType::In); | ||||||
|         let drawing_area = gtk::DrawingArea::new(); |         let drawing_area = gtk::DrawingArea::new(); | ||||||
|         drawing_area.set_size_request(50, 50); |         drawing_area.set_size_request(150, 50); | ||||||
|         edit_frame.add(&drawing_area); |         edit_frame.add(&drawing_area); | ||||||
|         edit_frame.show_all(); |         edit_frame.show_all(); | ||||||
| 
 | 
 | ||||||
| @ -166,11 +150,32 @@ impl CmdLine { | |||||||
|         state.levels.push(level); |         state.levels.push(level); | ||||||
|         if !self.displyed { |         if !self.displyed { | ||||||
|             self.displyed = true; |             self.displyed = true; | ||||||
|  |             let allocation = self.popover.get_relative_to().unwrap().get_allocation(); | ||||||
|  |             self.popover.set_pointing_to(>k::Rectangle { | ||||||
|  |                 x: allocation.width / 2, | ||||||
|  |                 y: allocation.height / 2, | ||||||
|  |                 width: 1, | ||||||
|  |                 height: 1, | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|             self.popover.popup(); |             self.popover.popup(); | ||||||
|         } else { |         } else { | ||||||
|             state.drawing_area.queue_draw() |             state.drawing_area.queue_draw() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn hide_level(&mut self, level_idx: u64) { | ||||||
|  |         let mut state = self.state.borrow_mut(); | ||||||
|  | 
 | ||||||
|  |         if level_idx as usize == state.levels.len() { | ||||||
|  |             state.levels.pop(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if state.levels.is_empty() { | ||||||
|  |             self.popover.hide(); | ||||||
|  |             self.displyed = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gtk_draw( | fn gtk_draw( | ||||||
| @ -188,7 +193,7 @@ fn gtk_draw( | |||||||
|             ctx, |             ctx, | ||||||
|             cursor, |             cursor, | ||||||
|             &render_state.font_ctx, |             &render_state.font_ctx, | ||||||
|             &level.model, |             &level.model_layout.model, | ||||||
|             &render_state.color_model, |             &render_state.color_model, | ||||||
|             &render_state.mode, |             &render_state.mode, | ||||||
|         ); |         ); | ||||||
|  | |||||||
| @ -76,6 +76,11 @@ pub trait RedrawEvents { | |||||||
|         indent: u64, |         indent: u64, | ||||||
|         level: u64, |         level: u64, | ||||||
|     ) -> RepaintMode; |     ) -> RepaintMode; | ||||||
|  |     
 | ||||||
|  |     fn cmdline_hide( | ||||||
|  |         &mut self, | ||||||
|  |         level: u64, | ||||||
|  |     ) -> RepaintMode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub trait GuiApi { | pub trait GuiApi { | ||||||
| @ -256,6 +261,7 @@ pub fn call( | |||||||
|             ui.mode_info_set(try_bool!(args[0]), mode_info) |             ui.mode_info_set(try_bool!(args[0]), mode_info) | ||||||
|         } |         } | ||||||
|         "cmdline_show" => call!(ui->cmdline_show(args: ext, uint, str, str, uint, uint)), |         "cmdline_show" => call!(ui->cmdline_show(args: ext, uint, str, str, uint, uint)), | ||||||
|  |         "cmdline_hide" => call!(ui->cmdline_hide(args: uint)), | ||||||
|         _ => { |         _ => { | ||||||
|             println!("Event {}({:?})", method, args); |             println!("Event {}({:?})", method, args); | ||||||
|             RepaintMode::Nothing |             RepaintMode::Nothing | ||||||
|  | |||||||
| @ -1189,6 +1189,11 @@ impl RedrawEvents for State { | |||||||
|         self.cmd_line.show_level(content, pos, firstc, prompt, indent, level); |         self.cmd_line.show_level(content, pos, firstc, prompt, indent, level); | ||||||
|         RepaintMode::Nothing |         RepaintMode::Nothing | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fn cmdline_hide(&mut self, level: u64) -> RepaintMode { | ||||||
|  |         self.cmd_line.hide_level(level); | ||||||
|  |         RepaintMode::Nothing | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl CursorRedrawCb for State { | impl CursorRedrawCb for State { | ||||||
|  | |||||||
| @ -2,11 +2,13 @@ mod cell; | |||||||
| mod line; | mod line; | ||||||
| mod item; | mod item; | ||||||
| mod model_rect; | mod model_rect; | ||||||
|  | mod model_layout; | ||||||
| 
 | 
 | ||||||
| pub use self::cell::{Cell, Attrs}; | pub use self::cell::{Cell, Attrs}; | ||||||
| pub use self::line::{Line, StyledLine}; | pub use self::line::{Line, StyledLine}; | ||||||
| pub use self::item::Item; | pub use self::item::Item; | ||||||
| pub use self::model_rect::{ModelRect, ModelRectVec}; | pub use self::model_rect::{ModelRect, ModelRectVec}; | ||||||
|  | pub use self::model_layout::ModelLayout; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| pub struct UiModel { | pub struct UiModel { | ||||||
|  | |||||||
							
								
								
									
										45
									
								
								src/ui_model/model_layout.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/ui_model/model_layout.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | use ui_model::{UiModel, Attrs}; | ||||||
|  | 
 | ||||||
|  | pub struct ModelLayout { | ||||||
|  |     pub model: UiModel, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ModelLayout { | ||||||
|  |     const COLUMNS_STEP: u64 = 50; | ||||||
|  |     const ROWS_STEP: u64 = 10; | ||||||
|  | 
 | ||||||
|  |     pub fn new() -> Self { | ||||||
|  |         ModelLayout { model: UiModel::new(ModelLayout::ROWS_STEP, ModelLayout::COLUMNS_STEP) } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Wrap all lines into model
 | ||||||
|  |     pub fn layout(&mut self, lines: Vec<Vec<(Option<Attrs>, Vec<char>)>>, columns: u64) { | ||||||
|  |         if lines.len() > self.model.rows || columns as usize > self.model.columns { | ||||||
|  |             let model_cols = ((columns / ModelLayout::COLUMNS_STEP) + 1) * | ||||||
|  |                 ModelLayout::COLUMNS_STEP; | ||||||
|  |             let model_rows = ((lines.len() as u64 / ModelLayout::ROWS_STEP) + 1) * | ||||||
|  |                 ModelLayout::ROWS_STEP; | ||||||
|  | 
 | ||||||
|  |             self.model = UiModel::new(model_rows, model_cols); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         let mut col_idx = 0; | ||||||
|  |         let mut row_idx = 0; | ||||||
|  |         for content in lines { | ||||||
|  |             for (attr, ch_list) in content { | ||||||
|  |                 for ch in ch_list { | ||||||
|  |                     if col_idx >= columns { | ||||||
|  |                         col_idx = 0; | ||||||
|  |                         row_idx += 1; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     self.model.set_cursor(row_idx, col_idx as usize); | ||||||
|  |                     self.model.put(ch, false, attr.as_ref()); | ||||||
|  |                     col_idx += 1; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             row_idx += 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 daa
						daa