animate window positions (doesn't take framerate into account)

macos-click-through
keith 4 years ago
parent 5349f60e12
commit f14a7f7dc6

@ -18,13 +18,18 @@ pub enum UiCommand {
Keyboard(String), Keyboard(String),
MouseButton { MouseButton {
action: String, action: String,
grid_id: u64,
position: (u32, u32), position: (u32, u32),
}, },
Scroll { Scroll {
direction: String, direction: String,
grid_id: u64,
position: (u32, u32),
},
Drag {
grid_id: u64,
position: (u32, u32), position: (u32, u32),
}, },
Drag(u32, u32),
FileDrop(String), FileDrop(String),
FocusLost, FocusLost,
FocusGained, FocusGained,
@ -48,27 +53,32 @@ impl UiCommand {
} }
UiCommand::MouseButton { UiCommand::MouseButton {
action, action,
grid_id,
position: (grid_x, grid_y), position: (grid_x, grid_y),
} => { } => {
if EDITOR.lock().mouse_enabled { if EDITOR.lock().mouse_enabled {
nvim.input_mouse("left", &action, "", 0, grid_y as i64, grid_x as i64) nvim.input_mouse("left", &action, "", grid_id as i64, grid_y as i64, grid_x as i64)
.await .await
.expect("Mouse Input Failed"); .expect("Mouse Input Failed");
} }
} }
UiCommand::Scroll { UiCommand::Scroll {
direction, direction,
grid_id,
position: (grid_x, grid_y), position: (grid_x, grid_y),
} => { } => {
if EDITOR.lock().mouse_enabled { if EDITOR.lock().mouse_enabled {
nvim.input_mouse("wheel", &direction, "", 0, grid_y as i64, grid_x as i64) nvim.input_mouse("wheel", &direction, "", grid_id as i64, grid_y as i64, grid_x as i64)
.await .await
.expect("Mouse Scroll Failed"); .expect("Mouse Scroll Failed");
} }
} }
UiCommand::Drag(grid_x, grid_y) => { UiCommand::Drag {
grid_id,
position: (grid_x, grid_y)
} => {
if EDITOR.lock().mouse_enabled { if EDITOR.lock().mouse_enabled {
nvim.input_mouse("left", "drag", "", 0, grid_y as i64, grid_x as i64) nvim.input_mouse("left", "drag", "", grid_id as i64, grid_y as i64, grid_x as i64)
.await .await
.expect("Mouse Drag Failed"); .expect("Mouse Drag Failed");
} }

@ -34,7 +34,6 @@ impl CharacterGrid {
let default_cell: GridCell = None; let default_cell: GridCell = None;
let mut new_characters = vec![default_cell; new_cell_count]; let mut new_characters = vec![default_cell; new_cell_count];
dbg!(self.width);
for x in 0..self.width.min(width) { for x in 0..self.width.min(width) {
for y in 0..self.height.min(height) { for y in 0..self.height.min(height) {
if let Some(existing_cell) = self.get_cell(x, y) { if let Some(existing_cell) = self.get_cell(x, y) {

@ -4,9 +4,8 @@ use std::sync::Arc;
use log::trace; use log::trace;
use skulpin::skia_safe::gpu::SurfaceOrigin; use skulpin::skia_safe::gpu::SurfaceOrigin;
use skulpin::skia_safe::{ use skulpin::skia_safe::{
colors, dash_path_effect, Budgeted, Canvas, ImageInfo, Paint, Rect, Surface, Color colors, dash_path_effect, Budgeted, Canvas, ImageInfo, Paint, Rect, Surface
}; };
use skulpin::skia_safe::paint::Style as PaintStyle;
use skulpin::CoordinateSystemHelper; use skulpin::CoordinateSystemHelper;
mod caching_shaper; mod caching_shaper;
@ -17,34 +16,45 @@ pub use caching_shaper::CachingShaper;
pub use font_options::*; pub use font_options::*;
use crate::editor::{Style, WindowRenderInfo, EDITOR}; use crate::editor::{Style, WindowRenderInfo, EDITOR};
use crate::redraw_scheduler::REDRAW_SCHEDULER;
use cursor_renderer::CursorRenderer; use cursor_renderer::CursorRenderer;
pub struct RenderedWindow {
surface: Surface,
current_position: (f32, f32)
}
pub struct Renderer { pub struct Renderer {
window_surfaces: HashMap<u64, Surface>, rendered_windows: HashMap<u64, RenderedWindow>,
paint: Paint, paint: Paint,
shaper: CachingShaper, shaper: CachingShaper,
pub font_width: f32, pub font_width: f32,
pub font_height: f32, pub font_height: f32,
pub window_regions: Vec<(u64, Rect)>,
cursor_renderer: CursorRenderer, cursor_renderer: CursorRenderer,
} }
impl Renderer { impl Renderer {
pub fn new() -> Renderer { pub fn new() -> Renderer {
let rendered_windows = HashMap::new();
let mut paint = Paint::new(colors::WHITE, None); let mut paint = Paint::new(colors::WHITE, None);
paint.set_anti_alias(false); paint.set_anti_alias(false);
let mut shaper = CachingShaper::new(); let mut shaper = CachingShaper::new();
let (font_width, font_height) = shaper.font_base_dimensions(); let (font_width, font_height) = shaper.font_base_dimensions();
let window_regions = Vec::new();
let cursor_renderer = CursorRenderer::new(); let cursor_renderer = CursorRenderer::new();
Renderer { Renderer {
window_surfaces: HashMap::new(), rendered_windows,
paint, paint,
shaper, shaper,
font_width, font_width,
font_height, font_height,
window_regions,
cursor_renderer, cursor_renderer,
} }
} }
@ -188,26 +198,39 @@ impl Renderer {
root_canvas: &mut Canvas, root_canvas: &mut Canvas,
window_render_info: &WindowRenderInfo, window_render_info: &WindowRenderInfo,
default_style: &Arc<Style>, default_style: &Arc<Style>,
) { ) -> (u64, Rect) {
let (grid_left, grid_top) = window_render_info.grid_position;
let target_left = grid_left as f32 * self.font_width;
let target_top = grid_top as f32 * self.font_height;
let image_width = (window_render_info.width as f32 * self.font_width) as i32; let image_width = (window_render_info.width as f32 * self.font_width) as i32;
let image_height = (window_render_info.height as f32 * self.font_height) as i32; let image_height = (window_render_info.height as f32 * self.font_height) as i32;
let mut surface = if window_render_info.should_clear { let mut rendered_window = if window_render_info.should_clear {
None None
} else { } else {
self.window_surfaces.remove(&window_render_info.grid_id) self.rendered_windows.remove(&window_render_info.grid_id)
} }
.unwrap_or_else(|| { .unwrap_or_else(|| {
self.build_window_surface(root_canvas, &default_style, (image_width, image_height)) let surface = self.build_window_surface(root_canvas, &default_style, (image_width, image_height));
RenderedWindow {
surface,
current_position: (target_left, target_top)
}
}); });
if surface.width() != image_width || surface.height() != image_height { if rendered_window.surface.width() != image_width || rendered_window.surface.height() != image_height {
let mut old_surface = surface; let mut old_surface = rendered_window.surface;
surface = self.build_window_surface(root_canvas, &default_style, (image_width, image_height)); rendered_window.surface = self.build_window_surface(root_canvas, &default_style, (image_width, image_height));
old_surface.draw(surface.canvas(), (0.0, 0.0), None); old_surface.draw(rendered_window.surface.canvas(), (0.0, 0.0), None);
} }
let mut canvas = surface.canvas(); let (current_left, current_top) = rendered_window.current_position;
let current_left = current_left + (target_left - current_left) * 0.4;
let current_top = current_top + (target_top - current_top) * 0.4;
rendered_window.current_position = (current_left, current_top);
let mut canvas = rendered_window.surface.canvas();
for command in window_render_info.draw_commands.iter() { for command in window_render_info.draw_commands.iter() {
self.draw_background( self.draw_background(
@ -230,20 +253,17 @@ impl Renderer {
); );
} }
let (grid_left, grid_top) = window_render_info.grid_position;
let image_left = grid_left as f32 * self.font_width;
let image_top = grid_top as f32 * self.font_height;
root_canvas.save_layer(&Default::default()); root_canvas.save_layer(&Default::default());
unsafe { unsafe {
surface.draw(root_canvas.surface().unwrap().canvas(), (image_left, image_top), None); rendered_window.surface.draw(root_canvas.surface().unwrap().canvas(), (current_left, current_top), None);
} }
root_canvas.restore(); root_canvas.restore();
self.window_surfaces self.rendered_windows.insert(window_render_info.grid_id, rendered_window);
.insert(window_render_info.grid_id, surface);
(window_render_info.grid_id, Rect::new(current_left, current_top, current_left + image_width as f32, current_top + image_height as f32))
} }
pub fn draw( pub fn draw(
@ -254,6 +274,8 @@ impl Renderer {
) -> bool { ) -> bool {
trace!("Rendering"); trace!("Rendering");
REDRAW_SCHEDULER.queue_next_frame();
let (render_info, default_style, cursor, guifont_setting) = { let (render_info, default_style, cursor, guifont_setting) = {
let mut editor = EDITOR.lock(); let mut editor = EDITOR.lock();
( (
@ -271,14 +293,15 @@ impl Renderer {
.unwrap_or(false); .unwrap_or(false);
for closed_window_id in render_info.closed_window_ids.iter() { for closed_window_id in render_info.closed_window_ids.iter() {
self.window_surfaces.remove(&closed_window_id); self.rendered_windows.remove(&closed_window_id);
} }
coordinate_system_helper.use_logical_coordinates(gpu_canvas); coordinate_system_helper.use_logical_coordinates(gpu_canvas);
for window_render_info in render_info.windows.iter() { self.window_regions = render_info.windows
self.draw_window(gpu_canvas, window_render_info, &default_style); .iter()
} .map(|window_render_info| self.draw_window(gpu_canvas, window_render_info, &default_style))
.collect();
self.cursor_renderer.draw( self.cursor_renderer.draw(
cursor, cursor,

@ -12,6 +12,7 @@ use skulpin::{
CoordinateSystem, LogicalSize, PhysicalSize, PresentMode, Renderer as SkulpinRenderer, CoordinateSystem, LogicalSize, PhysicalSize, PresentMode, Renderer as SkulpinRenderer,
RendererBuilder, Sdl2Window, Window, RendererBuilder, Sdl2Window, Window,
}; };
use skulpin::skia_safe::Rect;
use crate::bridge::{produce_neovim_keybinding_string, UiCommand, BRIDGE}; use crate::bridge::{produce_neovim_keybinding_string, UiCommand, BRIDGE};
use crate::editor::EDITOR; use crate::editor::EDITOR;
@ -52,6 +53,7 @@ struct WindowWrapper {
renderer: Renderer, renderer: Renderer,
mouse_down: bool, mouse_down: bool,
mouse_position: LogicalSize, mouse_position: LogicalSize,
grid_id_under_mouse: u64,
title: String, title: String,
previous_size: LogicalSize, previous_size: LogicalSize,
transparency: f32, transparency: f32,
@ -167,6 +169,7 @@ impl WindowWrapper {
width: 0, width: 0,
height: 0, height: 0,
}, },
grid_id_under_mouse: 0,
title: String::from("Neovide"), title: String::from("Neovide"),
previous_size: logical_size, previous_size: logical_size,
transparency: 1.0, transparency: 1.0,
@ -278,24 +281,42 @@ impl WindowWrapper {
pub fn handle_pointer_motion(&mut self, x: i32, y: i32) { pub fn handle_pointer_motion(&mut self, x: i32, y: i32) {
let previous_position = self.mouse_position; let previous_position = self.mouse_position;
let physical_size = PhysicalSize::new(
(x as f32 / self.renderer.font_width) as u32,
(y as f32 / self.renderer.font_height) as u32,
);
let sdl_window_wrapper = Sdl2Window::new(&self.window); let sdl_window_wrapper = Sdl2Window::new(&self.window);
self.mouse_position = physical_size.to_logical(sdl_window_wrapper.scale_factor()); let logical_position = PhysicalSize::new(x as u32, y as u32)
if self.mouse_down && previous_position != self.mouse_position { .to_logical(sdl_window_wrapper.scale_factor());
BRIDGE.queue_command(UiCommand::Drag(
self.mouse_position.width, let mut top_grid_position = None;
self.mouse_position.height,
)); for (grid_id, window_region) in self.renderer.window_regions.iter() {
if logical_position.width >= window_region.left as u32 && logical_position.width < window_region.right as u32 &&
logical_position.height >= window_region.top as u32 && logical_position.height < window_region.bottom as u32 {
top_grid_position = Some((
grid_id,
LogicalSize::new(logical_position.width - window_region.left as u32, logical_position.height - window_region.top as u32)
));
}
}
if let Some((grid_id, grid_position)) = top_grid_position {
self.grid_id_under_mouse = dbg!(*grid_id);
self.mouse_position = LogicalSize::new(
(grid_position.width as f32 / self.renderer.font_width) as u32,
(grid_position.height as f32 / self.renderer.font_height) as u32
);
if self.mouse_down && previous_position != self.mouse_position {
BRIDGE.queue_command(UiCommand::Drag {
grid_id: self.grid_id_under_mouse,
position: (self.mouse_position.width, self.mouse_position.height),
});
}
} }
} }
pub fn handle_pointer_down(&mut self) { pub fn handle_pointer_down(&mut self) {
BRIDGE.queue_command(UiCommand::MouseButton { BRIDGE.queue_command(UiCommand::MouseButton {
action: String::from("press"), action: String::from("press"),
grid_id: self.grid_id_under_mouse,
position: (self.mouse_position.width, self.mouse_position.height), position: (self.mouse_position.width, self.mouse_position.height),
}); });
self.mouse_down = true; self.mouse_down = true;
@ -304,6 +325,7 @@ impl WindowWrapper {
pub fn handle_pointer_up(&mut self) { pub fn handle_pointer_up(&mut self) {
BRIDGE.queue_command(UiCommand::MouseButton { BRIDGE.queue_command(UiCommand::MouseButton {
action: String::from("release"), action: String::from("release"),
grid_id: self.grid_id_under_mouse,
position: (self.mouse_position.width, self.mouse_position.height), position: (self.mouse_position.width, self.mouse_position.height),
}); });
self.mouse_down = false; self.mouse_down = false;
@ -319,6 +341,7 @@ impl WindowWrapper {
if let Some(input_type) = vertical_input_type { if let Some(input_type) = vertical_input_type {
BRIDGE.queue_command(UiCommand::Scroll { BRIDGE.queue_command(UiCommand::Scroll {
direction: input_type.to_string(), direction: input_type.to_string(),
grid_id: self.grid_id_under_mouse,
position: (self.mouse_position.width, self.mouse_position.height), position: (self.mouse_position.width, self.mouse_position.height),
}); });
} }
@ -332,6 +355,7 @@ impl WindowWrapper {
if let Some(input_type) = horizontal_input_type { if let Some(input_type) = horizontal_input_type {
BRIDGE.queue_command(UiCommand::Scroll { BRIDGE.queue_command(UiCommand::Scroll {
direction: input_type.to_string(), direction: input_type.to_string(),
grid_id: self.grid_id_under_mouse,
position: (self.mouse_position.width, self.mouse_position.height), position: (self.mouse_position.width, self.mouse_position.height),
}); });
} }

Loading…
Cancel
Save