Code reorganisation
This commit is contained in:
		
							parent
							
								
									14a154f628
								
							
						
					
					
						commit
						905b95343d
					
				| @ -1,5 +1,5 @@ | |||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| use std::cell::{RefCell, Cell}; | use std::cell::RefCell; | ||||||
| 
 | 
 | ||||||
| use gtk; | use gtk; | ||||||
| use gtk::prelude::*; | use gtk::prelude::*; | ||||||
| @ -16,54 +16,74 @@ use input; | |||||||
| const MIN_CONTENT_HEIGHT: i32 = 250; | const MIN_CONTENT_HEIGHT: i32 = 250; | ||||||
| 
 | 
 | ||||||
| struct State { | struct State { | ||||||
|     nvim: Rc<RefCell<Neovim>>, |     nvim: Option<Rc<RefCell<Neovim>>>, | ||||||
|     tree: gtk::TreeView, |  | ||||||
|     renderer: gtk::CellRendererText, |     renderer: gtk::CellRendererText, | ||||||
|  |     tree: gtk::TreeView, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl State { | impl State { | ||||||
|     pub fn new(popover: >k::Popover, |     pub fn new() -> Self { | ||||||
|                nvim: Rc<RefCell<Neovim>>, |         State { | ||||||
|  |             nvim: None, | ||||||
|  |             renderer: gtk::CellRendererText::new(), | ||||||
|  |             tree: gtk::TreeView::new(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn before_show(&mut self, | ||||||
|  |                    nvim: &Rc<RefCell<Neovim>>, | ||||||
|                    font_desc: &FontDescription, |                    font_desc: &FontDescription, | ||||||
|                    menu_items: &Vec<Vec<&str>>, |                    menu_items: &Vec<Vec<&str>>, | ||||||
|                selected: i64, |                    selected: i64) { | ||||||
|                x: i32, |         if self.nvim.is_none() { | ||||||
|                y: i32, |             self.nvim = Some(nvim.clone()); | ||||||
|                width: i32, |         } | ||||||
|                height: i32) |  | ||||||
|                -> Self { |  | ||||||
|         let tree = create_list(menu_items, font_desc); |  | ||||||
|         tree.set_can_focus(false); |  | ||||||
| 
 | 
 | ||||||
|         let nvim_ref = nvim.clone(); |         self.update_tree(menu_items, font_desc); | ||||||
|         tree.connect_button_press_event(move |tree, ev| { |         self.select(selected); | ||||||
|                                             tree_button_press(tree, ev, &mut *nvim_ref.borrow_mut()) |     } | ||||||
|                                         }); |  | ||||||
| 
 | 
 | ||||||
|         let scroll = gtk::ScrolledWindow::new(None, None); |     fn update_tree(&self, menu: &Vec<Vec<&str>>, font_desc: &FontDescription) { | ||||||
|         scroll.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic); |         if menu.is_empty() { | ||||||
|         scroll.set_min_content_height(MIN_CONTENT_HEIGHT); |             return; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         scroll.add(&tree); |         self.renderer | ||||||
|         scroll.show_all(); |             .set_property_font(Some(&font_desc.to_string())); | ||||||
|         popover.add(&scroll); |  | ||||||
|         popover.set_pointing_to(>k::Rectangle { |  | ||||||
|                                     x, |  | ||||||
|                                     y, |  | ||||||
|                                     width, |  | ||||||
|                                     height, |  | ||||||
|                                 }); |  | ||||||
| 
 | 
 | ||||||
|  |         let col_count = menu.get(0).unwrap().len(); | ||||||
|  |         let columns = self.tree.get_columns(); | ||||||
| 
 | 
 | ||||||
|         let state = State { |         if columns.len() != col_count { | ||||||
|             nvim, |             for col in columns { | ||||||
|             tree, |                 self.tree.remove_column(&col); | ||||||
|             renderer: gtk::CellRendererText::new(), |             } | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         state.select(selected); |             for i in 0..col_count { | ||||||
|  |                 self.append_column(i as i32); | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         state |         let list_store = gtk::ListStore::new(&vec![gtk::Type::String; col_count]); | ||||||
|  |         let all_column_ids: Vec<u32> = (0..col_count).map(|i| i as u32).collect(); | ||||||
|  | 
 | ||||||
|  |         for line in menu { | ||||||
|  |             let line_array: Vec<&glib::ToValue> = | ||||||
|  |                 line.iter().map(|v| v as &glib::ToValue).collect(); | ||||||
|  |             list_store.insert_with_values(None, &all_column_ids, &line_array[..]); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         self.tree.set_model(Some(&list_store)); | ||||||
|  |         self.tree.set_headers_visible(false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn append_column(&self, id: i32) { | ||||||
|  |         let renderer = &self.renderer; | ||||||
|  | 
 | ||||||
|  |         let column = gtk::TreeViewColumn::new(); | ||||||
|  |         column.pack_start(renderer, true); | ||||||
|  |         column.add_attribute(renderer, "text", id); | ||||||
|  |         self.tree.append_column(&column); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn select(&self, selected: i64) { |     fn select(&self, selected: i64) { | ||||||
| @ -80,30 +100,56 @@ impl State { | |||||||
| 
 | 
 | ||||||
| pub struct PopupMenu { | pub struct PopupMenu { | ||||||
|     popover: gtk::Popover, |     popover: gtk::Popover, | ||||||
|     state: Rc<Cell<Option<State>>>, |     open: bool, | ||||||
|  | 
 | ||||||
|  |     state: Rc<RefCell<State>>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl PopupMenu { | impl PopupMenu { | ||||||
|     pub fn new(drawing: >k::DrawingArea) -> PopupMenu { |     pub fn new(drawing: >k::DrawingArea) -> PopupMenu { | ||||||
|         let state = Rc::new(Cell::new(None)); |         let state = State::new(); | ||||||
|         let popover = gtk::Popover::new(Some(drawing)); |         let popover = gtk::Popover::new(Some(drawing)); | ||||||
|         popover.set_modal(false); |         popover.set_modal(false); | ||||||
| 
 | 
 | ||||||
|  |         state.tree.set_headers_visible(false); | ||||||
|  |         state.tree.set_can_focus(false); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |         let scroll = gtk::ScrolledWindow::new(None, None); | ||||||
|  |         scroll.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic); | ||||||
|  |         scroll.set_min_content_height(MIN_CONTENT_HEIGHT); | ||||||
|  | 
 | ||||||
|  |         scroll.add(&state.tree); | ||||||
|  |         scroll.show_all(); | ||||||
|  |         popover.add(&scroll); | ||||||
|  | 
 | ||||||
|  |         let state = Rc::new(RefCell::new(state)); | ||||||
|  |         let state_ref = state.clone(); | ||||||
|  |         state.borrow().tree.connect_button_press_event(move |tree, ev| { | ||||||
|  |                                             let state = state_ref.borrow(); | ||||||
|  |                                             let mut nvim = state.nvim.as_ref().unwrap().borrow_mut(); | ||||||
|  |                                             tree_button_press(tree, ev, &mut *nvim) | ||||||
|  |                                         }); | ||||||
|         let state_ref = state.clone(); |         let state_ref = state.clone(); | ||||||
|         popover.connect_key_press_event(move |_, ev| { |         popover.connect_key_press_event(move |_, ev| { | ||||||
|             let mut state: &mut State = state_ref.get_mut().as_mut().unwrap(); |                                             let state = state_ref.borrow(); | ||||||
|             input::gtk_key_press(&mut *state.nvim.borrow_mut(), ev) |                                             let mut nvim = state.nvim.as_ref().unwrap().borrow_mut(); | ||||||
|  |                                             input::gtk_key_press(&mut *nvim, ev) | ||||||
|                                         }); |                                         }); | ||||||
| 
 | 
 | ||||||
|         let popup = PopupMenu { popover, state }; |         PopupMenu { | ||||||
| 
 |             popover, | ||||||
| 
 |             state, | ||||||
|         popup |             open: false, | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn show(&self, |     pub fn is_open(&self) -> bool { | ||||||
|                 nvim: Rc<RefCell<Neovim>>, |         self.open | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn show(&mut self, | ||||||
|  |                 nvim: &Rc<RefCell<Neovim>>, | ||||||
|                 font_desc: &FontDescription, |                 font_desc: &FontDescription, | ||||||
|                 menu_items: &Vec<Vec<&str>>, |                 menu_items: &Vec<Vec<&str>>, | ||||||
|                 selected: i64, |                 selected: i64, | ||||||
| @ -111,66 +157,32 @@ impl PopupMenu { | |||||||
|                 y: i32, |                 y: i32, | ||||||
|                 width: i32, |                 width: i32, | ||||||
|                 height: i32) { |                 height: i32) { | ||||||
|         self.state | 
 | ||||||
|             .replace(Some(State::new(&self.popover, |         self.open = true; | ||||||
|                                      nvim, | 
 | ||||||
|                                      font_desc, |         self.popover | ||||||
|                                      menu_items, |             .set_pointing_to(>k::Rectangle { | ||||||
|                                      selected, |  | ||||||
|                                  x, |                                  x, | ||||||
|                                  y, |                                  y, | ||||||
|                                  width, |                                  width, | ||||||
|                                      height))); |                                  height, | ||||||
|  |                              }); | ||||||
|  |         self.state | ||||||
|  |             .borrow_mut() | ||||||
|  |             .before_show(&nvim, font_desc, menu_items, selected); | ||||||
|         self.popover.popup(); |         self.popover.popup(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn hide(self) { |     pub fn hide(&mut self) { | ||||||
|  |         self.open = false; | ||||||
|         self.popover.popdown(); |         self.popover.popdown(); | ||||||
|         let tree = self.state.get_mut().take().unwrap().tree; |  | ||||||
|         self.popover.remove(&tree); |  | ||||||
|         tree.destroy(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn select(&self, selected: i64) { |     pub fn select(&self, selected: i64) { | ||||||
|  |         self.state.borrow().select(selected); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn create_list(menu: &Vec<Vec<&str>>, font_desc: &FontDescription) -> gtk::TreeView { |  | ||||||
|     let tree = gtk::TreeView::new(); |  | ||||||
| 
 |  | ||||||
|     if menu.is_empty() { |  | ||||||
|         return tree; |  | ||||||
|     } |  | ||||||
|     let columns = menu.get(0).unwrap().len(); |  | ||||||
| 
 |  | ||||||
|     let font_str = font_desc.to_string(); |  | ||||||
|     for i in 0..columns { |  | ||||||
|         append_column(&tree, i as i32, &font_str); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     let list_store = gtk::ListStore::new(&vec![gtk::Type::String; columns]); |  | ||||||
|     let all_column_ids: Vec<u32> = (0..columns).map(|i| i as u32).collect(); |  | ||||||
| 
 |  | ||||||
|     for line in menu { |  | ||||||
|         let line_array: Vec<&glib::ToValue> = line.iter().map(|v| v as &glib::ToValue).collect(); |  | ||||||
|         list_store.insert_with_values(None, &all_column_ids, &line_array[..]); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     tree.set_model(Some(&list_store)); |  | ||||||
|     tree.set_headers_visible(false); |  | ||||||
| 
 |  | ||||||
|     tree |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn append_column(tree: >k::TreeView, id: i32, font_str: &str) { |  | ||||||
|     let renderer = gtk::CellRendererText::new(); |  | ||||||
|     renderer.set_property_font(Some(font_str)); |  | ||||||
| 
 |  | ||||||
|     let column = gtk::TreeViewColumn::new(); |  | ||||||
|     column.pack_start(&renderer, true); |  | ||||||
|     column.add_attribute(&renderer, "text", id); |  | ||||||
|     tree.append_column(&column); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| fn tree_button_press(tree: >k::TreeView, ev: &EventButton, nvim: &mut Neovim) -> Inhibit { | fn tree_button_press(tree: >k::TreeView, ev: &EventButton, nvim: &mut Neovim) -> Inhibit { | ||||||
|     if ev.get_event_type() != EventType::ButtonPress { |     if ev.get_event_type() != EventType::ButtonPress { | ||||||
|  | |||||||
| @ -138,7 +138,7 @@ impl State { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn close_popup_menu(&self) { |     fn close_popup_menu(&self) { | ||||||
|         if self.popup_menu.is_some() { |         if self.popup_menu.is_open() { | ||||||
|             let mut nvim = self.nvim(); |             let mut nvim = self.nvim(); | ||||||
|             nvim.input("<Esc>").report_err(&mut *nvim); |             nvim.input("<Esc>").report_err(&mut *nvim); | ||||||
|         } |         } | ||||||
| @ -825,7 +825,7 @@ impl RedrawEvents for State { | |||||||
|                 let point = ModelRect::point(col as usize, row as usize); |                 let point = ModelRect::point(col as usize, row as usize); | ||||||
|                 let (x, y, width, height) = point.to_area(line_height, char_width); |                 let (x, y, width, height) = point.to_area(line_height, char_width); | ||||||
| 
 | 
 | ||||||
|                 self.popup_menu.show(self.nvim.as_ref().unwrap().clone(), |                 self.popup_menu.show(self.nvim.as_ref().unwrap(), | ||||||
|                                                       &self.font_desc, |                                                       &self.font_desc, | ||||||
|                                                       menu, |                                                       menu, | ||||||
|                                                       selected, |                                                       selected, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 daa84
						daa84