Adapt size to contents
This commit is contained in:
parent
04c60cd61f
commit
5f7019dd0d
@ -1,5 +1,6 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
@ -13,12 +14,13 @@ use nvim::ErrorReport;
|
|||||||
|
|
||||||
use input;
|
use input;
|
||||||
|
|
||||||
const MIN_CONTENT_HEIGHT: i32 = 250;
|
const MAX_VISIBLE_ROWS: i32 = 10;
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
nvim: Option<Rc<RefCell<Neovim>>>,
|
nvim: Option<Rc<RefCell<Neovim>>>,
|
||||||
renderer: gtk::CellRendererText,
|
renderer: gtk::CellRendererText,
|
||||||
tree: gtk::TreeView,
|
tree: gtk::TreeView,
|
||||||
|
scroll: gtk::ScrolledWindow,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
@ -27,6 +29,7 @@ impl State {
|
|||||||
nvim: None,
|
nvim: None,
|
||||||
renderer: gtk::CellRendererText::new(),
|
renderer: gtk::CellRendererText::new(),
|
||||||
tree: gtk::TreeView::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_model(Some(&list_store));
|
||||||
self.tree.set_headers_visible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_column(&self, id: i32) {
|
fn append_column(&self, id: i32) {
|
||||||
@ -96,6 +98,17 @@ impl State {
|
|||||||
self.tree.get_selection().unselect_all();
|
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 {
|
pub struct PopupMenu {
|
||||||
@ -115,13 +128,11 @@ impl PopupMenu {
|
|||||||
state.tree.set_can_focus(false);
|
state.tree.set_can_focus(false);
|
||||||
|
|
||||||
|
|
||||||
let scroll = gtk::ScrolledWindow::new(None, None);
|
state.scroll.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic);
|
||||||
scroll.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic);
|
|
||||||
scroll.set_min_content_height(MIN_CONTENT_HEIGHT);
|
|
||||||
|
|
||||||
scroll.add(&state.tree);
|
state.scroll.add(&state.tree);
|
||||||
scroll.show_all();
|
state.scroll.show_all();
|
||||||
popover.add(&scroll);
|
popover.add(&state.scroll);
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(state));
|
let state = Rc::new(RefCell::new(state));
|
||||||
let state_ref = state.clone();
|
let state_ref = state.clone();
|
||||||
@ -130,6 +141,10 @@ impl PopupMenu {
|
|||||||
let mut nvim = state.nvim.as_ref().unwrap().borrow_mut();
|
let mut nvim = state.nvim.as_ref().unwrap().borrow_mut();
|
||||||
tree_button_press(tree, ev, &mut *nvim)
|
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();
|
let state_ref = state.clone();
|
||||||
popover.connect_key_press_event(move |_, ev| {
|
popover.connect_key_press_event(move |_, ev| {
|
||||||
let state = state_ref.borrow();
|
let state = state_ref.borrow();
|
||||||
@ -229,3 +244,24 @@ fn find_scroll_count(selected_idx: i32, target_idx: i32) -> i32 {
|
|||||||
selected_idx - target_idx
|
selected_idx - target_idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn on_treeview_allocate(state: Rc<RefCell<State>>) {
|
||||||
|
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)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -335,8 +335,16 @@ fn on_treeview_allocate(projects: Rc<RefCell<Projects>>) {
|
|||||||
|
|
||||||
idle_add(move || {
|
idle_add(move || {
|
||||||
let prj = projects.borrow();
|
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)
|
Continue(false)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user