finish up cursor options

macos-click-through
Keith Simmons 5 years ago
parent a1ad41247d
commit e4dd7e572b

1
Cargo.lock generated

@ -2425,6 +2425,7 @@ dependencies = [
"num_cpus",
"pin-project-lite",
"signal-hook-registry",
"slab",
"tokio-macros",
"winapi 0.3.8",
]

@ -20,7 +20,7 @@ rust-embed = { version = "5.2.0", features = ["debug-embed"] }
image = "0.22.3"
#nvim-rs = "0.1.0"
nvim-rs = { git = "https://github.com/KillTheMule/nvim-rs", branch = "futures", features = [ "use_tokio" ] }
tokio = { version = "0.2.9", features = [ "blocking", "process" ] }
tokio = { version = "0.2.9", features = [ "blocking", "process", "time" ] }
async-trait = "0.1.18"
[build-dependencies]

@ -5,6 +5,7 @@ mod editor;
mod window;
mod renderer;
mod error_handling;
mod redraw_scheduler;
#[macro_use] extern crate derive_new;
#[macro_use] extern crate rust_embed;

@ -0,0 +1,28 @@
use std::sync::Arc;
use std::time::Instant;
use skulpin::winit::window::Window;
use tokio::runtime::Runtime;
use tokio::time::{Instant as TokioInstant, delay_until};
pub struct RedrawScheduler {
runtime: Runtime,
window: Arc<Window>
}
impl RedrawScheduler {
pub fn new(window: &Arc<Window>) -> RedrawScheduler {
RedrawScheduler {
runtime: Runtime::new().unwrap(),
window: window.clone()
}
}
pub fn schedule(&self, time: Instant) {
let window = self.window.clone();
self.runtime.spawn(async move {
delay_until(TokioInstant::from_std(time)).await;
window.request_redraw();
});
}
}

@ -34,7 +34,7 @@ impl BlinkStatus {
}
}
pub fn update_status(&mut self, new_cursor: &Cursor) -> bool {
pub fn update_status(&mut self, new_cursor: &Cursor) -> (bool, Option<Instant>) {
if self.previous_cursor.is_none() || new_cursor != self.previous_cursor.as_ref().unwrap() {
self.previous_cursor = Some(new_cursor.clone());
self.last_transition = Instant::now();
@ -48,16 +48,16 @@ impl BlinkStatus {
if new_cursor.blinkwait == Some(0) ||
new_cursor.blinkoff == Some(0) ||
new_cursor.blinkon == Some(0) {
return true;
return (true, None);
}
let delay = match self.state {
BlinkState::Waiting => new_cursor.blinkwait,
BlinkState::Off => new_cursor.blinkoff,
BlinkState::On => new_cursor.blinkon
}.filter(|millis| millis > &0).map(Duration::from_millis);
}.filter(|millis| millis > &0).map(|millis| Duration::from_millis(millis));
if delay.map(|delay| Instant::now() - self.last_transition > delay).unwrap_or(false) {
if delay.map(|delay| self.last_transition + delay < Instant::now()).unwrap_or(false) {
self.state = match self.state {
BlinkState::Waiting => BlinkState::On,
BlinkState::On => BlinkState::Off,
@ -66,10 +66,17 @@ impl BlinkStatus {
self.last_transition = Instant::now();
}
match self.state {
BlinkState::Waiting | BlinkState::Off => false,
BlinkState::On => true
}
(
match self.state {
BlinkState::Waiting | BlinkState::Off => false,
BlinkState::On => true
},
(match self.state {
BlinkState::Waiting => new_cursor.blinkwait,
BlinkState::Off => new_cursor.blinkoff,
BlinkState::On => new_cursor.blinkon
}).map(|delay| self.last_transition + Duration::from_millis(delay))
)
}
}
@ -166,8 +173,8 @@ impl CursorRenderer {
font_width: f32, font_height: f32,
paint: &mut Paint, editor: Arc<Mutex<Editor>>,
shaper: &mut CachingShaper, fonts_lookup: &mut FontLookup,
canvas: &mut Canvas) -> bool {
let render = self.blink_status.update_status(&cursor);
canvas: &mut Canvas) -> (bool, Option<Instant>) {
let (render, scheduled_update) = self.blink_status.update_status(&cursor);
self.previous_position = {
let editor = editor.lock().unwrap();
@ -233,6 +240,6 @@ impl CursorRenderer {
canvas.restore();
}
animating
(animating, scheduled_update)
}
}

@ -1,4 +1,6 @@
use std::sync::{Arc, Mutex};
use std::time::Instant;
use skulpin::CoordinateSystemHelper;
use skulpin::skia_safe::{Canvas, Paint, Surface, Budgeted, Rect, colors};
use skulpin::skia_safe::gpu::SurfaceOrigin;
@ -19,7 +21,8 @@ const DEFAULT_FONT_SIZE: f32 = 14.0;
#[derive(new)]
pub struct DrawResult {
pub is_animating: bool,
pub font_changed: bool
pub font_changed: bool,
pub scheduled_update: Option<Instant>
}
pub struct Renderer {
@ -167,13 +170,13 @@ impl Renderer {
self.surface = Some(surface);
let cursor_animating = self.cursor_renderer.draw(
let (cursor_animating, scheduled_cursor_update) = self.cursor_renderer.draw(
cursor, &default_colors,
self.font_width, self.font_height,
&mut self.paint, self.editor.clone(),
&mut self.shaper, &mut self.fonts_lookup,
gpu_canvas);
DrawResult::new(draw_commands.len() > 0 || cursor_animating, font_changed)
DrawResult::new(draw_commands.len() > 0 || cursor_animating, font_changed, scheduled_cursor_update)
}
}

@ -10,9 +10,9 @@ use skulpin::winit::event_loop::{ControlFlow, EventLoop};
use skulpin::winit::window::{Icon, WindowBuilder};
use crate::editor::Editor;
use crate::bridge::{construct_keybinding_string, Bridge};
use crate::bridge::{construct_keybinding_string, Bridge, UiCommand};
use crate::renderer::Renderer;
use crate::bridge::UiCommand;
use crate::redraw_scheduler::RedrawScheduler;
#[derive(RustEmbed)]
#[folder = "assets/"]
@ -75,6 +75,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut bridge: Bridge, initial_size: (u6
editor.window = Some(window.clone());
}
let redraw_scheduler = RedrawScheduler::new(&window);
let mut live_frames = 0;
let mut frame_start = Instant::now();
event_loop.run(move |event, _window_target, control_flow| {
@ -197,6 +198,10 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut bridge: Bridge, initial_size: (u6
} else {
*control_flow = ControlFlow::Wait;
}
if let Some(scheduled_update) = draw_result.scheduled_update {
redraw_scheduler.schedule(scheduled_update);
}
}) {
println!("Error during draw: {:?}", e);
*control_flow = ControlFlow::Exit

Loading…
Cancel
Save