From 14a154f62864049c907dfefd5c2a68855e827d2a Mon Sep 17 00:00:00 2001 From: daa84 Date: Mon, 22 May 2017 18:38:36 +0300 Subject: [PATCH] Popup menu refactor --- src/popup_menu.rs | 106 +++++++++++++++++++++++++++++++++------------- src/shell.rs | 20 ++++----- 2 files changed, 87 insertions(+), 39 deletions(-) diff --git a/src/popup_menu.rs b/src/popup_menu.rs index 1b29acb..5d0e5a6 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -1,5 +1,5 @@ use std::rc::Rc; -use std::cell::RefCell; +use std::cell::{RefCell, Cell}; use gtk; use gtk::prelude::*; @@ -15,13 +15,14 @@ use input; const MIN_CONTENT_HEIGHT: i32 = 250; -pub struct PopupMenu { - popover: gtk::Popover, +struct State { + nvim: Rc>, tree: gtk::TreeView, + renderer: gtk::CellRendererText, } -impl PopupMenu { - pub fn new(drawing: >k::DrawingArea, +impl State { + pub fn new(popover: >k::Popover, nvim: Rc>, font_desc: &FontDescription, menu_items: &Vec>, @@ -30,10 +31,7 @@ impl PopupMenu { y: i32, width: i32, height: i32) - -> PopupMenu { - let popover = gtk::Popover::new(Some(drawing)); - popover.set_modal(false); - + -> Self { let tree = create_list(menu_items, font_desc); tree.set_can_focus(false); @@ -50,32 +48,25 @@ impl PopupMenu { scroll.show_all(); popover.add(&scroll); popover.set_pointing_to(>k::Rectangle { - x, - y, - width, - height, - }); + x, + y, + width, + height, + }); - popover.connect_key_press_event(move |_, ev| { - input::gtk_key_press(&mut *nvim.borrow_mut(), ev) - }); - let popup = PopupMenu { popover, tree }; + let state = State { + nvim, + tree, + renderer: gtk::CellRendererText::new(), + }; - popup.select(selected); + state.select(selected); - popup + state } - pub fn show(&self) { - self.popover.popup(); - } - - pub fn hide(self) { - self.popover.destroy(); - } - - pub fn select(&self, selected: i64) { + fn select(&self, selected: i64) { if selected >= 0 { let selected_path = gtk::TreePath::new_from_string(&format!("{}", selected)); self.tree.get_selection().select_path(&selected_path); @@ -87,6 +78,63 @@ impl PopupMenu { } } +pub struct PopupMenu { + popover: gtk::Popover, + state: Rc>>, +} + +impl PopupMenu { + pub fn new(drawing: >k::DrawingArea) -> PopupMenu { + let state = Rc::new(Cell::new(None)); + let popover = gtk::Popover::new(Some(drawing)); + popover.set_modal(false); + + + let state_ref = state.clone(); + popover.connect_key_press_event(move |_, ev| { + let mut state: &mut State = state_ref.get_mut().as_mut().unwrap(); + input::gtk_key_press(&mut *state.nvim.borrow_mut(), ev) + }); + + let popup = PopupMenu { popover, state }; + + + popup + } + + pub fn show(&self, + nvim: Rc>, + font_desc: &FontDescription, + menu_items: &Vec>, + selected: i64, + x: i32, + y: i32, + width: i32, + height: i32) { + self.state + .replace(Some(State::new(&self.popover, + nvim, + font_desc, + menu_items, + selected, + x, + y, + width, + height))); + self.popover.popup(); + } + + pub fn hide(self) { + self.popover.popdown(); + let tree = self.state.get_mut().take().unwrap().tree; + self.popover.remove(&tree); + tree.destroy(); + } + + pub fn select(&self, selected: i64) { + } +} + fn create_list(menu: &Vec>, font_desc: &FontDescription) -> gtk::TreeView { let tree = gtk::TreeView::new(); diff --git a/src/shell.rs b/src/shell.rs index cfd96be..cc41c24 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -48,7 +48,7 @@ pub struct State { nvim: Option>>, font_desc: FontDescription, cursor: Option, - popup_menu: Option, + popup_menu: PopupMenu, settings: Rc>, line_height: Option, @@ -61,9 +61,12 @@ pub struct State { impl State { pub fn new(settings: Rc>, parent: &Arc>) -> State { + let drawing_area = DrawingArea::new(); + let popup_menu = PopupMenu::new(&drawing_area); + State { model: UiModel::new(24, 80), - drawing_area: DrawingArea::new(), + drawing_area, nvim: None, cur_attrs: None, bg_color: COLOR_BLACK, @@ -73,7 +76,7 @@ impl State { mouse_enabled: true, font_desc: FontDescription::from_string(DEFAULT_FONT_NAME), cursor: None, - popup_menu: None, + popup_menu, settings: settings, line_height: None, @@ -822,17 +825,14 @@ impl RedrawEvents for State { let point = ModelRect::point(col as usize, row as usize); let (x, y, width, height) = point.to_area(line_height, char_width); - self.popup_menu = Some(PopupMenu::new( - &self.drawing_area, - self.nvim.as_ref().unwrap().clone(), + self.popup_menu.show(self.nvim.as_ref().unwrap().clone(), &self.font_desc, menu, selected, x, y, width, - height)); - self.popup_menu.as_ref().unwrap().show(); + height); } _ => (), }; @@ -841,12 +841,12 @@ impl RedrawEvents for State { } fn popupmenu_hide(&mut self) -> RepaintMode { - self.popup_menu.take().unwrap().hide(); + self.popup_menu.hide(); RepaintMode::Nothing } fn popupmenu_select(&mut self, selected: i64) -> RepaintMode { - self.popup_menu.as_mut().unwrap().select(selected); + self.popup_menu.select(selected); RepaintMode::Nothing } }