diff --git a/src/input.rs b/src/input.rs index 1fe0e2d..680bb71 100644 --- a/src/input.rs +++ b/src/input.rs @@ -6,7 +6,7 @@ use phf; include!(concat!(env!("OUT_DIR"), "/key_map_table.rs")); -fn keyval_to_input_string(val: &str, state: gdk::ModifierType) -> String { +pub fn keyval_to_input_string(val: &str, state: gdk::ModifierType) -> String { let mut input = String::from("<"); if state.contains(gdk::enums::modifier_type::ShiftMask) { input.push_str("S-"); diff --git a/src/nvim.rs b/src/nvim.rs index 0b62bde..0a0ac8b 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -33,6 +33,10 @@ pub trait RedrawEvents { fn on_update_fg(&mut self, fg: i64); fn on_mode_change(&mut self, mode: &str); + + fn on_mouse_on(&mut self); + + fn on_mouse_off(&mut self); } macro_rules! try_str { @@ -195,6 +199,18 @@ fn call(method: &str, args: Vec) { Ok(()) }); } + "mouse_on" => { + safe_call(move |ui| { + ui.on_mouse_on(); + Ok(()) + }); + } + "mouse_off" => { + safe_call(move |ui| { + ui.on_mouse_off(); + Ok(()) + }); + } _ => println!("Event {}({:?})", method, args), }; } diff --git a/src/ui.rs b/src/ui.rs index 41f0a0a..57bd3a5 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -12,7 +12,7 @@ use cairo::enums::{FontWeight, FontSlant}; use gtk; use gtk::prelude::*; use gtk::{Window, WindowType, DrawingArea, Grid, ToolButton, ButtonBox, Orientation, Image}; -use gdk::{Event, EventKey, EventConfigure}; +use gdk::{Event, EventKey, EventConfigure, EventButton, EventMotion, EventType}; use glib; use glib_sys; use neovim_lib::{Neovim, NeovimApi}; @@ -20,7 +20,7 @@ use neovim_lib::{Neovim, NeovimApi}; use ui_model::{UiModel, Attrs, Color, COLOR_BLACK, COLOR_WHITE}; use nvim::RedrawEvents; -use input::convert_key; +use input::{convert_key, keyval_to_input_string}; #[cfg(target_os = "linux")] const FONT_NAME: &'static str = "Droid Sans Mono for Powerline"; @@ -56,6 +56,7 @@ pub struct Ui { char_width: Option, resize_timer: Option, mode: NvimMode, + mouse_enabled: bool, } impl Ui { @@ -72,6 +73,7 @@ impl Ui { char_width: None, resize_timer: None, mode: NvimMode::Insert, + mouse_enabled: false, } } @@ -108,7 +110,12 @@ impl Ui { self.drawing_area.set_size_request(500, 300); self.drawing_area.set_hexpand(true); self.drawing_area.set_vexpand(true); + grid.attach(&self.drawing_area, 0, 1, 1, 1); + + self.drawing_area.connect_button_press_event(gtk_button_press); + self.drawing_area.connect_button_release_event(gtk_button_release); + self.drawing_area.connect_motion_notify_event(gtk_motion_notify); self.drawing_area.connect_draw(gtk_draw); self.window.add(&grid); @@ -119,6 +126,46 @@ impl Ui { } } +fn gtk_button_press(_: &DrawingArea, ev: &EventButton) -> Inhibit { + if ev.get_event_type() != EventType::ButtonPress { + return Inhibit(false); + } + + UI.with(|ui_cell| { + let mut ui = ui_cell.borrow_mut(); + if !ui.mouse_enabled { + return; + } + + if let Some(line_height) = ui.line_height { + if let Some(char_width) = ui.char_width { + let nvim = ui.nvim(); + let (x, y) = ev.get_position(); + let col = (x / char_width).round() as u64; + let row = (y / line_height).round() as u64; + let input_str = format!("{}<{},{}>", keyval_to_input_string("LeftMouse", ev.get_state()), col ,row); + nvim.input(&input_str).expect("Can't send mouse input event"); + } + } + }); + Inhibit(false) +} + +fn gtk_button_release(_: &DrawingArea, _: &EventButton) -> Inhibit { + UI.with(|ui_cell| { + let mut ui = ui_cell.borrow_mut(); + }); + Inhibit(false) +} + +fn gtk_motion_notify(_: &DrawingArea, _: &EventMotion) -> Inhibit { + UI.with(|ui_cell| { + let mut ui = ui_cell.borrow_mut(); + let nvim = ui.nvim(); + }); + Inhibit(false) +} + fn gtk_delete(_: &Window, _: &Event) -> Inhibit { UI.with(|ui_cell| { let mut ui = ui_cell.borrow_mut(); @@ -376,6 +423,14 @@ impl RedrawEvents for Ui { _ => self.mode = NvimMode::Other, } } + + fn on_mouse_on(&mut self) { + self.mouse_enabled = true; + } + + fn on_mouse_off(&mut self) { + self.mouse_enabled = false; + } } fn split_color(indexed_color: u64) -> Color {