2017-05-27 16:50:25 +00:00
|
|
|
use std::ops::Deref;
|
2017-05-27 20:51:22 +00:00
|
|
|
use std::rc::Rc;
|
|
|
|
use std::cell::RefCell;
|
2017-05-27 16:50:25 +00:00
|
|
|
|
|
|
|
use gtk;
|
|
|
|
use gtk::prelude::*;
|
|
|
|
|
2017-05-27 20:51:22 +00:00
|
|
|
use neovim_lib::{Neovim, NeovimApi};
|
2017-05-27 16:50:25 +00:00
|
|
|
use neovim_lib::neovim_api::Tabpage;
|
|
|
|
|
2017-05-27 20:51:22 +00:00
|
|
|
use nvim::ErrorReport;
|
|
|
|
|
|
|
|
struct State {
|
|
|
|
data: Vec<Tabpage>,
|
|
|
|
nvim: Option<Rc<RefCell<Neovim>>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl State {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
State {
|
|
|
|
data: Vec::new(),
|
|
|
|
nvim: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn change_current_page(&self, idx: i32) -> bool {
|
|
|
|
let mut nvim = self.nvim.as_ref().unwrap().borrow_mut();
|
|
|
|
nvim.set_current_tabpage(&self.data[idx as usize]).report_err(&mut *nvim);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-27 16:50:25 +00:00
|
|
|
pub struct Tabline {
|
|
|
|
tabs: gtk::Notebook,
|
2017-05-27 20:51:22 +00:00
|
|
|
state: Rc<RefCell<State>>,
|
2017-05-27 16:50:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Tabline {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
let tabs = gtk::Notebook::new();
|
|
|
|
|
|
|
|
tabs.set_can_focus(false);
|
|
|
|
tabs.set_scrollable(true);
|
|
|
|
tabs.set_show_border(false);
|
|
|
|
tabs.set_border_width(0);
|
2017-05-27 20:51:22 +00:00
|
|
|
tabs.hide();
|
|
|
|
|
|
|
|
let state = Rc::new(RefCell::new(State::new()));
|
|
|
|
|
|
|
|
let state_ref = state.clone();
|
|
|
|
tabs.connect_change_current_page(move |_, idx| state_ref.borrow().change_current_page(idx));
|
2017-05-27 16:50:25 +00:00
|
|
|
|
|
|
|
Tabline {
|
|
|
|
tabs,
|
2017-05-27 20:51:22 +00:00
|
|
|
state,
|
2017-05-27 16:50:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-27 20:51:22 +00:00
|
|
|
pub fn update_tabs(&self, nvim: &Rc<RefCell<Neovim>>, selected: &Tabpage, tabs: &Vec<(Tabpage, Option<&str>)>) {
|
|
|
|
if tabs.len() <= 1 {
|
|
|
|
self.tabs.hide();
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
self.tabs.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut state = self.state.borrow_mut();
|
|
|
|
|
|
|
|
if state.nvim.is_none() {
|
|
|
|
state.nvim = Some(nvim.clone());
|
|
|
|
}
|
|
|
|
|
2017-05-27 16:50:25 +00:00
|
|
|
let count = self.tabs.get_n_pages() as usize;
|
|
|
|
if count < tabs.len() {
|
|
|
|
for _ in count..tabs.len() {
|
|
|
|
let empty = gtk::Box::new(gtk::Orientation::Vertical, 0);
|
|
|
|
empty.show_all();
|
|
|
|
self.tabs.append_page(&empty, Some(>k::Label::new("AA")));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if count > tabs.len() {
|
|
|
|
for _ in tabs.len()..count {
|
|
|
|
self.tabs.remove_page(None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-27 20:51:22 +00:00
|
|
|
state.data.clear();
|
|
|
|
|
2017-05-27 16:50:25 +00:00
|
|
|
for (idx, tab) in tabs.iter().enumerate() {
|
|
|
|
let tab_child = self.tabs.get_nth_page(Some(idx as u32));
|
|
|
|
self.tabs.set_tab_label_text(&tab_child.unwrap(), &tab.1.unwrap_or("??"));
|
2017-05-27 20:51:22 +00:00
|
|
|
state.data.push(tab.0.clone());
|
|
|
|
|
|
|
|
if *selected == tab.0 {
|
|
|
|
self.tabs.set_current_page(Some(idx as u32));
|
|
|
|
}
|
2017-05-27 16:50:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Deref for Tabline {
|
|
|
|
type Target = gtk::Notebook;
|
|
|
|
|
|
|
|
fn deref(&self) -> >k::Notebook {
|
|
|
|
&self.tabs
|
|
|
|
}
|
|
|
|
}
|