diff --git a/src/popup_menu.rs b/src/popup_menu.rs index 1b9e238..76eaf49 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -6,6 +6,7 @@ use gtk; use gtk::prelude::*; use glib; use gdk::{EventButton, EventType}; +use pango::{self, LayoutExt}; use neovim_lib::{Neovim, NeovimApi}; @@ -23,6 +24,9 @@ struct State { scroll: gtk::ScrolledWindow, css_provider: gtk::CssProvider, info_label: gtk::Label, + word_column: gtk::TreeViewColumn, + kind_column: gtk::TreeViewColumn, + menu_column: gtk::TreeViewColumn, } impl State { @@ -34,24 +38,25 @@ impl State { style_context.add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); let renderer = gtk::CellRendererText::new(); + renderer.set_property_ellipsize(pango::EllipsizeMode::End); // word - let column = gtk::TreeViewColumn::new(); - column.pack_start(&renderer, true); - column.add_attribute(&renderer, "text", 0); - tree.append_column(&column); + let word_column = gtk::TreeViewColumn::new(); + word_column.pack_start(&renderer, true); + word_column.add_attribute(&renderer, "text", 0); + tree.append_column(&word_column); // kind - let column = gtk::TreeViewColumn::new(); - column.pack_start(&renderer, true); - column.add_attribute(&renderer, "text", 1); - tree.append_column(&column); + let kind_column = gtk::TreeViewColumn::new(); + kind_column.pack_start(&renderer, true); + kind_column.add_attribute(&renderer, "text", 1); + tree.append_column(&kind_column); // menu - let column = gtk::TreeViewColumn::new(); - column.pack_start(&renderer, true); - column.add_attribute(&renderer, "text", 2); - tree.append_column(&column); + let menu_column = gtk::TreeViewColumn::new(); + menu_column.pack_start(&renderer, true); + menu_column.add_attribute(&renderer, "text", 2); + tree.append_column(&menu_column); let info_label = gtk::Label::new(None); info_label.set_line_wrap(true); @@ -63,6 +68,9 @@ impl State { renderer, css_provider, info_label, + word_column, + kind_column, + menu_column, } } @@ -78,11 +86,57 @@ impl State { self.select(selected); } + fn limit_column_widths(&self, menu: &[CompleteItem], shell: &shell::State) { + let layout = shell.font_ctx.create_layout(); + let kind_chars = menu.iter().map(|i| i.kind.len()).max().unwrap(); + let max_width = self.scroll.get_max_content_width(); + let (xpad, _) = self.renderer.get_padding(); + + const DEFAULT_PADDING: i32 = 5; + + if kind_chars > 0 { + layout.set_text("[v]"); + let (kind_width, _) = layout.get_pixel_size(); + + self.word_column.set_fixed_width(max_width - kind_width); + + self.kind_column.set_fixed_width(kind_width + xpad * 2 + DEFAULT_PADDING); + self.kind_column.set_visible(true); + } else { + let max_line = menu.iter().max_by_key(|m| m.word.len()).unwrap(); + layout.set_text(max_line.word); + let (word_max_width, _) = layout.get_pixel_size(); + + self.kind_column.set_visible(false); + + let word_column_width = word_max_width + xpad * 2 + DEFAULT_PADDING; + if word_column_width > max_width { + self.word_column.set_fixed_width(max_width); + } else { + self.word_column.set_fixed_width(word_column_width); + } + } + + + let max_line = menu.iter().max_by_key(|m| m.menu.len()).unwrap(); + + if max_line.menu.len() > 0 { + layout.set_text(max_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_visible(true); + } else { + self.menu_column.set_visible(false); + } + } + fn update_tree(&self, menu: &[CompleteItem], shell: &shell::State) { if menu.is_empty() { return; } + self.limit_column_widths(menu, shell); + self.renderer.set_property_font( Some(&shell.get_font_desc().to_string()), ); diff --git a/src/render/context.rs b/src/render/context.rs index f8d6ba8..62223c0 100644 --- a/src/render/context.rs +++ b/src/render/context.rs @@ -38,6 +38,10 @@ impl Context { .collect() } + pub fn create_layout(&self) -> pango::Layout { + pango::Layout::new(&self.state.pango_context) + } + #[inline] pub fn font_description(&self) -> &pango::FontDescription { &self.state.font_desc diff --git a/src/shell.rs b/src/shell.rs index 5864d16..976a49a 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -836,9 +836,8 @@ fn set_nvim_initialized(state_arc: Arc>) { } fn draw_initializing(state: &State, ctx: &cairo::Context) { - let layout = pangocairo::functions::create_layout(ctx).unwrap(); - let desc = state.get_font_desc(); let alloc = state.drawing_area.get_allocation(); + let layout = state.font_ctx.create_layout(); ctx.set_source_rgb( state.color_model.bg_color.0, @@ -847,7 +846,6 @@ fn draw_initializing(state: &State, ctx: &cairo::Context) { ); ctx.paint(); - layout.set_font_description(desc); layout.set_text("Loading->"); let (width, height) = layout.get_pixel_size();