Add colors/height/current
This commit is contained in:
parent
d288caf37f
commit
1560748f1f
@ -17,6 +17,7 @@ use ui::UiMutex;
|
||||
use render::{self, CellMetrics};
|
||||
use shell;
|
||||
use cursor;
|
||||
use popup_menu;
|
||||
|
||||
pub struct Level {
|
||||
model_layout: ModelLayout,
|
||||
@ -265,6 +266,8 @@ pub struct CmdLine {
|
||||
popover: gtk::Popover,
|
||||
wild_tree: gtk::TreeView,
|
||||
wild_scroll: gtk::ScrolledWindow,
|
||||
wild_css_provider: gtk::CssProvider,
|
||||
wild_renderer: gtk::CellRendererText,
|
||||
displyed: bool,
|
||||
state: Arc<UiMutex<State>>,
|
||||
}
|
||||
@ -287,8 +290,7 @@ impl CmdLine {
|
||||
|
||||
drawing_area.connect_draw(clone!(state => move |_, ctx| gtk_draw(ctx, &state)));
|
||||
|
||||
|
||||
let (wild_scroll, wild_tree) = CmdLine::create_widlmenu();
|
||||
let (wild_scroll, wild_tree, wild_css_provider, wild_renderer) = CmdLine::create_widlmenu();
|
||||
content.pack_start(&wild_scroll, false, true, 0);
|
||||
popover.add(&content);
|
||||
|
||||
@ -301,11 +303,22 @@ impl CmdLine {
|
||||
displyed: false,
|
||||
wild_scroll,
|
||||
wild_tree,
|
||||
wild_css_provider,
|
||||
wild_renderer,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_widlmenu() -> (gtk::ScrolledWindow, gtk::TreeView) {
|
||||
fn create_widlmenu() -> (
|
||||
gtk::ScrolledWindow,
|
||||
gtk::TreeView,
|
||||
gtk::CssProvider,
|
||||
gtk::CellRendererText,
|
||||
) {
|
||||
let css_provider = gtk::CssProvider::new();
|
||||
|
||||
let tree = gtk::TreeView::new();
|
||||
let style_context = tree.get_style_context().unwrap();
|
||||
style_context.add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
tree.get_selection().set_mode(gtk::SelectionMode::Single);
|
||||
tree.set_headers_visible(false);
|
||||
@ -327,7 +340,11 @@ impl CmdLine {
|
||||
tree.show_all();
|
||||
scroll.hide();
|
||||
|
||||
(scroll, tree)
|
||||
tree.connect_size_allocate(
|
||||
clone!(scroll, renderer => move |tree, _| on_wild_treeview_allocate(&scroll, tree, &renderer)),
|
||||
);
|
||||
|
||||
(scroll, tree, css_provider, renderer)
|
||||
}
|
||||
|
||||
pub fn show_level(&mut self, ctx: &CmdLineContext) {
|
||||
@ -446,7 +463,15 @@ impl CmdLine {
|
||||
.set_mode_info(mode_info);
|
||||
}
|
||||
|
||||
pub fn show_wildmenu(&self, items: Vec<String>) {
|
||||
pub fn show_wildmenu(&self, items: Vec<String>, render_state: &shell::RenderState) {
|
||||
self.wild_renderer
|
||||
.set_property_font(Some(&render_state.font_ctx.font_description().to_string()));
|
||||
|
||||
self.wild_renderer
|
||||
.set_property_foreground_rgba(Some(&render_state.color_model.pmenu_fg().into()));
|
||||
|
||||
popup_menu::update_css(&self.wild_css_provider, &render_state.color_model);
|
||||
|
||||
let list_store = gtk::ListStore::new(&vec![gtk::Type::String; 1]);
|
||||
for item in items {
|
||||
list_store.insert_with_values(None, &[0], &[&item]);
|
||||
@ -458,6 +483,21 @@ impl CmdLine {
|
||||
pub fn hide_wildmenu(&self) {
|
||||
self.wild_scroll.hide();
|
||||
}
|
||||
|
||||
pub fn wildmenu_select(&self, selected: i64) {
|
||||
if selected >= 0 {
|
||||
let wild_tree = self.wild_tree.clone();
|
||||
idle_add(move || {
|
||||
let selected_path = gtk::TreePath::new_from_string(&format!("{}", selected));
|
||||
wild_tree.get_selection().select_path(&selected_path);
|
||||
wild_tree.scroll_to_cell(&selected_path, None, false, 0.0, 0.0);
|
||||
|
||||
Continue(false)
|
||||
});
|
||||
} else {
|
||||
self.wild_tree.get_selection().unselect_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gtk_draw(ctx: &cairo::Context, state: &Arc<UiMutex<State>>) -> Inhibit {
|
||||
@ -499,6 +539,20 @@ fn gtk_draw(ctx: &cairo::Context, state: &Arc<UiMutex<State>>) -> Inhibit {
|
||||
Inhibit(false)
|
||||
}
|
||||
|
||||
fn on_wild_treeview_allocate(
|
||||
scroll: >k::ScrolledWindow,
|
||||
tree: >k::TreeView,
|
||||
renderer: >k::CellRendererText,
|
||||
) {
|
||||
let treeview_height = popup_menu::calc_treeview_height(tree, renderer);
|
||||
|
||||
idle_add(clone!(scroll => move || {
|
||||
scroll
|
||||
.set_max_content_height(treeview_height);
|
||||
Continue(false)
|
||||
}));
|
||||
}
|
||||
|
||||
pub struct CmdLineContext {
|
||||
pub content: Vec<(HashMap<String, Value>, String)>,
|
||||
pub pos: u64,
|
||||
|
@ -233,6 +233,7 @@ pub fn call(
|
||||
"cmdline_special_char" => call!(ui->cmdline_special_char(args: str, bool, uint)),
|
||||
"wildmenu_show" => call!(ui->wildmenu_show(args: ext)),
|
||||
"wildmenu_hide" => ui.wildmenu_hide(),
|
||||
"wildmenu_select" => call!(ui->wildmenu_select(args: int)),
|
||||
_ => {
|
||||
warn!("Event {}({:?})", method, args);
|
||||
RepaintMode::Nothing
|
||||
|
@ -62,11 +62,17 @@ impl State {
|
||||
let info_label = gtk::Label::new(None);
|
||||
info_label.set_line_wrap(true);
|
||||
|
||||
let scroll = gtk::ScrolledWindow::new(None, None);
|
||||
|
||||
tree.connect_size_allocate(
|
||||
clone!(scroll, renderer => move |tree, _| on_treeview_allocate(&scroll, tree, &renderer)),
|
||||
);
|
||||
|
||||
State {
|
||||
nvim: None,
|
||||
tree,
|
||||
scroll: gtk::ScrolledWindow::new(None, None),
|
||||
renderer,
|
||||
scroll,
|
||||
css_provider,
|
||||
info_label,
|
||||
word_column,
|
||||
@ -82,6 +88,7 @@ impl State {
|
||||
|
||||
self.scroll.set_max_content_width(ctx.max_width);
|
||||
self.scroll.set_propagate_natural_width(true);
|
||||
self.scroll.set_propagate_natural_height(true);
|
||||
self.update_tree(&ctx);
|
||||
self.select(ctx.selected);
|
||||
}
|
||||
@ -99,27 +106,29 @@ impl State {
|
||||
let (word_max_width, _) = layout.get_pixel_size();
|
||||
let word_column_width = word_max_width + xpad * 2 + DEFAULT_PADDING;
|
||||
|
||||
|
||||
if kind_exists {
|
||||
layout.set_text("[v]");
|
||||
let (kind_width, _) = layout.get_pixel_size();
|
||||
|
||||
self.kind_column.set_fixed_width(kind_width + xpad * 2 + DEFAULT_PADDING);
|
||||
self.kind_column
|
||||
.set_fixed_width(kind_width + xpad * 2 + DEFAULT_PADDING);
|
||||
self.kind_column.set_visible(true);
|
||||
|
||||
self.word_column.set_fixed_width(min(max_width - kind_width, word_column_width));
|
||||
self.word_column
|
||||
.set_fixed_width(min(max_width - kind_width, word_column_width));
|
||||
} else {
|
||||
self.kind_column.set_visible(false);
|
||||
self.word_column.set_fixed_width(min(max_width, word_column_width));
|
||||
self.word_column
|
||||
.set_fixed_width(min(max_width, word_column_width));
|
||||
}
|
||||
|
||||
|
||||
let max_menu_line = ctx.menu_items.iter().max_by_key(|m| m.menu.len()).unwrap();
|
||||
|
||||
if max_menu_line.menu.len() > 0 {
|
||||
layout.set_text(max_menu_line.menu);
|
||||
let (menu_max_width, _) = layout.get_pixel_size();
|
||||
self.menu_column.set_fixed_width(menu_max_width + xpad * 2 + DEFAULT_PADDING);
|
||||
self.menu_column
|
||||
.set_fixed_width(menu_max_width + xpad * 2 + DEFAULT_PADDING);
|
||||
self.menu_column.set_visible(true);
|
||||
} else {
|
||||
self.menu_column.set_visible(false);
|
||||
@ -133,16 +142,14 @@ impl State {
|
||||
|
||||
self.limit_column_widths(ctx);
|
||||
|
||||
self.renderer.set_property_font(
|
||||
Some(&ctx.font_ctx.font_description().to_string()),
|
||||
);
|
||||
self.renderer
|
||||
.set_property_font(Some(&ctx.font_ctx.font_description().to_string()));
|
||||
|
||||
let color_model = &ctx.color_model;
|
||||
self.renderer.set_property_foreground_rgba(
|
||||
Some(&color_model.pmenu_fg().into()),
|
||||
);
|
||||
self.renderer
|
||||
.set_property_foreground_rgba(Some(&color_model.pmenu_fg().into()));
|
||||
|
||||
self.update_css(color_model);
|
||||
update_css(&self.css_provider, color_model);
|
||||
|
||||
let list_store = gtk::ListStore::new(&vec![gtk::Type::String; 4]);
|
||||
let all_column_ids: Vec<u32> = (0..4).map(|i| i as u32).collect();
|
||||
@ -155,39 +162,14 @@ impl State {
|
||||
self.tree.set_model(&list_store);
|
||||
}
|
||||
|
||||
fn update_css(&self, color_model: &ColorModel) {
|
||||
let bg = color_model.pmenu_bg_sel();
|
||||
let fg = color_model.pmenu_fg_sel();
|
||||
|
||||
match gtk::CssProviderExt::load_from_data(
|
||||
&self.css_provider,
|
||||
&format!(
|
||||
".view :selected {{ color: {}; background-color: {};}}\n
|
||||
.view {{ background-color: {}; }}",
|
||||
fg.to_hex(),
|
||||
bg.to_hex(),
|
||||
color_model.pmenu_bg().to_hex(),
|
||||
).as_bytes(),
|
||||
) {
|
||||
Err(e) => error!("Can't update css {}", e),
|
||||
Ok(_) => (),
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
self.tree.scroll_to_cell(
|
||||
Some(&selected_path),
|
||||
None,
|
||||
false,
|
||||
0.0,
|
||||
0.0,
|
||||
);
|
||||
self.tree
|
||||
.scroll_to_cell(Some(&selected_path), None, false, 0.0, 0.0);
|
||||
|
||||
self.show_info_column(&selected_path);
|
||||
|
||||
} else {
|
||||
self.tree.get_selection().unselect_all();
|
||||
self.info_label.hide();
|
||||
@ -212,17 +194,6 @@ impl State {
|
||||
self.info_label.hide();
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -243,11 +214,9 @@ impl PopupMenu {
|
||||
state.tree.set_headers_visible(false);
|
||||
state.tree.set_can_focus(false);
|
||||
|
||||
|
||||
state.scroll.set_policy(
|
||||
gtk::PolicyType::Automatic,
|
||||
gtk::PolicyType::Automatic,
|
||||
);
|
||||
state
|
||||
.scroll
|
||||
.set_policy(gtk::PolicyType::Automatic, gtk::PolicyType::Automatic);
|
||||
|
||||
state.scroll.add(&state.tree);
|
||||
state.scroll.show_all();
|
||||
@ -259,8 +228,10 @@ impl PopupMenu {
|
||||
|
||||
let state = Rc::new(RefCell::new(state));
|
||||
let state_ref = state.clone();
|
||||
state.borrow().tree.connect_button_press_event(
|
||||
move |tree, ev| {
|
||||
state
|
||||
.borrow()
|
||||
.tree
|
||||
.connect_button_press_event(move |tree, ev| {
|
||||
let state = state_ref.borrow();
|
||||
let nvim = state.nvim.as_ref().unwrap().nvim();
|
||||
if let Some(mut nvim) = nvim {
|
||||
@ -268,13 +239,7 @@ impl PopupMenu {
|
||||
} else {
|
||||
Inhibit(false)
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
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| {
|
||||
@ -345,7 +310,11 @@ fn tree_button_press(tree: >k::TreeView, ev: &EventButton, nvim: &mut Neovim)
|
||||
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
|
||||
};
|
||||
@ -383,22 +352,46 @@ fn find_scroll_count(selected_idx: i32, target_idx: i32) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_treeview_allocate(
|
||||
scroll: >k::ScrolledWindow,
|
||||
tree: >k::TreeView,
|
||||
renderer: >k::CellRendererText,
|
||||
) {
|
||||
let treeview_height = calc_treeview_height(tree, renderer);
|
||||
|
||||
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);
|
||||
}
|
||||
idle_add(clone!(scroll => move || {
|
||||
scroll
|
||||
.set_max_content_height(treeview_height);
|
||||
Continue(false)
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn update_css(css_provider: >k::CssProvider, color_model: &ColorModel) {
|
||||
let bg = color_model.pmenu_bg_sel();
|
||||
let fg = color_model.pmenu_fg_sel();
|
||||
|
||||
match gtk::CssProviderExt::load_from_data(
|
||||
css_provider,
|
||||
&format!(
|
||||
".view :selected {{ color: {}; background-color: {};}}\n
|
||||
.view {{ background-color: {}; }}",
|
||||
fg.to_hex(),
|
||||
bg.to_hex(),
|
||||
color_model.pmenu_bg().to_hex(),
|
||||
).as_bytes(),
|
||||
) {
|
||||
Err(e) => error!("Can't update css {}", e),
|
||||
Ok(_) => (),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn calc_treeview_height(tree: >k::TreeView, renderer: >k::CellRendererText) -> i32 {
|
||||
let (_, natural_size) = renderer.get_preferred_height(tree);
|
||||
let (_, ypad) = renderer.get_padding();
|
||||
|
||||
let row_height = natural_size + ypad;
|
||||
|
||||
let actual_count = tree.get_model().unwrap().iter_n_children(None);
|
||||
|
||||
row_height * min(actual_count, MAX_VISIBLE_ROWS) as i32
|
||||
}
|
||||
|
12
src/shell.rs
12
src/shell.rs
@ -1422,15 +1422,21 @@ impl State {
|
||||
RepaintMode::Nothing
|
||||
}
|
||||
|
||||
pub fn wildmenu_show(&mut self, items: Vec<String>) -> RepaintMode {
|
||||
self.cmd_line.show_wildmenu(items);
|
||||
pub fn wildmenu_show(&self, items: Vec<String>) -> RepaintMode {
|
||||
self.cmd_line
|
||||
.show_wildmenu(items, &*self.render_state.borrow());
|
||||
RepaintMode::Nothing
|
||||
}
|
||||
|
||||
pub fn wildmenu_hide(&mut self) -> RepaintMode {
|
||||
pub fn wildmenu_hide(&self) -> RepaintMode {
|
||||
self.cmd_line.hide_wildmenu();
|
||||
RepaintMode::Nothing
|
||||
}
|
||||
|
||||
pub fn wildmenu_select(&self, selected: i64) -> RepaintMode {
|
||||
self.cmd_line.wildmenu_select(selected);
|
||||
RepaintMode::Nothing
|
||||
}
|
||||
}
|
||||
|
||||
impl CursorRedrawCb for State {
|
||||
|
Loading…
Reference in New Issue
Block a user