From cd5535104279a996d851a4a494ceaf43d924eb00 Mon Sep 17 00:00:00 2001 From: daa Date: Fri, 24 Mar 2017 23:34:03 +0300 Subject: [PATCH] Optimization of cursor animation --- src/cursor.rs | 122 +++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/src/cursor.rs b/src/cursor.rs index f6e1169..8b4acbd 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -31,46 +31,30 @@ impl Alpha { } enum AnimPhase { - Shown(i32), + Shown, Hide, - Hidden(i32), + Hidden, Show, } -impl AnimPhase { - fn sub(&mut self, step: i32) -> bool { - match self { - &mut AnimPhase::Shown(ref mut val) | - &mut AnimPhase::Hidden(ref mut val) => { - *val -= step; - if *val <= 0 { - false - } else { - true - } - } - _ => false, - } - } -} - pub struct State { alpha: Alpha, anim_phase: AnimPhase, + + timer: Option, } impl State { pub fn new() -> State { State { alpha: Alpha(1.0), - anim_phase: AnimPhase::Shown(500), + anim_phase: AnimPhase::Shown, + timer: None, } } } pub struct Cursor { - timer: Option, - state: Arc>, } @@ -78,49 +62,16 @@ impl Cursor { pub fn new() -> 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(); - - // wait - // [TODO]: Implement wait through new timeout - 2017-03-24 10:21 - if mut_state.anim_phase.sub(100) { - return glib::Continue(true); - } - - match mut_state.anim_phase { - AnimPhase::Shown(_) => { - mut_state.anim_phase = AnimPhase::Hide; - } - AnimPhase::Hide => { - if !mut_state.alpha.hide(0.3) { - mut_state.anim_phase = AnimPhase::Hidden(300); - } - } - AnimPhase::Hidden(_) => { - mut_state.anim_phase = AnimPhase::Show; - } - AnimPhase::Show => { - if !mut_state.alpha.show(0.3) { - mut_state.anim_phase = AnimPhase::Shown(500); - } - } - } - - SHELL!(&shell = { - let point = shell.model.cur_point(); - shell.on_redraw(&RepaintMode::Area(point)); - }); - glib::Continue(true) - })); + let state = self.state.clone(); + let mut mut_state = self.state.lock().unwrap(); + if mut_state.timer.is_none() { + mut_state.timer = Some(glib::timeout_add(100, move || anim_step(&state))); } } @@ -153,9 +104,60 @@ impl Cursor { } } +// [TODO]: Reset animation phase on events - 2017-03-24 11:33 +fn anim_step(state: &Arc>) -> glib::Continue { + let moved_state = state.clone(); + let mut mut_state = state.lock().unwrap(); + + let next_event = match mut_state.anim_phase { + AnimPhase::Shown => { + mut_state.anim_phase = AnimPhase::Hide; + Some(100) + } + AnimPhase::Hide => { + if !mut_state.alpha.hide(0.3) { + mut_state.anim_phase = AnimPhase::Hidden; + + Some(300) + } else { + None + } + } + AnimPhase::Hidden => { + mut_state.anim_phase = AnimPhase::Show; + + Some(100) + } + AnimPhase::Show => { + if !mut_state.alpha.show(0.3) { + mut_state.anim_phase = AnimPhase::Shown; + + Some(500) + } else { + None + } + } + }; + + SHELL!(&shell = { + let point = shell.model.cur_point(); + shell.on_redraw(&RepaintMode::Area(point)); + }); + + + if let Some(timeout) = next_event { + mut_state.timer = Some(glib::timeout_add(timeout, move || anim_step(&moved_state) )); + + glib::Continue(false) + } else { + glib::Continue(true) + } + +} + impl Drop for Cursor { fn drop(&mut self) { - if let Some(timer_id) = self.timer { + if let Some(timer_id) = self.state.lock().unwrap().timer { glib::source_remove(timer_id); } }