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),
MouseButton {
action: String,
grid_id: u64,
position: (u32, u32),
},
Scroll {
direction: String,
grid_id: u64,
position: (u32, u32),
},
Drag {
grid_id: u64,
position: (u32, u32),
},
Drag(u32, u32),
FileDrop(String),
FocusLost,
FocusGained,
@ -48,27 +53,32 @@ impl UiCommand {
}
UiCommand::MouseButton {
action,
grid_id,
position: (grid_x, grid_y),
} => {
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
.expect("Mouse Input Failed");
}
}
UiCommand::Scroll {
direction,
grid_id,
position: (grid_x, grid_y),
} => {
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
.expect("Mouse Scroll Failed");
}
}
UiCommand::Drag(grid_x, grid_y) => {
UiCommand::Drag {
grid_id,
position: (grid_x, grid_y)
} => {
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
.expect("Mouse Drag Failed");
}

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

@ -4,9 +4,8 @@ use std::sync::Arc;
use log::trace;
use skulpin::skia_safe::gpu::SurfaceOrigin;
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;
mod caching_shaper;
@ -17,34 +16,45 @@ pub use caching_shaper::CachingShaper;
pub use font_options::*;
use crate::editor::{Style, WindowRenderInfo, EDITOR};
use crate::redraw_scheduler::REDRAW_SCHEDULER;
use cursor_renderer::CursorRenderer;
pub struct RenderedWindow {
surface: Surface,
current_position: (f32, f32)
}
pub struct Renderer {
window_surfaces: HashMap<u64, Surface>,
rendered_windows: HashMap<u64, RenderedWindow>,
paint: Paint,
shaper: CachingShaper,
pub font_width: f32,
pub font_height: f32,
pub window_regions: Vec<(u64, Rect)>,
cursor_renderer: CursorRenderer,
}
impl Renderer {
pub fn new() -> Renderer {
let rendered_windows = HashMap::new();
let mut paint = Paint::new(colors::WHITE, None);
paint.set_anti_alias(false);
let mut shaper = CachingShaper::new();
let (font_width, font_height) = shaper.font_base_dimensions();
let window_regions = Vec::new();
let cursor_renderer = CursorRenderer::new();
Renderer {
window_surfaces: HashMap::new(),
rendered_windows,
paint,
shaper,
font_width,
font_height,
window_regions,
cursor_renderer,
}
}
@ -188,26 +198,39 @@ impl Renderer {
root_canvas: &mut Canvas,
window_render_info: &WindowRenderInfo,
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_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
} else {
self.window_surfaces.remove(&window_render_info.grid_id)
self.rendered_windows.remove(&window_render_info.grid_id)
}
.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 {
let mut old_surface = surface;
surface = self.build_window_surface(root_canvas, &default_style, (image_width, image_height));
old_surface.draw(surface.canvas(), (0.0, 0.0), None);
if rendered_window.surface.width() != image_width || rendered_window.surface.height() != image_height {
let mut old_surface = rendered_window.surface;
rendered_window.surface = self.build_window_surface(root_canvas, &default_style, (image_width, image_height));
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() {
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());
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();
self.window_surfaces
.insert(window_render_info.grid_id, surface);
self.rendered_windows.insert(window_render_info.grid_id, rendered_window);
(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(
@ -254,6 +274,8 @@ impl Renderer {
) -> bool {
trace!("Rendering");
REDRAW_SCHEDULER.queue_next_frame();
let (render_info, default_style, cursor, guifont_setting) = {
let mut editor = EDITOR.lock();
(
@ -271,14 +293,15 @@ impl Renderer {
.unwrap_or(false);
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);
for window_render_info in render_info.windows.iter() {
self.draw_window(gpu_canvas, window_render_info, &default_style);
}
self.window_regions = render_info.windows
.iter()
.map(|window_render_info| self.draw_window(gpu_canvas, window_render_info, &default_style))
.collect();
self.cursor_renderer.draw(
cursor,

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

Loading…
Cancel
Save