no longer dropping draw commands. Wonky background, and font changes don't work

macos-click-through
keith 4 years ago
parent 197c68f4b2
commit f198f23551

@ -110,8 +110,4 @@ impl UiCommand {
}
}
}
pub fn is_resize(&self) -> bool {
matches!(self, UiCommand::Resize { .. })
}
}

@ -7,8 +7,9 @@ use std::collections::HashMap;
use std::sync::Arc;
use std::sync::mpsc::{Sender, Receiver};
use std::thread;
use std::fmt;
use log::{error, trace};
use log::{error, warn, trace};
use crate::bridge::{EditorMode, GuiOption, RedrawEvent, WindowAnchor};
use crate::redraw_scheduler::REDRAW_SCHEDULER;
@ -56,10 +57,25 @@ pub enum DrawCommand {
UpdateCursor(Cursor),
FontChanged(String),
DefaultStyleChanged(Style),
}
pub enum WindowCommand {
TitleChanged(String),
SetMouseEnabled(bool),
}
impl fmt::Debug for DrawCommand {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DrawCommand::CloseWindow(_) => write!(formatter, "CloseWindow"),
DrawCommand::Window { grid_id, command } => write!(formatter, "Window {} {:?}", grid_id, command),
DrawCommand::UpdateCursor(_) => write!(formatter, "UpdateCursor"),
DrawCommand::FontChanged(_) => write!(formatter, "FontChanged"),
DrawCommand::DefaultStyleChanged(_) => write!(formatter, "DefaultStyleChanged"),
}
}
}
pub struct Editor {
pub windows: HashMap<u64, Window>,
pub cursor: Cursor,
@ -67,11 +83,12 @@ pub struct Editor {
pub previous_style: Option<Arc<Style>>,
pub mode_list: Vec<CursorMode>,
pub current_mode: EditorMode,
pub draw_command_sender: Sender<DrawCommand>
pub draw_command_sender: Sender<DrawCommand>,
pub window_command_sender: Sender<WindowCommand>,
}
impl Editor {
pub fn new(draw_command_sender: Sender<DrawCommand>) -> Editor {
pub fn new(draw_command_sender: Sender<DrawCommand>, window_command_sender: Sender<WindowCommand>) -> Editor {
Editor {
windows: HashMap::new(),
cursor: Cursor::new(),
@ -79,14 +96,15 @@ impl Editor {
previous_style: None,
mode_list: Vec::new(),
current_mode: EditorMode::Unknown(String::from("")),
draw_command_sender
draw_command_sender,
window_command_sender
}
}
pub fn handle_redraw_event(&mut self, event: RedrawEvent) {
match event {
RedrawEvent::SetTitle { title } => {
self.draw_command_sender.send(DrawCommand::TitleChanged(title)).ok();
self.window_command_sender.send(WindowCommand::TitleChanged(title)).ok();
},
RedrawEvent::ModeInfoSet { cursor_modes } => self.mode_list = cursor_modes,
RedrawEvent::OptionSet { gui_option } => self.set_option(gui_option),
@ -98,10 +116,10 @@ impl Editor {
}
}
RedrawEvent::MouseOn => {
self.draw_command_sender.send(DrawCommand::SetMouseEnabled(true)).ok();
self.window_command_sender.send(WindowCommand::SetMouseEnabled(true)).ok();
}
RedrawEvent::MouseOff => {
self.draw_command_sender.send(DrawCommand::SetMouseEnabled(false)).ok();
self.window_command_sender.send(WindowCommand::SetMouseEnabled(false)).ok();
}
RedrawEvent::BusyStart => {
trace!("Cursor off");
@ -209,7 +227,7 @@ impl Editor {
}
fn resize_window(&mut self, grid: u64, width: u64, height: u64) {
println!("editor resize {}", grid);
warn!("editor resize {}", grid);
if let Some(window) = self.windows.get_mut(&grid) {
window.resize(width, height);
} else {
@ -233,7 +251,7 @@ impl Editor {
width: u64,
height: u64,
) {
println!("position {}", grid);
warn!("position {}", grid);
if let Some(window) = self.windows.get_mut(&grid) {
window.position(
width,
@ -264,7 +282,7 @@ impl Editor {
anchor_left: f64,
anchor_top: f64,
) {
println!("floating position {}", grid);
warn!("floating position {}", grid);
let parent_position = self.get_window_top_left(anchor_grid);
if let Some(window) = self.windows.get_mut(&grid) {
let width = window.get_width();
@ -292,7 +310,7 @@ impl Editor {
}
fn set_message_position(&mut self, grid: u64, grid_top: u64) {
println!("message position {}", grid);
warn!("message position {}", grid);
let parent_width = self.windows.get(&1).map(|parent| parent.get_width()).unwrap_or(1);
if let Some(window) = self.windows.get_mut(&grid) {
@ -363,9 +381,9 @@ impl Editor {
}
}
pub fn start_editor(redraw_event_receiver: Receiver<RedrawEvent>, draw_command_sender: Sender<DrawCommand>) {
pub fn start_editor(redraw_event_receiver: Receiver<RedrawEvent>, draw_command_sender: Sender<DrawCommand>, window_command_sender: Sender<WindowCommand>) {
thread::spawn(move || {
let mut editor = Editor::new(draw_command_sender);
let mut editor = Editor::new(draw_command_sender, window_command_sender);
loop {
if let Ok(redraw_event) = redraw_event_receiver.recv() {

@ -1,6 +1,7 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::mpsc::Sender;
use std::fmt;
use log::warn;
use unicode_segmentation::UnicodeSegmentation;
@ -10,7 +11,7 @@ use super::grid::CharacterGrid;
use super::style::Style;
use crate::bridge::GridLineCell;
#[derive(new, Debug, Clone)]
#[derive(new, Clone)]
pub enum WindowDrawCommand {
Position {
grid_left: f64,
@ -40,6 +41,20 @@ pub enum WindowDrawCommand {
Close
}
impl fmt::Debug for WindowDrawCommand {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
WindowDrawCommand::Position { .. } => write!(formatter, "Position"),
WindowDrawCommand::Cell { .. } => write!(formatter, "Cell"),
WindowDrawCommand::Scroll { .. } => write!(formatter, "Scroll"),
WindowDrawCommand::Clear => write!(formatter, "Clear"),
WindowDrawCommand::Show => write!(formatter, "Show"),
WindowDrawCommand::Hide => write!(formatter, "Hide"),
WindowDrawCommand::Close => write!(formatter, "Close"),
}
}
}
pub struct Window {
grid_id: u64,
grid: CharacterGrid,

@ -134,8 +134,9 @@ fn main() {
let (redraw_event_sender, redraw_event_receiver) = channel();
let (draw_command_sender, draw_command_receiver) = channel();
let (ui_command_sender, ui_command_receiver) = channel();
let (window_command_sender, window_command_receiver) = channel();
start_bridge(ui_command_sender.clone(), ui_command_receiver, redraw_event_sender, running.clone());
start_editor(redraw_event_receiver, draw_command_sender);
start_window(draw_command_receiver, ui_command_sender, running.clone());
start_editor(redraw_event_receiver, draw_command_sender, window_command_sender);
start_window(draw_command_receiver, window_command_receiver, ui_command_sender, running.clone());
}

@ -1,9 +1,10 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use log::{trace, error};
use log::{trace, warn, error};
use skulpin::skia_safe::{
colors, dash_path_effect, Canvas, Paint, Rect, BlendMode
colors, dash_path_effect, Canvas, Paint, Rect, BlendMode, Color
};
use skulpin::CoordinateSystemHelper;
@ -57,10 +58,11 @@ pub struct Renderer {
pub font_width: f32,
pub font_height: f32,
pub window_regions: Vec<(u64, Rect)>,
pub draw_command_receiver: Receiver<DrawCommand>,
}
impl Renderer {
pub fn new() -> Renderer {
pub fn new(draw_command_receiver: Receiver<DrawCommand>) -> Renderer {
let rendered_windows = HashMap::new();
let cursor_renderer = CursorRenderer::new();
let settings = SETTINGS.get::<RendererSettings>();
@ -87,6 +89,7 @@ impl Renderer {
font_width,
font_height,
window_regions,
draw_command_receiver,
}
}
@ -115,20 +118,13 @@ impl Renderer {
grid_pos: (u64, u64),
cell_width: u64,
style: &Option<Arc<Style>>,
floating: bool,
) {
self.paint.set_blend_mode(BlendMode::Src);
let region = self.compute_text_region(grid_pos, cell_width);
let style = style.as_ref().unwrap_or(&self.default_style);
let mut color = style.background(&self.default_style.colors);
if floating {
color.a = color.a * self.settings.floating_opacity.min(1.0).max(0.0);
}
self.paint.set_color(color.to_color());
self.paint.set_color(style.background(&self.default_style.colors).to_color());
canvas.draw_rect(region, &self.paint);
}
@ -152,6 +148,10 @@ impl Renderer {
let region = self.compute_text_region(grid_pos, cell_width);
canvas.clip_rect(region, None, Some(false));
self.paint.set_blend_mode(BlendMode::Src);
let transparent = Color::from_argb(0, 255, 255, 255);
self.paint.set_color(transparent);
canvas.draw_rect(region, &self.paint);
if style.underline || style.undercurl {
let line_position = self.shaper.underline_position();
@ -200,6 +200,7 @@ impl Renderer {
}
pub fn handle_draw_command(&mut self, root_canvas: &mut Canvas, draw_command: DrawCommand) {
warn!("{:?}", &draw_command);
match draw_command {
DrawCommand::Window {
grid_id,
@ -212,13 +213,14 @@ impl Renderer {
command
} => {
if let Some(rendered_window) = self.rendered_windows.remove(&grid_id) {
warn!("Window positioned {}", grid_id);
let rendered_window = rendered_window.handle_window_draw_command(self, command);
self.rendered_windows.insert(grid_id, rendered_window);
} else if let WindowDrawCommand::Position {
grid_left, grid_top,
width, height, ..
} = command {
println!("Created window {}", grid_id);
warn!("Created window {}", grid_id);
let new_window = RenderedWindow::new(
root_canvas, &self, grid_id,
(grid_left as f32, grid_top as f32).into(),
@ -251,6 +253,11 @@ impl Renderer {
) {
trace!("Rendering");
let draw_commands: Vec<DrawCommand> = self.draw_command_receiver.try_iter().collect();
for draw_command in draw_commands.into_iter() {
self.handle_draw_command(root_canvas, draw_command);
}
root_canvas.clear(self.default_style.colors.background.clone().unwrap().to_color());
coordinate_system_helper.use_logical_coordinates(root_canvas);

@ -1,6 +1,6 @@
use skulpin::skia_safe::gpu::SurfaceOrigin;
use skulpin::skia_safe::{
Budgeted, Canvas, ImageInfo, Rect, Surface, Point, image_filters::blur
Budgeted, Canvas, ImageInfo, Rect, Surface, Point, Paint, Color, image_filters::blur
};
use skulpin::skia_safe::canvas::{
SaveLayerRec,
@ -40,12 +40,14 @@ fn build_window_surface(
)
.expect("Could not create surface");
let canvas = surface.canvas();
canvas.clear(renderer.default_style.colors.background.clone().unwrap().to_color());
surface
}
pub struct RenderedWindow {
surface: Surface,
background_surface: Surface,
foreground_surface: Surface,
pub id: u64,
pub hidden: bool,
pub floating: bool,
@ -60,10 +62,12 @@ pub struct RenderedWindow {
impl RenderedWindow {
pub fn new(parent_canvas: &mut Canvas, renderer: &Renderer, id: u64, grid_position: Point, grid_width: u64, grid_height: u64) -> RenderedWindow {
let surface = build_window_surface(parent_canvas, renderer, grid_width, grid_height);
let background_surface = build_window_surface(parent_canvas, renderer, grid_width, grid_height);
let foreground_surface = build_window_surface(parent_canvas, renderer, grid_width, grid_height);
RenderedWindow {
surface,
background_surface,
foreground_surface,
id,
hidden: false,
floating: false,
@ -135,10 +139,18 @@ impl RenderedWindow {
root_canvas.save_layer(&save_layer_rec);
}
self.surface.draw(
root_canvas.as_mut(),
(current_pixel_position.x, current_pixel_position.y),
None);
let mut paint = Paint::default();
if self.floating {
let a = (settings.floating_opacity.min(1.0).max(0.0) * 255.0) as u8;
paint.set_color(Color::from_argb(a, 255, 255, 255));
}
let background_snapshot = self.background_surface.image_snapshot();
root_canvas.draw_image(background_snapshot, (current_pixel_position.x, current_pixel_position.y), Some(&paint));
let foreground_snapshot = self.foreground_surface.image_snapshot();
root_canvas.draw_image(foreground_snapshot, (current_pixel_position.x, current_pixel_position.y), None);
if self.floating {
root_canvas.restore();
@ -168,9 +180,14 @@ impl RenderedWindow {
}
if grid_width != self.grid_width || grid_height != self.grid_height {
let mut old_surface = self.surface;
self.surface = build_window_surface(old_surface.canvas(), &renderer, grid_width, grid_height);
old_surface.draw(self.surface.canvas(), (0.0, 0.0), None);
let mut old_background = self.background_surface;
self.background_surface = build_window_surface(old_background.canvas(), &renderer, grid_width, grid_height);
old_background.draw(self.background_surface.canvas(), (0.0, 0.0), None);
let mut old_foreground = self.foreground_surface;
self.foreground_surface = build_window_surface(old_foreground.canvas(), &renderer, grid_width, grid_height);
old_foreground.draw(self.foreground_surface.canvas(), (0.0, 0.0), None);
self.grid_width = grid_width;
self.grid_height = grid_height;
}
@ -180,23 +197,28 @@ impl RenderedWindow {
WindowDrawCommand::Cell {
text, cell_width, window_left, window_top, style
} => {
let mut canvas = self.surface.canvas();
let grid_position = (window_left, window_top);
{
let mut background_canvas = self.background_surface.canvas();
renderer.draw_background(
&mut canvas,
&mut background_canvas,
grid_position,
cell_width,
&style,
self.floating,
&style
);
}
{
let mut foreground_canvas = self.foreground_surface.canvas();
renderer.draw_foreground(
&mut canvas,
&mut foreground_canvas,
&text,
grid_position,
cell_width,
&style,
);
}
},
WindowDrawCommand::Scroll {
top, bot, left, right, rows, cols
@ -207,22 +229,42 @@ impl RenderedWindow {
right as f32 * renderer.font_width,
bot as f32 * renderer.font_height);
let snapshot = self.surface.image_snapshot();
let canvas = self.surface.canvas();
{
let background_snapshot = self.background_surface.image_snapshot();
let background_canvas = self.background_surface.canvas();
canvas.save();
canvas.clip_rect(scrolled_region, None, Some(false));
background_canvas.save();
background_canvas.clip_rect(scrolled_region, None, Some(false));
let mut translated_region = scrolled_region.clone();
translated_region.offset((-cols as f32 * renderer.font_width, -rows as f32 * renderer.font_height));
canvas.draw_image_rect(snapshot, Some((&scrolled_region, SrcRectConstraint::Fast)), translated_region, &renderer.paint);
background_canvas.draw_image_rect(background_snapshot, Some((&scrolled_region, SrcRectConstraint::Fast)), translated_region, &renderer.paint);
background_canvas.restore();
}
{
let foreground_snapshot = self.foreground_surface.image_snapshot();
let foreground_canvas = self.foreground_surface.canvas();
foreground_canvas.save();
foreground_canvas.clip_rect(scrolled_region, None, Some(false));
canvas.restore();
let mut translated_region = scrolled_region.clone();
translated_region.offset((-cols as f32 * renderer.font_width, -rows as f32 * renderer.font_height));
foreground_canvas.draw_image_rect(foreground_snapshot, Some((&scrolled_region, SrcRectConstraint::Fast)), translated_region, &renderer.paint);
foreground_canvas.restore();
}
},
WindowDrawCommand::Clear => {
let canvas = self.surface.canvas();
self.surface = build_window_surface(canvas, &renderer, self.grid_width, self.grid_height);
let background_canvas = self.background_surface.canvas();
self.background_surface = build_window_surface(background_canvas, &renderer, self.grid_width, self.grid_height);
let foreground_canvas = self.foreground_surface.canvas();
self.foreground_surface = build_window_surface(foreground_canvas, &renderer, self.grid_width, self.grid_height);
},
WindowDrawCommand::Show => self.hidden = false,
WindowDrawCommand::Hide => self.hidden = true,

@ -4,7 +4,7 @@ use std::sync::Arc;
use std::sync::atomic::{Ordering, AtomicBool};
use std::sync::mpsc::{Sender, Receiver};
use log::{debug, error, info, trace};
use log::{debug, error, warn, info, trace};
use skulpin::sdl2;
use skulpin::sdl2::event::{Event, WindowEvent};
use skulpin::sdl2::keyboard::Keycode;
@ -16,7 +16,7 @@ use skulpin::{
RendererBuilder, Sdl2Window, Window,
};
use crate::editor::DrawCommand;
use crate::editor::{DrawCommand, WindowCommand};
use crate::bridge::{produce_neovim_keybinding_string, UiCommand};
use crate::redraw_scheduler::REDRAW_SCHEDULER;
use crate::renderer::Renderer;
@ -111,7 +111,7 @@ pub fn window_geometry_or_default() -> (u64, u64) {
}
impl WindowWrapper {
pub fn new(ui_command_sender: Sender<UiCommand>, running: Arc<AtomicBool>) -> WindowWrapper {
pub fn new(ui_command_sender: Sender<UiCommand>, draw_command_receiver: Receiver<DrawCommand>, running: Arc<AtomicBool>) -> WindowWrapper {
let context = sdl2::init().expect("Failed to initialize sdl2");
let video_subsystem = context
.video()
@ -120,7 +120,7 @@ impl WindowWrapper {
let (width, height) = window_geometry_or_default();
let renderer = Renderer::new();
let renderer = Renderer::new(draw_command_receiver);
let logical_size = LogicalSize {
width: (width as f32 * renderer.font_width) as u32,
height: (height as f32 * renderer.font_height + 1.0) as u32,
@ -381,7 +381,7 @@ impl WindowWrapper {
REDRAW_SCHEDULER.queue_next_frame();
}
pub fn draw_frame(&mut self, draw_commands: Vec<DrawCommand>, dt: f32) -> VkResult<bool> {
pub fn draw_frame(&mut self, dt: f32) -> VkResult<bool> {
let sdl_window_wrapper = Sdl2Window::new(&self.window);
let new_size = sdl_window_wrapper.logical_size();
if self.previous_size != new_size {
@ -395,10 +395,6 @@ impl WindowWrapper {
let renderer = &mut self.renderer;
self.skulpin_renderer
.draw(&sdl_window_wrapper, |canvas, coordinate_system_helper| {
for draw_command in draw_commands.into_iter() {
renderer.handle_draw_command(canvas, draw_command);
}
renderer.draw_frame(canvas, &coordinate_system_helper, dt)
})?;
@ -435,8 +431,8 @@ pub fn initialize_settings() {
register_nvim_setting!("fullscreen", WindowSettings::fullscreen);
}
pub fn start_window(draw_command_receiver: Receiver<DrawCommand>, ui_command_sender: Sender<UiCommand>, running: Arc<AtomicBool>) {
let mut window = WindowWrapper::new(ui_command_sender.clone(), running.clone());
pub fn start_window(draw_command_receiver: Receiver<DrawCommand>, window_command_receiver: Receiver<WindowCommand>, ui_command_sender: Sender<UiCommand>, running: Arc<AtomicBool>) {
let mut window = WindowWrapper::new(ui_command_sender.clone(), draw_command_receiver, running.clone());
info!("Starting window event loop");
let mut event_pump = window
@ -503,17 +499,14 @@ pub fn start_window(draw_command_receiver: Receiver<DrawCommand>, ui_command_sen
1.0 / refresh_rate
};
let mut unhandled_draw_commands = Vec::new();
for draw_command in draw_command_receiver.try_iter() {
match draw_command {
DrawCommand::TitleChanged(new_title) => window.handle_title_changed(new_title),
DrawCommand::SetMouseEnabled(mouse_enabled) => window.mouse_enabled = mouse_enabled,
unhandled_command => unhandled_draw_commands.push(unhandled_command)
for window_command in window_command_receiver.try_iter() {
match window_command {
WindowCommand::TitleChanged(new_title) => window.handle_title_changed(new_title),
WindowCommand::SetMouseEnabled(mouse_enabled) => window.mouse_enabled = mouse_enabled,
}
}
match window.draw_frame(unhandled_draw_commands, dt) {
match window.draw_frame(dt) {
Ok(animating) => {
was_animating = animating;
},

Loading…
Cancel
Save