From 865054e36e2cc739c9caa6471f5c762dfcd7344d Mon Sep 17 00:00:00 2001 From: daa84 Date: Thu, 23 Mar 2017 18:04:24 +0300 Subject: [PATCH] Implement base cursor animation, still need a lot of improvements --- src/cursor.rs | 121 ++++++++++++++++++++++++++++++++++++++++---------- src/main.rs | 3 +- src/shell.rs | 16 +------ src/ui.rs | 16 +++++++ 4 files changed, 117 insertions(+), 39 deletions(-) diff --git a/src/cursor.rs b/src/cursor.rs index f011eb4..053e4e1 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -1,22 +1,113 @@ use cairo; use ui_model::Color; +use ui::UI; use shell::{Shell, NvimMode}; +use std::sync::{Arc, Mutex}; +use gtk::WidgetExt; use glib; +struct Alpha(f64); + +impl Alpha { + pub fn show(&mut self, step: f64) -> bool { + self.0 += step; + if self.0 > 1.0 { + self.0 = 1.0; + false + } else { + true + } + } + pub fn hide(&mut self, step: f64) -> bool { + self.0 -= step; + if self.0 < 0.0 { + self.0 = 0.0; + false + } else { + true + } + } +} + +enum AnimPhase { + Shown, + Hide, + Hidden, + Show, +} + +pub struct State { + alpha: Alpha, + anim_phase: AnimPhase, +} + +impl State { + pub fn new() -> State { + State { + alpha: Alpha(1.0), + anim_phase: AnimPhase::Shown, + } + } +} + // display, 2 sec -> hiding 1 sec -> not visible 1 sec -> showing 1 sec pub struct Cursor { + timer: Option, + + state: Arc>, } impl Cursor { pub fn new() -> Cursor { - Cursor { } + + Cursor { + timer: None, + state: Arc::new(Mutex::new(State::new())), + } + + } + + pub fn start(&mut self) { + if self.timer.is_none() { + let state = self.state.clone(); + self.timer = Some(glib::timeout_add(100, move || { + let mut mut_state = state.lock().unwrap(); + match mut_state.anim_phase { + AnimPhase::Shown => { + mut_state.anim_phase = AnimPhase::Hide; + } + AnimPhase::Hide => { + if !mut_state.alpha.hide(0.1) { + mut_state.anim_phase = AnimPhase::Hidden; + } + } + AnimPhase::Hidden => { + mut_state.anim_phase = AnimPhase::Show; + } + AnimPhase::Show => { + if !mut_state.alpha.show(0.1) { + mut_state.anim_phase = AnimPhase::Shown; + } + } + } + + SHELL!(&shell = { + // FIXME: repaint only changed area + shell.drawing_area.queue_draw(); + }); + glib::Continue(true) + })); + } } pub fn draw(&self, ctx: &cairo::Context, shell: &Shell, char_width: f64, line_height: f64, line_y: f64, double_width: bool, bg: &Color) { + + let current_point = ctx.get_current_point(); - ctx.set_source_rgba(1.0 - bg.0, 1.0 - bg.1, 1.0 - bg.2, 0.5); + let state = self.state.lock().unwrap(); + ctx.set_source_rgba(1.0 - bg.0, 1.0 - bg.1, 1.0 - bg.2, 0.5 * state.alpha.0); let cursor_width = if shell.mode == NvimMode::Insert { char_width / 5.0 @@ -33,28 +124,10 @@ impl Cursor { } } - -pub struct Animation { - state_stream: Vec>, - state: Option>, - timer: Option, -} - -impl Animation { - pub fn new() -> Animation { - Animation { - state_stream: vec![], - state: None, - timer: None, +impl Drop for Cursor { + fn drop(&mut self) { + if let Some(timer_id) = self.timer { + glib::source_remove(timer_id); } } } - -trait AnimationState { - fn clone(&self) -> AnimationState; - - // [TODO]: Description - repaint rect here - fn next(&mut self) -> Option; - - fn paint(&self, ctx: &cairo::Context, shell: &Shell); -} diff --git a/src/main.rs b/src/main.rs index 41c8436..315861c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,9 +11,10 @@ extern crate neovim_lib; extern crate phf; mod nvim; -mod shell; mod ui_model; +#[macro_use] mod ui; +mod shell; mod input; mod settings; mod cursor; diff --git a/src/shell.rs b/src/shell.rs index 710fa82..343f2d0 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -22,20 +22,6 @@ use cursor::Cursor; const DEFAULT_FONT_NAME: &'static str = "DejaVu Sans Mono 12"; -macro_rules! SHELL { - (&$id:ident = $expr:expr) => ( - UI.with(|ui_cell| { - let $id = &ui_cell.borrow().shell; - $expr - }); - ); - ($id:ident = $expr:expr) => ( - UI.with(|ui_cell| { - let mut $id = &mut ui_cell.borrow_mut().shell; - $expr - }); - ); -} #[derive(PartialEq)] pub enum NvimMode { @@ -104,6 +90,8 @@ impl Shell { pub fn add_configure_event(&mut self) { self.drawing_area.connect_configure_event(gtk_configure_event); + + self.cursor.start(); } pub fn set_nvim(&mut self, nvim: Neovim) { diff --git a/src/ui.rs b/src/ui.rs index f0a5c35..1cd17d4 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -29,6 +29,22 @@ ui_thread_var!(UI, Ui, Ui::new()); ui_thread_var!(SET, settings::Settings, settings::Settings::new()); +#[macro_export] +macro_rules! SHELL { + (&$id:ident = $expr:expr) => ( + UI.with(|ui_cell| { + let $id = &ui_cell.borrow().shell; + $expr + }); + ); + ($id:ident = $expr:expr) => ( + UI.with(|ui_cell| { + let mut $id = &mut ui_cell.borrow_mut().shell; + $expr + }); + ); +} + pub struct Ui { pub initialized: bool, pub window: Option,