From 5f7019dd0dfc79f26d4b0397838aa6ddce091df4 Mon Sep 17 00:00:00 2001 From: daa84 Date: Wed, 24 May 2017 17:51:16 +0300 Subject: [PATCH] Adapt size to contents --- src/popup_menu.rs | 52 +++++++++++++++++++++++++++++++++++++++-------- src/project.rs | 12 +++++++++-- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/popup_menu.rs b/src/popup_menu.rs index 6f54fc3..720c59e 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -1,5 +1,6 @@ use std::rc::Rc; use std::cell::RefCell; +use std::cmp::min; use gtk; use gtk::prelude::*; @@ -13,12 +14,13 @@ use nvim::ErrorReport; use input; -const MIN_CONTENT_HEIGHT: i32 = 250; +const MAX_VISIBLE_ROWS: i32 = 10; struct State { nvim: Option>>, renderer: gtk::CellRendererText, tree: gtk::TreeView, + scroll: gtk::ScrolledWindow, } impl State { @@ -27,6 +29,7 @@ impl State { nvim: None, renderer: gtk::CellRendererText::new(), tree: gtk::TreeView::new(), + scroll: gtk::ScrolledWindow::new(None, None), } } @@ -74,7 +77,6 @@ impl State { } self.tree.set_model(Some(&list_store)); - self.tree.set_headers_visible(false); } fn append_column(&self, id: i32) { @@ -96,6 +98,17 @@ impl State { self.tree.get_selection().unselect_all(); } } + + fn calc_treeview_height(&self) -> i32 { + let (_, natural_size) = self.renderer.get_preferred_height(&self.tree); + let (_, ypad) = self.renderer.get_padding(); + + let row_height = natural_size + ypad; + + let actual_count = self.tree.get_model().unwrap().iter_n_children(None); + + row_height * min(actual_count, MAX_VISIBLE_ROWS) as i32 + } } pub struct PopupMenu { @@ -115,13 +128,11 @@ impl PopupMenu { 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); + state.scroll.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic); - scroll.add(&state.tree); - scroll.show_all(); - popover.add(&scroll); + state.scroll.add(&state.tree); + state.scroll.show_all(); + popover.add(&state.scroll); let state = Rc::new(RefCell::new(state)); let state_ref = state.clone(); @@ -130,6 +141,10 @@ impl PopupMenu { let mut nvim = state.nvim.as_ref().unwrap().borrow_mut(); tree_button_press(tree, ev, &mut *nvim) }); + + let state_ref = state.clone(); + state.borrow().tree.connect_size_allocate(move |_, _| on_treeview_allocate(state_ref.clone())); + let state_ref = state.clone(); popover.connect_key_press_event(move |_, ev| { let state = state_ref.borrow(); @@ -229,3 +244,24 @@ fn find_scroll_count(selected_idx: i32, target_idx: i32) -> i32 { selected_idx - target_idx } } + + +fn on_treeview_allocate(state: Rc>) { + let treeview_height = state.borrow().calc_treeview_height(); + + idle_add(move || { + let state = state.borrow(); + + // strange solution to make gtk assertions happy + let previous_height = state.scroll.get_max_content_height(); + if previous_height < treeview_height { + state.scroll.set_max_content_height(treeview_height); + state.scroll.set_min_content_height(treeview_height); + } else if previous_height > treeview_height { + state.scroll.set_min_content_height(treeview_height); + state.scroll.set_max_content_height(treeview_height); + } + Continue(false) + }); +} + diff --git a/src/project.rs b/src/project.rs index a7a5b5a..0814390 100644 --- a/src/project.rs +++ b/src/project.rs @@ -335,8 +335,16 @@ fn on_treeview_allocate(projects: Rc>) { idle_add(move || { let prj = projects.borrow(); - prj.scroll.set_min_content_height(treeview_height); - prj.scroll.set_max_content_height(treeview_height); + + // strange solution to make gtk assertions happy + let previous_height = prj.scroll.get_max_content_height(); + if previous_height < treeview_height { + prj.scroll.set_max_content_height(treeview_height); + prj.scroll.set_min_content_height(treeview_height); + } else if previous_height > treeview_height { + prj.scroll.set_min_content_height(treeview_height); + prj.scroll.set_max_content_height(treeview_height); + } Continue(false) }); }