Implement base cursor animation, still need a lot of improvements

This commit is contained in:
daa84 2017-03-23 18:04:24 +03:00
parent 75eac4bc7d
commit 865054e36e
4 changed files with 117 additions and 39 deletions

View File

@ -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<glib::SourceId>,
state: Arc<Mutex<State>>,
}
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<Box<AnimationState>>,
state: Option<Box<AnimationState>>,
timer: Option<glib::SourceId>,
}
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<u32>;
fn paint(&self, ctx: &cairo::Context, shell: &Shell);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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<ApplicationWindow>,