Move draw-related functionality into Graphics struct

This commit is contained in:
mars 2022-10-05 17:29:26 -06:00
parent 71202752f8
commit 4d448585ec
1 changed files with 121 additions and 89 deletions

View File

@ -19,7 +19,7 @@ use std::sync::Arc;
use std::thread::JoinHandle;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use winit::window::{Window, WindowBuilder, WindowId};
static NORMAL_FONT_DATA: &[u8] = include_bytes!("ter-u16n.bdf");
static BOLD_FONT_DATA: &[u8] = include_bytes!("ter-u16b.bdf");
@ -40,24 +40,19 @@ impl EventListener for TermListener {
}
}
pub struct App {
pub struct Graphics {
normal_font: bdf::Font,
bold_font: bdf::Font,
graphics: GraphicsContext<Window>,
should_quit: bool,
width: usize,
height: usize,
cell_width: usize,
cell_height: usize,
current_width: usize,
current_height: usize,
colors: Colors,
term_loop: JoinHandle<(TermEventLoop<Pty, TermListener>, TermState)>,
term_channel: MioSender<TermMsg>,
term_events: Receiver<TermEvent>,
term: Arc<FairMutex<Term<TermListener>>>,
buffer: Vec<u32>,
}
impl App {
pub fn new(window: Window) -> Self {
impl Graphics {
pub fn new() -> Self {
let normal_font = bdf::read(NORMAL_FONT_DATA).unwrap();
let bold_font = bdf::read(BOLD_FONT_DATA).unwrap();
@ -68,70 +63,25 @@ impl App {
let cell_width = normal_font.bounds().width as usize;
let cell_height = normal_font.bounds().height as usize;
let current_width = 2000;
let current_height = 2000;
let term_size = alacritty_terminal::term::SizeInfo::new(
current_width as f32,
current_height as f32,
cell_width as f32,
cell_height as f32,
0.0,
0.0,
false,
);
let (sender, term_events) = channel();
let term_config = alacritty_terminal::config::Config {
pty_config: PtyConfig {
shell: Some(alacritty_terminal::config::Program::Just(
"/usr/bin/fish".to_string(),
)),
working_directory: None,
hold: false,
},
..Default::default()
};
alacritty_terminal::tty::setup_env(&term_config);
let term_listener = TermListener::new(sender.clone());
let term = Term::new(&term_config, term_size, term_listener);
let mut colors = term.colors().to_owned();
let term = FairMutex::new(term);
let term = Arc::new(term);
let pty = alacritty_terminal::tty::new(&term_config.pty_config, &term_size, None).unwrap();
let term_listener = TermListener::new(sender);
let term_loop = TermEventLoop::new(term.clone(), term_listener, pty, false, false);
let term_channel = term_loop.channel();
let width = 2000;
let height = 2000;
let buffer = vec![0u32; width * height];
let mut colors = Colors::default();
Self::load_colors(&mut colors);
Self {
normal_font,
bold_font,
graphics: unsafe { GraphicsContext::new(window).unwrap() },
should_quit: false,
width,
height,
cell_width,
cell_height,
current_width,
current_height,
term,
term_channel,
term_events,
colors,
term_loop: term_loop.spawn(),
buffer,
}
}
pub fn should_quit(&self) -> bool {
self.should_quit
}
pub fn load_colors(color: &mut Colors) {
use NamedColor::*;
@ -177,18 +127,39 @@ impl App {
}
}
pub fn redraw(&mut self) {
pub fn color_to_u32(&self, color: &Color) -> u32 {
let rgb = match color {
Color::Named(name) => self.colors[*name].unwrap(),
Color::Spec(rgb) => *rgb,
Color::Indexed(index) => self.colors[*index as usize].unwrap_or(Rgb {
r: 255,
g: 0,
b: 255,
}),
};
((rgb.r as u32) << 16) | ((rgb.g as u32) << 8) | (rgb.b as u32)
}
pub fn resize(&mut self, width: usize, height: usize) {
self.width = width;
self.height = height;
self.buffer.clear();
self.buffer.resize(width * height, 0);
}
pub fn redraw(&mut self, term: &Term<TermListener>, context: &mut GraphicsContext<Window>) {
let (width, height) = {
let size = self.graphics.window().inner_size();
let size = context.window().inner_size();
(size.width as usize, size.height as usize)
};
if width != self.current_width || height != self.current_height {
self.on_resize(width as u32, height as u32);
if width != self.width || height != self.height {
self.resize(width, height);
}
let mut buffer = vec![0u32; (width * height) as usize];
let term = self.term.lock();
let content = term.renderable_content();
let mut missing_chars = std::collections::HashSet::new();
@ -316,22 +287,74 @@ impl App {
}
}
self.graphics
.set_buffer(&buffer, width as u16, height as u16);
context.set_buffer(&buffer, width as u16, height as u16);
}
}
pub fn color_to_u32(&self, color: &Color) -> u32 {
let rgb = match color {
Color::Named(name) => self.colors[*name].unwrap(),
Color::Spec(rgb) => *rgb,
Color::Indexed(index) => self.colors[*index as usize].unwrap_or(Rgb {
r: 255,
g: 0,
b: 255,
}),
pub struct App {
graphics: Graphics,
graphics_context: GraphicsContext<Window>,
should_quit: bool,
term_loop: JoinHandle<(TermEventLoop<Pty, TermListener>, TermState)>,
term_channel: MioSender<TermMsg>,
term_events: Receiver<TermEvent>,
term: Arc<FairMutex<Term<TermListener>>>,
}
impl App {
pub fn new(window: Window) -> Self {
let graphics = Graphics::new();
let term_size = alacritty_terminal::term::SizeInfo::new(
graphics.width as f32,
graphics.height as f32,
graphics.cell_width as f32,
graphics.cell_height as f32,
0.0,
0.0,
false,
);
let (sender, term_events) = channel();
let term_config = alacritty_terminal::config::Config {
pty_config: PtyConfig {
shell: Some(alacritty_terminal::config::Program::Just(
"/usr/bin/fish".to_string(),
)),
working_directory: None,
hold: false,
},
..Default::default()
};
((rgb.r as u32) << 16) | ((rgb.g as u32) << 8) | (rgb.b as u32)
alacritty_terminal::tty::setup_env(&term_config);
let term_listener = TermListener::new(sender.clone());
let term = Term::new(&term_config, term_size, term_listener);
let term = FairMutex::new(term);
let term = Arc::new(term);
let pty = alacritty_terminal::tty::new(&term_config.pty_config, &term_size, None).unwrap();
let term_listener = TermListener::new(sender);
let term_loop = TermEventLoop::new(term.clone(), term_listener, pty, false, false);
let term_channel = term_loop.channel();
Self {
graphics,
graphics_context: unsafe { GraphicsContext::new(window).unwrap() },
should_quit: false,
term,
term_channel,
term_events,
term_loop: term_loop.spawn(),
}
}
pub fn should_quit(&self) -> bool {
self.should_quit
}
pub fn update(&mut self) {
@ -343,6 +366,11 @@ impl App {
}
}
pub fn redraw(&mut self) {
let term = self.term.lock();
self.graphics.redraw(&term, &mut self.graphics_context);
}
pub fn virtual_keycode_to_string(
keycode: winit::event::VirtualKeyCode,
) -> Option<&'static str> {
@ -377,6 +405,7 @@ impl App {
match c {
'\u{7f}' => {
// We use a special escape code for the delete key.
log::debug!("Ignoring.");
return;
}
@ -397,8 +426,8 @@ impl App {
let term_size = alacritty_terminal::term::SizeInfo::new(
width as f32,
height as f32,
self.cell_width as f32,
self.cell_height as f32,
self.graphics.cell_width as f32,
self.graphics.cell_height as f32,
0.0,
0.0,
false,
@ -406,8 +435,11 @@ impl App {
self.term_channel.send(TermMsg::Resize(term_size)).unwrap();
self.current_width = width as usize;
self.current_height = height as usize;
self.graphics.resize(width as usize, height as usize);
}
pub fn window_id(&self) -> WindowId {
self.graphics_context.window().id()
}
}
@ -423,7 +455,7 @@ fn main() {
*control_flow = ControlFlow::Wait;
match event {
Event::RedrawRequested(window_id) if window_id == app.graphics.window().id() => {
Event::RedrawRequested(window_id) if window_id == app.window_id() => {
counter += 1;
if counter > 30 {
@ -432,10 +464,10 @@ fn main() {
}
}
Event::MainEventsCleared => {
app.graphics.window().request_redraw();
app.graphics_context.window().request_redraw();
app.update();
}
Event::WindowEvent { event, window_id } if window_id == app.graphics.window().id() => {
Event::WindowEvent { event, window_id } if window_id == app.window_id() => {
match event {
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;