Initialize nvim after gui size is nown
ALos some code cleanup
This commit is contained in:
parent
d9b7b1a1cc
commit
5260d78418
@ -37,6 +37,8 @@ use gio::ApplicationExt;
|
|||||||
|
|
||||||
use ui::Ui;
|
use ui::Ui;
|
||||||
|
|
||||||
|
use shell::ShellOptions;
|
||||||
|
|
||||||
const BIN_PATH_ARG: &'static str = "--nvim-bin-path";
|
const BIN_PATH_ARG: &'static str = "--nvim-bin-path";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -64,11 +66,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn activate(app: >k::Application) {
|
fn activate(app: >k::Application) {
|
||||||
let mut ui = Ui::new();
|
let mut ui = Ui::new(ShellOptions::new(nvim_bin_path(std::env::args()), open_arg()));
|
||||||
|
|
||||||
ui.init(app,
|
ui.init(app);
|
||||||
nvim_bin_path(std::env::args()).as_ref(),
|
|
||||||
open_arg().as_ref());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nvim_bin_path<I>(args: I) -> Option<String>
|
fn nvim_bin_path<I>(args: I) -> Option<String>
|
||||||
|
@ -77,7 +77,9 @@ macro_rules! try_uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize(shell: Arc<UiMutex<shell::State>>,
|
pub fn initialize(shell: Arc<UiMutex<shell::State>>,
|
||||||
nvim_bin_path: Option<&String>)
|
nvim_bin_path: Option<&String>,
|
||||||
|
cols: u64,
|
||||||
|
rows: u64)
|
||||||
-> Result<Neovim> {
|
-> Result<Neovim> {
|
||||||
let mut cmd = if let Some(path) = nvim_bin_path {
|
let mut cmd = if let Some(path) = nvim_bin_path {
|
||||||
Command::new(path)
|
Command::new(path)
|
||||||
@ -120,7 +122,7 @@ pub fn initialize(shell: Arc<UiMutex<shell::State>>,
|
|||||||
let mut opts = UiAttachOptions::new();
|
let mut opts = UiAttachOptions::new();
|
||||||
opts.set_popupmenu_external(false);
|
opts.set_popupmenu_external(false);
|
||||||
opts.set_tabline_external(true);
|
opts.set_tabline_external(true);
|
||||||
nvim.ui_attach(80, 24, opts)
|
nvim.ui_attach(cols, rows, opts)
|
||||||
.map_err(|e| Error::new(ErrorKind::Other, e))?;
|
.map_err(|e| Error::new(ErrorKind::Other, e))?;
|
||||||
nvim.command("runtime! ginit.vim")
|
nvim.command("runtime! ginit.vim")
|
||||||
.map_err(|e| Error::new(ErrorKind::Other, e))?;
|
.map_err(|e| Error::new(ErrorKind::Other, e))?;
|
||||||
|
272
src/shell.rs
272
src/shell.rs
@ -1,8 +1,8 @@
|
|||||||
use std::cell::{RefMut, RefCell};
|
use std::cell::{RefMut, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
use cairo;
|
use cairo;
|
||||||
use pangocairo::CairoContextExt;
|
use pangocairo::CairoContextExt;
|
||||||
@ -24,13 +24,24 @@ use nvim::{RedrawEvents, GuiApi, RepaintMode, ErrorReport};
|
|||||||
use input;
|
use input;
|
||||||
use input::keyval_to_input_string;
|
use input::keyval_to_input_string;
|
||||||
use cursor::Cursor;
|
use cursor::Cursor;
|
||||||
use ui;
|
|
||||||
use ui::UiMutex;
|
use ui::UiMutex;
|
||||||
use popup_menu::PopupMenu;
|
use popup_menu::PopupMenu;
|
||||||
use tabline::Tabline;
|
use tabline::Tabline;
|
||||||
|
|
||||||
const DEFAULT_FONT_NAME: &'static str = "DejaVu Sans Mono 12";
|
const DEFAULT_FONT_NAME: &'static str = "DejaVu Sans Mono 12";
|
||||||
|
|
||||||
|
macro_rules! idle_cb_call {
|
||||||
|
($state:ident.$cb:ident($( $x:expr ),*)) => (
|
||||||
|
glib::idle_add(move || {
|
||||||
|
if let Some(ref cb) = $state.borrow().$cb {
|
||||||
|
(&mut *cb.borrow_mut())($($x),*);
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::Continue(false)
|
||||||
|
});
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum NvimMode {
|
pub enum NvimMode {
|
||||||
@ -61,16 +72,18 @@ pub struct State {
|
|||||||
request_resize: bool,
|
request_resize: bool,
|
||||||
resize_timer: Option<glib::SourceId>,
|
resize_timer: Option<glib::SourceId>,
|
||||||
|
|
||||||
parent: sync::Weak<UiMutex<ui::Components>>,
|
options: ShellOptions,
|
||||||
|
|
||||||
|
detach_cb: Option<Box<RefCell<FnMut() + Send + 'static>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new(settings: Rc<RefCell<Settings>>, parent: &Arc<UiMutex<ui::Components>>) -> State {
|
pub fn new(settings: Rc<RefCell<Settings>>, options: ShellOptions) -> State {
|
||||||
let drawing_area = gtk::DrawingArea::new();
|
let drawing_area = gtk::DrawingArea::new();
|
||||||
let popup_menu = RefCell::new(PopupMenu::new(&drawing_area));
|
let popup_menu = RefCell::new(PopupMenu::new(&drawing_area));
|
||||||
|
|
||||||
State {
|
State {
|
||||||
model: UiModel::new(24, 80),
|
model: UiModel::new(1, 1),
|
||||||
nvim: None,
|
nvim: None,
|
||||||
cur_attrs: None,
|
cur_attrs: None,
|
||||||
bg_color: COLOR_BLACK,
|
bg_color: COLOR_BLACK,
|
||||||
@ -91,7 +104,9 @@ impl State {
|
|||||||
resize_timer: None,
|
resize_timer: None,
|
||||||
request_resize: false,
|
request_resize: false,
|
||||||
|
|
||||||
parent: Arc::downgrade(parent),
|
options,
|
||||||
|
|
||||||
|
detach_cb: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +126,16 @@ impl State {
|
|||||||
self.nvim.as_ref().unwrap().clone()
|
self.nvim.as_ref().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_detach_cb<F>(&mut self, cb: Option<F>)
|
||||||
|
where F: FnMut() + Send + 'static
|
||||||
|
{
|
||||||
|
if cb.is_some() {
|
||||||
|
self.detach_cb = Some(Box::new(RefCell::new(cb.unwrap())));
|
||||||
|
} else {
|
||||||
|
self.detach_cb = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_pango_font(&self) -> FontDescription {
|
fn create_pango_font(&self) -> FontDescription {
|
||||||
self.font_desc.clone()
|
self.font_desc.clone()
|
||||||
}
|
}
|
||||||
@ -146,14 +171,12 @@ impl State {
|
|||||||
|
|
||||||
pub fn open_file(&self, path: &str) {
|
pub fn open_file(&self, path: &str) {
|
||||||
let mut nvim = self.nvim();
|
let mut nvim = self.nvim();
|
||||||
nvim.command(&format!("e {}", path))
|
nvim.command(&format!("e {}", path)).report_err(&mut *nvim);
|
||||||
.report_err(&mut *nvim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cd(&self, path: &str) {
|
pub fn cd(&self, path: &str) {
|
||||||
let mut nvim = self.nvim();
|
let mut nvim = self.nvim();
|
||||||
nvim.command(&format!("cd {}", path))
|
nvim.command(&format!("cd {}", path)).report_err(&mut *nvim);
|
||||||
.report_err(&mut *nvim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_resize(&mut self) {
|
fn request_resize(&mut self) {
|
||||||
@ -183,6 +206,36 @@ impl State {
|
|||||||
_ => self.drawing_area.queue_draw(),
|
_ => self.drawing_area.queue_draw(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calc_char_bounds(&self, ctx: &cairo::Context) -> (i32, i32) {
|
||||||
|
let layout = ctx.create_pango_layout();
|
||||||
|
|
||||||
|
let desc = self.create_pango_font();
|
||||||
|
layout.set_font_description(Some(&desc));
|
||||||
|
layout.set_text("A", -1);
|
||||||
|
|
||||||
|
layout.get_pixel_size()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_line_metrics(&mut self, ctx: &cairo::Context) {
|
||||||
|
if self.line_height.is_none() {
|
||||||
|
let (width, height) = self.calc_char_bounds(ctx);
|
||||||
|
self.line_height = Some(height as f64);
|
||||||
|
self.char_width = Some(width as f64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_nvim_size(&self) -> Option<(usize, usize)> {
|
||||||
|
if let Some(line_height) = self.line_height {
|
||||||
|
if let Some(char_width) = self.char_width {
|
||||||
|
let alloc = self.drawing_area.get_allocation();
|
||||||
|
return Some(((alloc.width as f64 / char_width).trunc() as usize,
|
||||||
|
(alloc.height as f64 / line_height).trunc() as usize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UiState {
|
pub struct UiState {
|
||||||
@ -195,6 +248,20 @@ impl UiState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ShellOptions {
|
||||||
|
nvim_bin_path: Option<String>,
|
||||||
|
open_path: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShellOptions {
|
||||||
|
pub fn new(nvim_bin_path: Option<String>, open_path: Option<String>) -> Self {
|
||||||
|
ShellOptions {
|
||||||
|
nvim_bin_path,
|
||||||
|
open_path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Shell {
|
pub struct Shell {
|
||||||
pub state: Arc<UiMutex<State>>,
|
pub state: Arc<UiMutex<State>>,
|
||||||
ui_state: Rc<RefCell<UiState>>,
|
ui_state: Rc<RefCell<UiState>>,
|
||||||
@ -203,9 +270,9 @@ pub struct Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Shell {
|
impl Shell {
|
||||||
pub fn new(settings: Rc<RefCell<Settings>>, parent: &Arc<UiMutex<ui::Components>>) -> Shell {
|
pub fn new(settings: Rc<RefCell<Settings>>, options: ShellOptions) -> Shell {
|
||||||
let shell = Shell {
|
let shell = Shell {
|
||||||
state: Arc::new(UiMutex::new(State::new(settings, parent))),
|
state: Arc::new(UiMutex::new(State::new(settings, options))),
|
||||||
ui_state: Rc::new(RefCell::new(UiState::new())),
|
ui_state: Rc::new(RefCell::new(UiState::new())),
|
||||||
|
|
||||||
widget: gtk::Box::new(gtk::Orientation::Vertical, 0),
|
widget: gtk::Box::new(gtk::Orientation::Vertical, 0),
|
||||||
@ -218,8 +285,7 @@ impl Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self) {
|
pub fn init(&mut self) {
|
||||||
let state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
state.drawing_area.set_size_request(500, 300);
|
|
||||||
state.drawing_area.set_hexpand(true);
|
state.drawing_area.set_hexpand(true);
|
||||||
state.drawing_area.set_vexpand(true);
|
state.drawing_area.set_vexpand(true);
|
||||||
state.drawing_area.set_can_focus(true);
|
state.drawing_area.set_can_focus(true);
|
||||||
@ -265,12 +331,7 @@ impl Shell {
|
|||||||
let ref_state = self.state.clone();
|
let ref_state = self.state.clone();
|
||||||
state
|
state
|
||||||
.drawing_area
|
.drawing_area
|
||||||
.connect_draw(move |_, ctx| {
|
.connect_draw(move |_, ctx| gtk_draw(&ref_state, ctx));
|
||||||
let mut state = ref_state.borrow_mut();
|
|
||||||
let ref_parent = sync::Weak::upgrade(&state.parent).unwrap();
|
|
||||||
let parent = ref_parent.borrow();
|
|
||||||
gtk_draw(&*parent, &mut *state, ctx)
|
|
||||||
});
|
|
||||||
|
|
||||||
let ref_state = self.state.clone();
|
let ref_state = self.state.clone();
|
||||||
state
|
state
|
||||||
@ -296,6 +357,13 @@ impl Shell {
|
|||||||
state
|
state
|
||||||
.drawing_area
|
.drawing_area
|
||||||
.connect_focus_out_event(move |_, _| gtk_focus_out(&mut *ref_state.borrow_mut()));
|
.connect_focus_out_event(move |_, _| gtk_focus_out(&mut *ref_state.borrow_mut()));
|
||||||
|
|
||||||
|
let ref_state = self.state.clone();
|
||||||
|
state
|
||||||
|
.drawing_area
|
||||||
|
.connect_configure_event(move |_, ev| gtk_configure_event(&ref_state, ev));
|
||||||
|
|
||||||
|
state.cursor.as_mut().unwrap().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -308,24 +376,6 @@ impl Shell {
|
|||||||
self.state.borrow_mut().set_font_desc(font_name);
|
self.state.borrow_mut().set_font_desc(font_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_configure_event(&mut self) {
|
|
||||||
let mut state = self.state.borrow_mut();
|
|
||||||
|
|
||||||
let ref_state = self.state.clone();
|
|
||||||
state
|
|
||||||
.drawing_area
|
|
||||||
.connect_configure_event(move |_, ev| gtk_configure_event(&ref_state, ev));
|
|
||||||
|
|
||||||
state.cursor.as_mut().unwrap().start();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_nvim(&mut self, nvim_bin_path: Option<&String>) {
|
|
||||||
let nvim =
|
|
||||||
nvim::initialize(self.state.clone(), nvim_bin_path).expect("Can't start nvim instance");
|
|
||||||
let mut state = self.state.borrow_mut();
|
|
||||||
state.nvim = Some(Rc::new(RefCell::new(nvim)));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn grab_focus(&self) {
|
pub fn grab_focus(&self) {
|
||||||
self.state.borrow().drawing_area.grab_focus();
|
self.state.borrow().drawing_area.grab_focus();
|
||||||
}
|
}
|
||||||
@ -360,11 +410,18 @@ impl Shell {
|
|||||||
let mut nvim = &mut *state.nvim();
|
let mut nvim = &mut *state.nvim();
|
||||||
nvim.command(":wa").report_err(nvim);
|
nvim.command(":wa").report_err(nvim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_detach_cb<F>(&self, cb: Option<F>)
|
||||||
|
where F: FnMut() + Send + 'static
|
||||||
|
{
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
state.set_detach_cb(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Shell {
|
impl Deref for Shell {
|
||||||
type Target = gtk::Box;
|
type Target = gtk::Box;
|
||||||
|
|
||||||
fn deref(&self) -> >k::Box {
|
fn deref(&self) -> >k::Box {
|
||||||
&self.widget
|
&self.widget
|
||||||
}
|
}
|
||||||
@ -450,20 +507,54 @@ fn gtk_motion_notify(shell: &mut State, ui_state: &mut UiState, ev: &EventMotion
|
|||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gtk_draw(parent: &ui::Components, state: &mut State, ctx: &cairo::Context) -> Inhibit {
|
#[inline]
|
||||||
|
fn update_line_metrics(state_arc: &Arc<UiMutex<State>>, ctx: &cairo::Context) {
|
||||||
|
let mut state = state_arc.borrow_mut();
|
||||||
|
|
||||||
if state.line_height.is_none() {
|
if state.line_height.is_none() {
|
||||||
let (width, height) = calc_char_bounds(state, ctx);
|
state.calc_line_metrics(ctx);
|
||||||
state.line_height = Some(height as f64);
|
|
||||||
state.char_width = Some(width as f64);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draw(state, ctx);
|
fn gtk_draw(state: &Arc<UiMutex<State>>, ctx: &cairo::Context) -> Inhibit {
|
||||||
request_window_resize(parent, state);
|
update_line_metrics(state, ctx);
|
||||||
|
init_nvim(state);
|
||||||
|
|
||||||
|
draw(&*state.borrow(), ctx);
|
||||||
|
request_window_resize(&mut *state.borrow_mut());
|
||||||
|
|
||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn init_nvim(state_arc: &Arc<UiMutex<State>>) {
|
||||||
|
let mut state = state_arc.borrow_mut();
|
||||||
|
|
||||||
|
if state.nvim.is_none() {
|
||||||
|
let (cols, rows) = state.calc_nvim_size().unwrap();
|
||||||
|
let mut nvim = nvim::initialize(state_arc.clone(),
|
||||||
|
state.options.nvim_bin_path.as_ref(),
|
||||||
|
cols as u64,
|
||||||
|
rows as u64)
|
||||||
|
.expect("Can't start nvim instance");
|
||||||
|
|
||||||
|
if let Some(ref path) = state.options.open_path {
|
||||||
|
nvim.command(&format!("e {}", path)).report_err(&mut nvim);
|
||||||
|
}
|
||||||
|
|
||||||
|
let guard = nvim.session.take_dispatch_guard();
|
||||||
|
|
||||||
|
let state_ref = state_arc.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
guard.join().expect("Can't join dispatch thread");
|
||||||
|
|
||||||
|
idle_cb_call!(state_ref.detach_cb());
|
||||||
|
});
|
||||||
|
|
||||||
|
state.nvim = Some(Rc::new(RefCell::new(nvim)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_model_clip(state: &State,
|
fn get_model_clip(state: &State,
|
||||||
line_height: f64,
|
line_height: f64,
|
||||||
@ -500,7 +591,7 @@ fn draw_backgound(state: &State,
|
|||||||
|
|
||||||
if !draw_bitmap.get(col_idx, line_idx) {
|
if !draw_bitmap.get(col_idx, line_idx) {
|
||||||
let (bg, _) = state.colors(cell);
|
let (bg, _) = state.colors(cell);
|
||||||
|
|
||||||
if &state.bg_color != bg {
|
if &state.bg_color != bg {
|
||||||
ctx.set_source_rgb(bg.0, bg.1, bg.2);
|
ctx.set_source_rgb(bg.0, bg.1, bg.2);
|
||||||
ctx.rectangle(current_point.0, current_point.1, char_width, line_height);
|
ctx.rectangle(current_point.0, current_point.1, char_width, line_height);
|
||||||
@ -533,15 +624,21 @@ fn draw(state: &State, ctx: &cairo::Context) {
|
|||||||
for clip_idx in 0..clip_rects.len() {
|
for clip_idx in 0..clip_rects.len() {
|
||||||
let clip = clip_rects.get(clip_idx).unwrap();
|
let clip = clip_rects.get(clip_idx).unwrap();
|
||||||
|
|
||||||
let model_clip = get_model_clip(state,
|
let model_clip =
|
||||||
line_height,
|
get_model_clip(state,
|
||||||
char_width,
|
line_height,
|
||||||
(clip.x, clip.y, clip.x + clip.width, clip.y + clip.height));
|
char_width,
|
||||||
|
(clip.x, clip.y, clip.x + clip.width, clip.y + clip.height));
|
||||||
|
|
||||||
let line_x = model_clip.left as f64 * char_width;
|
let line_x = model_clip.left as f64 * char_width;
|
||||||
let mut line_y: f64 = model_clip.top as f64 * line_height;
|
let mut line_y: f64 = model_clip.top as f64 * line_height;
|
||||||
|
|
||||||
draw_backgound(state, &draw_bitmap, ctx, line_height, char_width, &model_clip);
|
draw_backgound(state,
|
||||||
|
&draw_bitmap,
|
||||||
|
ctx,
|
||||||
|
line_height,
|
||||||
|
char_width,
|
||||||
|
&model_clip);
|
||||||
|
|
||||||
for (line_idx, line) in state.model.clip_model(&model_clip) {
|
for (line_idx, line) in state.model.clip_model(&model_clip) {
|
||||||
|
|
||||||
@ -644,17 +741,7 @@ fn update_font_description(desc: &mut FontDescription, attrs: &Attrs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_char_bounds(shell: &State, ctx: &cairo::Context) -> (i32, i32) {
|
fn request_window_resize(state: &mut State) {
|
||||||
let layout = ctx.create_pango_layout();
|
|
||||||
|
|
||||||
let desc = shell.create_pango_font();
|
|
||||||
layout.set_font_description(Some(&desc));
|
|
||||||
layout.set_text("A", -1);
|
|
||||||
|
|
||||||
layout.get_pixel_size()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn request_window_resize(parent: &ui::Components, state: &mut State) {
|
|
||||||
if !state.request_resize {
|
if !state.request_resize {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -670,7 +757,12 @@ fn request_window_resize(parent: &ui::Components, state: &mut State) {
|
|||||||
let request_width = (state.model.columns as f64 * state.char_width.unwrap()) as i32;
|
let request_width = (state.model.columns as f64 * state.char_width.unwrap()) as i32;
|
||||||
|
|
||||||
if width != request_width || height != request_height {
|
if width != request_width || height != request_height {
|
||||||
let window = parent.window();
|
let window: gtk::Window = state
|
||||||
|
.drawing_area
|
||||||
|
.get_toplevel()
|
||||||
|
.unwrap()
|
||||||
|
.downcast()
|
||||||
|
.unwrap();
|
||||||
let (win_width, win_height) = window.get_size();
|
let (win_width, win_height) = window.get_size();
|
||||||
let h_border = win_width - width;
|
let h_border = win_width - width;
|
||||||
let v_border = win_height - height;
|
let v_border = win_height - height;
|
||||||
@ -685,35 +777,26 @@ fn split_color(indexed_color: u64) -> Color {
|
|||||||
Color(r / 255.0, g / 255.0, b / 255.0)
|
Color(r / 255.0, g / 255.0, b / 255.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gtk_configure_event(state: &Arc<UiMutex<State>>, ev: &EventConfigure) -> bool {
|
fn gtk_configure_event(state: &Arc<UiMutex<State>>, _: &EventConfigure) -> bool {
|
||||||
let (width, height) = ev.get_size();
|
|
||||||
|
|
||||||
let mut state_ref = state.borrow_mut();
|
let mut state_ref = state.borrow_mut();
|
||||||
|
|
||||||
if let Some(timer) = state_ref.resize_timer {
|
if let Some(timer) = state_ref.resize_timer {
|
||||||
glib::source_remove(timer);
|
glib::source_remove(timer);
|
||||||
}
|
}
|
||||||
if let Some(line_height) = state_ref.line_height {
|
if let Some((columns, rows)) = state_ref.calc_nvim_size() {
|
||||||
if let Some(char_width) = state_ref.char_width {
|
let state = state.clone();
|
||||||
|
state_ref.resize_timer = Some(glib::timeout_add(250, move || {
|
||||||
|
let mut state_ref = state.borrow_mut();
|
||||||
|
|
||||||
let state = state.clone();
|
state_ref.resize_timer = None;
|
||||||
state_ref.resize_timer = Some(glib::timeout_add(250, move || {
|
|
||||||
let mut state_ref = state.borrow_mut();
|
|
||||||
|
|
||||||
state_ref.resize_timer = None;
|
if state_ref.model.rows != rows || state_ref.model.columns != columns {
|
||||||
|
if let Err(err) = state_ref.nvim().ui_try_resize(columns as u64, rows as u64) {
|
||||||
let rows = (height as f64 / line_height).trunc() as usize;
|
println!("Error trying resize nvim {}", err);
|
||||||
let columns = (width as f64 / char_width).trunc() as usize;
|
|
||||||
if state_ref.model.rows != rows || state_ref.model.columns != columns {
|
|
||||||
if let Err(err) = state_ref
|
|
||||||
.nvim()
|
|
||||||
.ui_try_resize(columns as u64, rows as u64) {
|
|
||||||
println!("Error trying resize nvim {}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Continue(false)
|
}
|
||||||
}));
|
Continue(false)
|
||||||
}
|
}));
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -859,13 +942,9 @@ impl RedrawEvents for State {
|
|||||||
let point = ModelRect::point(col as usize, row as usize);
|
let point = ModelRect::point(col as usize, row as usize);
|
||||||
let (x, y, width, height) = point.to_area(line_height, char_width);
|
let (x, y, width, height) = point.to_area(line_height, char_width);
|
||||||
|
|
||||||
self.popup_menu.borrow_mut().show(&self,
|
self.popup_menu
|
||||||
menu,
|
.borrow_mut()
|
||||||
selected,
|
.show(&self, menu, selected, x, y, width, height);
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height);
|
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
@ -884,8 +963,12 @@ impl RedrawEvents for State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn tabline_update(&mut self, selected: Tabpage, tabs: Vec<(Tabpage, Option<&str>)>) -> RepaintMode {
|
fn tabline_update(&mut self,
|
||||||
self.tabs.update_tabs(&self.nvim.as_ref().unwrap(), &selected, &tabs);
|
selected: Tabpage,
|
||||||
|
tabs: Vec<(Tabpage, Option<&str>)>)
|
||||||
|
-> RepaintMode {
|
||||||
|
self.tabs
|
||||||
|
.update_tabs(&self.nvim.as_ref().unwrap(), &selected, &tabs);
|
||||||
|
|
||||||
RepaintMode::Nothing
|
RepaintMode::Nothing
|
||||||
}
|
}
|
||||||
@ -910,7 +993,7 @@ impl ModelBitamp {
|
|||||||
pub fn new(cols: usize, rows: usize) -> ModelBitamp {
|
pub fn new(cols: usize, rows: usize) -> ModelBitamp {
|
||||||
let words_for_cols = cols / 64 + 1;
|
let words_for_cols = cols / 64 + 1;
|
||||||
|
|
||||||
ModelBitamp {
|
ModelBitamp {
|
||||||
words_for_cols: words_for_cols,
|
words_for_cols: words_for_cols,
|
||||||
model: vec![0; rows * words_for_cols],
|
model: vec![0; rows * words_for_cols],
|
||||||
}
|
}
|
||||||
@ -950,4 +1033,3 @@ mod tests {
|
|||||||
assert_eq!(false, bitmap.get(62, 22));
|
assert_eq!(false, bitmap.get(62, 22));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
src/ui.rs
44
src/ui.rs
@ -8,10 +8,9 @@ use gtk_sys;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{ApplicationWindow, HeaderBar, ToolButton, Image, AboutDialog};
|
use gtk::{ApplicationWindow, HeaderBar, ToolButton, Image, AboutDialog};
|
||||||
use gio::{Menu, MenuItem, SimpleAction};
|
use gio::{Menu, MenuItem, SimpleAction};
|
||||||
use glib;
|
|
||||||
|
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use shell::Shell;
|
use shell::{Shell, ShellOptions};
|
||||||
use shell_dlg;
|
use shell_dlg;
|
||||||
use project::Projects;
|
use project::Projects;
|
||||||
|
|
||||||
@ -51,10 +50,10 @@ impl Components {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
pub fn new() -> Ui {
|
pub fn new(options: ShellOptions) -> Ui {
|
||||||
let comps = Arc::new(UiMutex::new(Components::new()));
|
let comps = Arc::new(UiMutex::new(Components::new()));
|
||||||
let settings = Rc::new(RefCell::new(Settings::new()));
|
let settings = Rc::new(RefCell::new(Settings::new()));
|
||||||
let shell = Rc::new(RefCell::new(Shell::new(settings.clone(), &comps)));
|
let shell = Rc::new(RefCell::new(Shell::new(settings.clone(), options)));
|
||||||
settings.borrow_mut().set_shell(Rc::downgrade(&shell));
|
settings.borrow_mut().set_shell(Rc::downgrade(&shell));
|
||||||
|
|
||||||
let projects = Projects::new(&comps.borrow().open_btn, shell.clone());
|
let projects = Projects::new(&comps.borrow().open_btn, shell.clone());
|
||||||
@ -68,10 +67,7 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self,
|
pub fn init(&mut self, app: >k::Application) {
|
||||||
app: >k::Application,
|
|
||||||
nvim_bin_path: Option<&String>,
|
|
||||||
open_path: Option<&String>) {
|
|
||||||
if self.initialized {
|
if self.initialized {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -89,7 +85,9 @@ impl Ui {
|
|||||||
|
|
||||||
let projects = self.projects.clone();
|
let projects = self.projects.clone();
|
||||||
comps.header_bar.pack_start(&comps.open_btn);
|
comps.header_bar.pack_start(&comps.open_btn);
|
||||||
comps.open_btn.connect_clicked(move |_| projects.borrow_mut().show());
|
comps
|
||||||
|
.open_btn
|
||||||
|
.connect_clicked(move |_| projects.borrow_mut().show());
|
||||||
|
|
||||||
let save_image = Image::new_from_icon_name("document-save",
|
let save_image = Image::new_from_icon_name("document-save",
|
||||||
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32);
|
gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32);
|
||||||
@ -112,40 +110,22 @@ impl Ui {
|
|||||||
let window = comps.window.as_ref().unwrap();
|
let window = comps.window.as_ref().unwrap();
|
||||||
|
|
||||||
window.set_titlebar(Some(&comps.header_bar));
|
window.set_titlebar(Some(&comps.header_bar));
|
||||||
|
window.set_default_size(800, 600);
|
||||||
|
|
||||||
let mut shell = self.shell.borrow_mut();
|
let shell = self.shell.borrow();
|
||||||
window.add(&**shell);
|
window.add(&**shell);
|
||||||
|
|
||||||
window.show_all();
|
window.show_all();
|
||||||
window.set_title("Neovim-gtk");
|
window.set_title("NeoVim-gtk");
|
||||||
|
|
||||||
let comps_ref = self.comps.clone();
|
let comps_ref = self.comps.clone();
|
||||||
let shell_ref = self.shell.clone();
|
let shell_ref = self.shell.clone();
|
||||||
window.connect_delete_event(move |_, _| gtk_delete(&*comps_ref, &*shell_ref));
|
window.connect_delete_event(move |_, _| gtk_delete(&*comps_ref, &*shell_ref));
|
||||||
|
|
||||||
shell.add_configure_event();
|
|
||||||
shell.init_nvim(nvim_bin_path);
|
|
||||||
shell.grab_focus();
|
shell.grab_focus();
|
||||||
|
|
||||||
if open_path.is_some() {
|
let comps_ref = self.comps.clone();
|
||||||
shell.open_file(open_path.unwrap());
|
shell.set_detach_cb(Some(move || comps_ref.borrow().close_window()));
|
||||||
}
|
|
||||||
|
|
||||||
self.guard_dispatch_thread(&mut shell);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn guard_dispatch_thread(&self, shell: &mut Shell) {
|
|
||||||
let state = shell.state.borrow();
|
|
||||||
let guard = state.nvim().session.take_dispatch_guard();
|
|
||||||
|
|
||||||
let comps = self.comps.clone();
|
|
||||||
thread::spawn(move || {
|
|
||||||
guard.join().expect("Can't join dispatch thread");
|
|
||||||
glib::idle_add(move || {
|
|
||||||
comps.borrow().close_window();
|
|
||||||
glib::Continue(false)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_main_menu(&self, app: >k::Application) {
|
fn create_main_menu(&self, app: >k::Application) {
|
||||||
|
Loading…
Reference in New Issue
Block a user