Optimization of cursor animation

This commit is contained in:
daa 2017-03-24 23:34:03 +03:00
parent 0c5d57346b
commit cd55351042
1 changed files with 62 additions and 60 deletions

View File

@ -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<glib::SourceId>,
}
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<glib::SourceId>,
state: Arc<Mutex<State>>,
}
@ -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<Mutex<State>>) -> 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);
}
}