Working on grid rendering
This commit is contained in:
parent
e14b3db68a
commit
342d38a9fb
5 changed files with 95 additions and 61 deletions
|
@ -15,7 +15,7 @@ pub use clipboard::ClipboardItem;
|
||||||
pub mod fonts;
|
pub mod fonts;
|
||||||
pub mod geometry;
|
pub mod geometry;
|
||||||
mod presenter;
|
mod presenter;
|
||||||
mod scene;
|
pub mod scene;
|
||||||
pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene};
|
pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene};
|
||||||
pub mod text_layout;
|
pub mod text_layout;
|
||||||
pub use text_layout::TextLayoutCache;
|
pub use text_layout::TextLayoutCache;
|
||||||
|
|
|
@ -81,7 +81,7 @@ pub struct Shadow {
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Glyph {
|
pub struct Glyph {
|
||||||
pub font_id: FontId,
|
pub font_id: FontId,
|
||||||
pub font_size: f32,
|
pub font_size: f32,
|
||||||
|
|
10
crates/terminal/src/gpui_func_tools.rs
Normal file
10
crates/terminal/src/gpui_func_tools.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use gpui::geometry::rect::RectF;
|
||||||
|
|
||||||
|
pub fn paint_layer<F>(cx: &mut gpui::PaintContext, clip_bounds: Option<RectF>, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut gpui::PaintContext) -> (),
|
||||||
|
{
|
||||||
|
cx.scene.push_layer(clip_bounds);
|
||||||
|
f(cx);
|
||||||
|
cx.scene.pop_layer()
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ const UP_SEQ: &str = "\x1b[A";
|
||||||
const DOWN_SEQ: &str = "\x1b[B";
|
const DOWN_SEQ: &str = "\x1b[B";
|
||||||
const DEFAULT_TITLE: &str = "Terminal";
|
const DEFAULT_TITLE: &str = "Terminal";
|
||||||
|
|
||||||
|
pub mod gpui_func_tools;
|
||||||
pub mod terminal_element;
|
pub mod terminal_element;
|
||||||
|
|
||||||
///Action for carrying the input to the PTY
|
///Action for carrying the input to the PTY
|
||||||
|
@ -479,8 +480,9 @@ fn to_alac_rgb(color: Color) -> AlacRgb {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::terminal_element::{build_chunks, BuiltChunks};
|
use alacritty_terminal::{grid::GridIterator, term::cell::Cell};
|
||||||
use gpui::TestAppContext;
|
use gpui::TestAppContext;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
///Basic integration test, can we get the terminal to show up, execute a command,
|
///Basic integration test, can we get the terminal to show up, execute a command,
|
||||||
//and produce noticable output?
|
//and produce noticable output?
|
||||||
|
@ -496,14 +498,18 @@ mod tests {
|
||||||
terminal
|
terminal
|
||||||
.condition(cx, |terminal, _cx| {
|
.condition(cx, |terminal, _cx| {
|
||||||
let term = terminal.term.clone();
|
let term = terminal.term.clone();
|
||||||
let BuiltChunks { chunks, .. } = build_chunks(
|
let content = grid_as_str(term.lock().renderable_content().display_iter);
|
||||||
term.lock().renderable_content().display_iter,
|
|
||||||
&Default::default(),
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
let content = chunks.iter().map(|e| e.0.trim()).collect::<String>();
|
|
||||||
content.contains("7")
|
content.contains("7")
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn grid_as_str(grid_iterator: GridIterator<Cell>) -> String {
|
||||||
|
let lines = grid_iterator.group_by(|i| i.point.line.0);
|
||||||
|
lines
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, line)| line.map(|i| i.c).collect::<String>())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use gpui::{
|
||||||
vector::{vec2f, Vector2F},
|
vector::{vec2f, Vector2F},
|
||||||
},
|
},
|
||||||
json::json,
|
json::json,
|
||||||
|
scene::Glyph,
|
||||||
text_layout::{Line, RunStyle},
|
text_layout::{Line, RunStyle},
|
||||||
Event, FontCache, MouseRegion, PaintContext, Quad, SizeConstraint, WeakViewHandle,
|
Event, FontCache, MouseRegion, PaintContext, Quad, SizeConstraint, WeakViewHandle,
|
||||||
};
|
};
|
||||||
|
@ -26,7 +27,7 @@ use settings::Settings;
|
||||||
use std::{iter, rc::Rc};
|
use std::{iter, rc::Rc};
|
||||||
use theme::TerminalStyle;
|
use theme::TerminalStyle;
|
||||||
|
|
||||||
use crate::{Input, ScrollTerminal, Terminal};
|
use crate::{gpui_func_tools::paint_layer, Input, ScrollTerminal, Terminal};
|
||||||
|
|
||||||
///Scrolling is unbearably sluggish by default. Alacritty supports a configurable
|
///Scrolling is unbearably sluggish by default. Alacritty supports a configurable
|
||||||
///Scroll multiplier that is set to 3 by default. This will be removed when I
|
///Scroll multiplier that is set to 3 by default. This will be removed when I
|
||||||
|
@ -82,6 +83,7 @@ pub struct LayoutState {
|
||||||
cur_size: SizeInfo,
|
cur_size: SizeInfo,
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
background_rects: Vec<(RectF, Color)>, //Vec index == Line index for the LineSpan
|
background_rects: Vec<(RectF, Color)>, //Vec index == Line index for the LineSpan
|
||||||
|
ccc: Glyph,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalEl {
|
impl TerminalEl {
|
||||||
|
@ -188,6 +190,14 @@ impl Element for TerminalEl {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let g = Glyph {
|
||||||
|
font_id: text_style.font_id,
|
||||||
|
font_size: text_style.font_size,
|
||||||
|
id: 50,
|
||||||
|
origin: vec2f(0., 0.),
|
||||||
|
color: Color::red(),
|
||||||
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
constraint.max,
|
constraint.max,
|
||||||
LayoutState {
|
LayoutState {
|
||||||
|
@ -198,6 +208,7 @@ impl Element for TerminalEl {
|
||||||
cur_size,
|
cur_size,
|
||||||
background_rects,
|
background_rects,
|
||||||
background_color: terminal_theme.background,
|
background_color: terminal_theme.background,
|
||||||
|
ccc: g,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -210,64 +221,71 @@ impl Element for TerminalEl {
|
||||||
cx: &mut gpui::PaintContext,
|
cx: &mut gpui::PaintContext,
|
||||||
) -> Self::PaintState {
|
) -> Self::PaintState {
|
||||||
//Setup element stuff
|
//Setup element stuff
|
||||||
cx.scene.push_layer(Some(visible_bounds));
|
let clip_bounds = Some(visible_bounds);
|
||||||
|
paint_layer(cx, clip_bounds, |cx| {
|
||||||
|
//Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
|
||||||
|
cx.scene.push_mouse_region(MouseRegion {
|
||||||
|
view_id: self.view.id(),
|
||||||
|
mouse_down: Some(Rc::new(|_, cx| cx.focus_parent_view())),
|
||||||
|
bounds: visible_bounds,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
//Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
|
let origin = bounds.origin() + vec2f(layout.em_width.0, 0.);
|
||||||
cx.scene.push_mouse_region(MouseRegion {
|
|
||||||
view_id: self.view.id(),
|
|
||||||
mouse_down: Some(Rc::new(|_, cx| cx.focus_parent_view())),
|
|
||||||
bounds: visible_bounds,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
let origin = bounds.origin() + vec2f(layout.em_width.0, 0.);
|
paint_layer(cx, clip_bounds, |cx| {
|
||||||
|
layout.ccc.origin.set_x(visible_bounds.origin_x() + 20.);
|
||||||
|
layout.ccc.origin.set_y(visible_bounds.origin_y() + 20.);
|
||||||
|
cx.scene.push_glyph(layout.ccc)
|
||||||
|
});
|
||||||
|
|
||||||
//Start us off with a nice simple background color
|
//Start us off with a nice simple background color
|
||||||
cx.scene.push_layer(Some(visible_bounds));
|
paint_layer(cx, clip_bounds, |cx| {
|
||||||
cx.scene.push_quad(Quad {
|
cx.scene.push_quad(Quad {
|
||||||
bounds: RectF::new(bounds.origin(), bounds.size()),
|
bounds: RectF::new(bounds.origin(), bounds.size()),
|
||||||
background: Some(layout.background_color),
|
background: Some(layout.background_color),
|
||||||
border: Default::default(),
|
border: Default::default(),
|
||||||
corner_radius: 0.,
|
corner_radius: 0.,
|
||||||
});
|
});
|
||||||
|
|
||||||
//Draw cell backgrounds
|
//Draw cell backgrounds
|
||||||
for background_rect in &layout.background_rects {
|
for background_rect in &layout.background_rects {
|
||||||
let new_origin = origin + background_rect.0.origin();
|
let new_origin = origin + background_rect.0.origin();
|
||||||
cx.scene.push_quad(Quad {
|
cx.scene.push_quad(Quad {
|
||||||
bounds: RectF::new(new_origin, background_rect.0.size()),
|
bounds: RectF::new(new_origin, background_rect.0.size()),
|
||||||
background: Some(background_rect.1),
|
background: Some(background_rect.1),
|
||||||
border: Default::default(),
|
border: Default::default(),
|
||||||
corner_radius: 0.,
|
corner_radius: 0.,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
cx.scene.pop_layer();
|
});
|
||||||
|
|
||||||
//Draw text
|
paint_layer(cx, clip_bounds, |cx| {
|
||||||
cx.scene.push_layer(Some(visible_bounds));
|
let mut line_origin = origin.clone();
|
||||||
let mut line_origin = origin.clone();
|
for line in &layout.lines {
|
||||||
for line in &layout.lines {
|
let boundaries =
|
||||||
let boundaries = RectF::new(line_origin, vec2f(bounds.width(), layout.line_height.0));
|
RectF::new(line_origin, vec2f(bounds.width(), layout.line_height.0));
|
||||||
if boundaries.intersects(visible_bounds) {
|
if boundaries.intersects(visible_bounds) {
|
||||||
line.paint(line_origin, visible_bounds, layout.line_height.0, cx);
|
line.paint(line_origin, visible_bounds, layout.line_height.0, cx);
|
||||||
|
}
|
||||||
|
line_origin.set_y(boundaries.max_y());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Draw cursor
|
||||||
|
if let Some(cursor) = &layout.cursor {
|
||||||
|
paint_layer(cx, clip_bounds, |cx| {
|
||||||
|
cursor.paint(origin, cx);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
line_origin.set_y(boundaries.max_y());
|
|
||||||
}
|
|
||||||
cx.scene.pop_layer();
|
|
||||||
|
|
||||||
//Draw cursor
|
#[cfg(debug_assertions)]
|
||||||
if let Some(cursor) = &layout.cursor {
|
if DEBUG_GRID {
|
||||||
cx.scene.push_layer(Some(visible_bounds));
|
paint_layer(cx, clip_bounds, |cx| {
|
||||||
cursor.paint(origin, cx);
|
draw_debug_grid(bounds, layout, cx);
|
||||||
cx.scene.pop_layer();
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if DEBUG_GRID {
|
|
||||||
draw_debug_grid(bounds, layout, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
cx.scene.pop_layer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_event(
|
fn dispatch_event(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue