Make only changed area repaintable

This commit is contained in:
daa 2017-03-24 22:23:22 +03:00
parent 865054e36e
commit 0c5d57346b
3 changed files with 55 additions and 26 deletions

View File

@ -2,8 +2,8 @@ use cairo;
use ui_model::Color;
use ui::UI;
use shell::{Shell, NvimMode};
use nvim::{RepaintMode, RedrawEvents};
use std::sync::{Arc, Mutex};
use gtk::WidgetExt;
use glib;
@ -31,12 +31,29 @@ impl Alpha {
}
enum AnimPhase {
Shown,
Shown(i32),
Hide,
Hidden,
Hidden(i32),
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,
@ -44,14 +61,13 @@ pub struct State {
impl State {
pub fn new() -> State {
State {
State {
alpha: Alpha(1.0),
anim_phase: AnimPhase::Shown,
anim_phase: AnimPhase::Shown(500),
}
}
}
// display, 2 sec -> hiding 1 sec -> not visible 1 sec -> showing 1 sec
pub struct Cursor {
timer: Option<glib::SourceId>,
@ -60,7 +76,7 @@ pub struct Cursor {
impl Cursor {
pub fn new() -> Cursor {
Cursor {
timer: None,
state: Arc::new(Mutex::new(State::new())),
@ -73,41 +89,54 @@ impl Cursor {
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 => {
AnimPhase::Shown(_) => {
mut_state.anim_phase = AnimPhase::Hide;
}
AnimPhase::Hide => {
if !mut_state.alpha.hide(0.1) {
mut_state.anim_phase = AnimPhase::Hidden;
if !mut_state.alpha.hide(0.3) {
mut_state.anim_phase = AnimPhase::Hidden(300);
}
}
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;
if !mut_state.alpha.show(0.3) {
mut_state.anim_phase = AnimPhase::Shown(500);
}
}
}
SHELL!(&shell = {
// FIXME: repaint only changed area
shell.drawing_area.queue_draw();
let point = shell.model.cur_point();
shell.on_redraw(&RepaintMode::Area(point));
});
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) {
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();
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);
ctx.set_source_rgba(1.0 - bg.0, 1.0 - bg.1, 1.0 - bg.2, 0.6 * state.alpha.0);
let cursor_width = if shell.mode == NvimMode::Insert {
char_width / 5.0

View File

@ -469,7 +469,7 @@ fn gtk_configure_event(_: &DrawingArea, ev: &EventConfigure) -> bool {
impl RedrawEvents for Shell {
fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode {
RepaintMode::Area(self.model.set_cursor(row, col))
RepaintMode::Area(self.model.set_cursor(row as usize, col as usize))
}
fn on_put(&mut self, text: &str) -> RepaintMode {

View File

@ -152,11 +152,11 @@ impl UiModel {
ModelRect::point(self.cur_row, self.cur_col)
}
pub fn set_cursor(&mut self, row: u64, col: u64) -> ModelRect {
pub fn set_cursor(&mut self, row: usize, col: usize) -> ModelRect {
let mut changed_region = self.cur_point();
self.cur_row = row as usize;
self.cur_col = col as usize;
self.cur_row = row;
self.cur_col = col;
changed_region.join(&self.cur_point());
@ -298,8 +298,8 @@ impl ModelRect {
pub fn to_area(&self, line_height: f64, char_width: f64) -> (i32, i32, i32, i32) {
(self.left as i32 * char_width as i32,
self.top as i32 * line_height as i32,
(self.right - self.left + 1) as i32 * char_width as i32- 1,
(self.bot - self.top + 1) as i32 * line_height as i32 - 1)
(self.right - self.left + 1) as i32 * char_width as i32,
(self.bot - self.top + 1) as i32 * line_height as i32)
}
pub fn from_area(line_height: f64, char_width: f64, x1: f64, y1: f64, x2: f64, y2: f64) -> ModelRect {
@ -474,8 +474,8 @@ mod tests {
assert_eq!(5, x);
assert_eq!(10, y);
assert_eq!(4, width);
assert_eq!(9, height);
assert_eq!(5, width);
assert_eq!(10, height);
}
#[test]