Make only changed area repaintable
This commit is contained in:
parent
865054e36e
commit
0c5d57346b
@ -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,
|
||||
@ -46,12 +63,11 @@ impl State {
|
||||
pub fn new() -> 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>,
|
||||
|
||||
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user