From 6f8ed8c1fe4ca32cb5350a3797ddc1f6e5e88950 Mon Sep 17 00:00:00 2001 From: daa84 Date: Wed, 17 May 2017 18:25:50 +0300 Subject: [PATCH] Use popover instead of popup --- src/popup_menu.rs | 93 +++++++++++++++++++++++++---------------------- src/shell.rs | 37 +++++-------------- 2 files changed, 59 insertions(+), 71 deletions(-) diff --git a/src/popup_menu.rs b/src/popup_menu.rs index ac32987..be0c82c 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -1,9 +1,8 @@ use std::rc::Rc; use std::cell::RefCell; +use gtk; use gtk::prelude::*; -use gtk::{Window, WindowType, TreeView, TreeViewColumn, TreePath, CellRendererText, ListStore, - Type, ScrolledWindow, PolicyType}; use glib; use pango::FontDescription; use gdk::{EventButton, EventType}; @@ -17,45 +16,51 @@ use input; const MIN_CONTENT_HEIGHT: i32 = 250; pub struct PopupMenu { - menu: Window, - list: TreeView, + popover: gtk::Popover, + tree: gtk::TreeView, } impl PopupMenu { - pub fn new(nvim: Rc>, + pub fn new(drawing: >k::DrawingArea, + nvim: Rc>, font_desc: &FontDescription, - menu: &Vec>, + menu_items: &Vec>, selected: i64, x: i32, y: i32, - grow_up: bool) + width: i32, + height: i32) -> PopupMenu { - let win = Window::new(WindowType::Popup); + let popover = gtk::Popover::new(Some(drawing)); + popover.set_modal(false); - let tree = create_list(menu, font_desc); + let tree = create_list(menu_items, font_desc); tree.set_can_focus(false); let nvim_ref = nvim.clone(); - tree.connect_button_press_event(move |tree, ev| tree_button_press(tree, ev, &mut *nvim_ref.borrow_mut())); + tree.connect_button_press_event(move |tree, ev| { + tree_button_press(tree, ev, &mut *nvim_ref.borrow_mut()) + }); - let scroll = ScrolledWindow::new(None, None); - scroll.set_policy(PolicyType::Never, PolicyType::Automatic); + 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(&tree); - win.add(&scroll); - if grow_up { - win.move_(x, y - MIN_CONTENT_HEIGHT); - } else { - win.move_(x, y); - } + scroll.show_all(); + popover.add(&scroll); + popover.set_pointing_to(>k::Rectangle { + x, + y, + width, + height, + }); - win.connect_key_press_event(move |_, ev| input::gtk_key_press(&mut *nvim.borrow_mut(), ev)); + popover.connect_key_press_event(move |_, ev| { + input::gtk_key_press(&mut *nvim.borrow_mut(), ev) + }); - let popup = PopupMenu { - menu: win, - list: tree, - }; + let popup = PopupMenu { popover, tree }; popup.select(selected); @@ -63,28 +68,34 @@ impl PopupMenu { } pub fn show(&self) { - self.menu.show_all(); + let popover = self.popover.clone(); + gtk::idle_add(move || { + popover.popup(); + Continue(false) + }); } pub fn hide(self) { - self.menu.destroy(); + gtk::idle_add(move || { + self.popover.destroy(); + Continue(false) + }); } pub fn select(&self, selected: i64) { if selected >= 0 { - let selected_path = TreePath::new_from_string(&format!("{}", selected)); - self.list - .get_selection() - .select_path(&selected_path); - self.list.scroll_to_cell(Some(&selected_path), None, false, 0.0, 0.0); + let selected_path = gtk::TreePath::new_from_string(&format!("{}", selected)); + self.tree.get_selection().select_path(&selected_path); + self.tree + .scroll_to_cell(Some(&selected_path), None, false, 0.0, 0.0); } else { - self.list.get_selection().unselect_all(); + self.tree.get_selection().unselect_all(); } } } -fn create_list(menu: &Vec>, font_desc: &FontDescription) -> TreeView { - let tree = TreeView::new(); +fn create_list(menu: &Vec>, font_desc: &FontDescription) -> gtk::TreeView { + let tree = gtk::TreeView::new(); if menu.is_empty() { return tree; @@ -96,7 +107,7 @@ fn create_list(menu: &Vec>, font_desc: &FontDescription) -> TreeView { append_column(&tree, i as i32, &font_str); } - let list_store = ListStore::new(&vec![Type::String; columns]); + let list_store = gtk::ListStore::new(&vec![gtk::Type::String; columns]); let all_column_ids: Vec = (0..columns).map(|i| i as u32).collect(); for line in menu { @@ -110,17 +121,17 @@ fn create_list(menu: &Vec>, font_desc: &FontDescription) -> TreeView { tree } -fn append_column(tree: &TreeView, id: i32, font_str: &str) { - let renderer = CellRendererText::new(); +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 = TreeViewColumn::new(); + 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: &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 { return Inhibit(false); } @@ -128,11 +139,7 @@ fn tree_button_press(tree: &TreeView, ev: &EventButton, nvim: &mut Neovim) -> In let (paths, ..) = tree.get_selection().get_selected_rows(); let selected_idx = if !paths.is_empty() { let ids = paths[0].get_indices(); - if !ids.is_empty() { - ids[0] - } else { - -1 - } + if !ids.is_empty() { ids[0] } else { -1 } } else { -1 }; diff --git a/src/shell.rs b/src/shell.rs index fce78ff..4edf3f1 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -345,7 +345,6 @@ fn gtk_focus_out(state: &mut State) -> Inhibit { let point = state.model.cur_point(); state.on_redraw(&RepaintMode::Area(point)); - state.close_popup_menu(); Inhibit(false) } @@ -820,37 +819,19 @@ impl RedrawEvents for State { -> RepaintMode { match (&self.line_height, &self.char_width) { (&Some(line_height), &Some(char_width)) => { - let parent = sync::Weak::upgrade(&self.parent).unwrap(); - let comps = parent.borrow(); - let window = comps.window(); - let screen = window.get_screen().unwrap(); - let height = screen.get_height(); + let point = ModelRect::point(col as usize, row as usize); + let (x, y, width, height) = point.to_area(line_height, char_width); - let point = ModelRect::point((col + 1) as usize, (row + 1) as usize); - let (x, y, ..) = point.to_area(line_height, char_width); - let translated = self.drawing_area.translate_coordinates(window, x, y); - let (x, y) = if let Some((x, y)) = translated { - (x, y) - } else { - (x, y) - }; - - let (win_x, win_y) = window.get_position(); - let (abs_x, mut abs_y) = (win_x + x, win_y + y); - - let grow_up = abs_y > height / 2; - - if grow_up { - abs_y -= line_height as i32; - } - - self.popup_menu = Some(PopupMenu::new(self.nvim.as_ref().unwrap().clone(), + self.popup_menu = Some(PopupMenu::new( + &self.drawing_area, + self.nvim.as_ref().unwrap().clone(), &self.font_desc, menu, selected, - abs_x, - abs_y, - grow_up)); + x, + y, + width, + height)); self.popup_menu.as_ref().unwrap().show(); } _ => (),