Tab switch event

This commit is contained in:
daa 2017-05-28 12:29:50 +03:00
parent 30f9ea98a1
commit dcd8f48072
2 changed files with 54 additions and 21 deletions

View File

@ -54,7 +54,10 @@ pub trait RedrawEvents {
fn popupmenu_select(&mut self, selected: i64) -> RepaintMode; fn popupmenu_select(&mut self, selected: i64) -> RepaintMode;
fn tabline_update(&mut self, selected: Tabpage, tabs: Vec<(Tabpage, Option<&str>)>) -> RepaintMode; fn tabline_update(&mut self,
selected: Tabpage,
tabs: Vec<(Tabpage, Option<&str>)>)
-> RepaintMode;
} }
pub trait GuiApi { pub trait GuiApi {
@ -218,6 +221,11 @@ fn call_gui_event(ui: &mut shell::State,
.set_option(UiOption::ExtPopupmenu(try_uint!(args[1]) == 1)) .set_option(UiOption::ExtPopupmenu(try_uint!(args[1]) == 1))
.map_err(|e| e.to_string())? .map_err(|e| e.to_string())?
} }
"Tabline" => {
ui.nvim()
.set_option(UiOption::ExtTabline(try_uint!(args[1]) == 1))
.map_err(|e| e.to_string())?
}
opt => error!("Unknown option {}", opt), opt => error!("Unknown option {}", opt),
} }
} }
@ -301,7 +309,7 @@ fn call(ui: &mut shell::State,
tabs_out.push((tab_attr.unwrap(), name_attr)); tabs_out.push((tab_attr.unwrap(), name_attr));
} }
ui.tabline_update(Tabpage::new(args[0].clone()), tabs_out) ui.tabline_update(Tabpage::new(args[0].clone()), tabs_out)
}, }
_ => { _ => {
println!("Event {}({:?})", method, args); println!("Event {}({:?})", method, args);
RepaintMode::Nothing RepaintMode::Nothing

View File

@ -5,6 +5,8 @@ use std::cell::RefCell;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
use glib::signal;
use neovim_lib::{Neovim, NeovimApi}; use neovim_lib::{Neovim, NeovimApi};
use neovim_lib::neovim_api::Tabpage; use neovim_lib::neovim_api::Tabpage;
@ -12,6 +14,7 @@ use nvim::ErrorReport;
struct State { struct State {
data: Vec<Tabpage>, data: Vec<Tabpage>,
selected: Option<Tabpage>,
nvim: Option<Rc<RefCell<Neovim>>>, nvim: Option<Rc<RefCell<Neovim>>>,
} }
@ -19,20 +22,24 @@ impl State {
pub fn new() -> Self { pub fn new() -> Self {
State { State {
data: Vec::new(), data: Vec::new(),
selected: None,
nvim: None, nvim: None,
} }
} }
fn change_current_page(&self, idx: i32) -> bool { fn switch_page(&self, idx: u32) {
let target = &self.data[idx as usize];
if Some(target) != self.selected.as_ref() {
let mut nvim = self.nvim.as_ref().unwrap().borrow_mut(); let mut nvim = self.nvim.as_ref().unwrap().borrow_mut();
nvim.set_current_tabpage(&self.data[idx as usize]).report_err(&mut *nvim); nvim.set_current_tabpage(&target).report_err(&mut *nvim);
true }
} }
} }
pub struct Tabline { pub struct Tabline {
tabs: gtk::Notebook, tabs: gtk::Notebook,
state: Rc<RefCell<State>>, state: Rc<RefCell<State>>,
switch_handler_id: u64,
} }
impl Tabline { impl Tabline {
@ -48,15 +55,35 @@ impl Tabline {
let state = Rc::new(RefCell::new(State::new())); let state = Rc::new(RefCell::new(State::new()));
let state_ref = state.clone(); let state_ref = state.clone();
tabs.connect_change_current_page(move |_, idx| state_ref.borrow().change_current_page(idx)); let switch_handler_id =
tabs.connect_switch_page(move |_, _, idx| state_ref.borrow().switch_page(idx));
Tabline { Tabline {
tabs, tabs,
state, state,
switch_handler_id,
} }
} }
pub fn update_tabs(&self, nvim: &Rc<RefCell<Neovim>>, selected: &Tabpage, tabs: &Vec<(Tabpage, Option<&str>)>) { fn update_state(&self,
nvim: &Rc<RefCell<Neovim>>,
selected: &Tabpage,
tabs: &Vec<(Tabpage, Option<&str>)>) {
let mut state = self.state.borrow_mut();
if state.nvim.is_none() {
state.nvim = Some(nvim.clone());
}
state.selected = Some(selected.clone());
state.data = tabs.iter().map(|item| item.0.clone()).collect();
}
pub fn update_tabs(&self,
nvim: &Rc<RefCell<Neovim>>,
selected: &Tabpage,
tabs: &Vec<(Tabpage, Option<&str>)>) {
if tabs.len() <= 1 { if tabs.len() <= 1 {
self.tabs.hide(); self.tabs.hide();
return; return;
@ -64,37 +91,35 @@ impl Tabline {
self.tabs.show(); self.tabs.show();
} }
let mut state = self.state.borrow_mut(); self.update_state(nvim, selected, tabs);
if state.nvim.is_none() {
state.nvim = Some(nvim.clone()); signal::signal_handler_block(&self.tabs, self.switch_handler_id);
}
let count = self.tabs.get_n_pages() as usize; let count = self.tabs.get_n_pages() as usize;
if count < tabs.len() { if count < tabs.len() {
for _ in count..tabs.len() { for _ in count..tabs.len() {
let empty = gtk::Box::new(gtk::Orientation::Vertical, 0); let empty = gtk::Box::new(gtk::Orientation::Vertical, 0);
empty.show_all(); empty.show_all();
self.tabs.append_page(&empty, Some(&gtk::Label::new("AA"))); self.tabs.append_page(&empty, Some(&gtk::Label::new(None)));
} }
} } else if count > tabs.len() {
else if count > tabs.len() {
for _ in tabs.len()..count { for _ in tabs.len()..count {
self.tabs.remove_page(None); self.tabs.remove_page(None);
} }
} }
state.data.clear();
for (idx, tab) in tabs.iter().enumerate() { for (idx, tab) in tabs.iter().enumerate() {
let tab_child = self.tabs.get_nth_page(Some(idx as u32)); 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("??")); self.tabs
state.data.push(tab.0.clone()); .set_tab_label_text(&tab_child.unwrap(), &tab.1.unwrap_or("??"));
if *selected == tab.0 { if *selected == tab.0 {
self.tabs.set_current_page(Some(idx as u32)); self.tabs.set_current_page(Some(idx as u32));
} }
} }
signal::signal_handler_unblock(&self.tabs, self.switch_handler_id);
} }
} }