Start porting terminal_element to gpui2

Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
Kirill Bulatov 2023-11-14 11:15:57 +02:00
parent d89c51135a
commit 61d6cb880c
2 changed files with 63 additions and 61 deletions

View file

@ -335,6 +335,10 @@ where
}; };
Bounds { origin, size } Bounds { origin, size }
} }
pub fn new(origin: Point<T>, size: Size<T>) -> Self {
Bounds { origin, size }
}
} }
impl<T> Bounds<T> impl<T> Bounds<T>

View file

@ -1,17 +1,7 @@
use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
use gpui::{ use gpui::{
color::Color, serde_json::json, AnyElement, Bounds, HighlightStyle, Hsla, Line, ModelContext, MouseButton,
elements::{Empty, Overlay}, Pixels, Point, TextStyle, ViewContext, WeakModel, WindowContext,
fonts::{HighlightStyle, Properties, Style::Italic, TextStyle, Underline, Weight},
geometry::{
rect::RectF,
vector::{vec2f, Vector2F},
},
platform::{CursorStyle, MouseButton},
serde_json::json,
text_layout::{Line, RunStyle},
AnyElement, Element, EventContext, FontCache, ModelContext, MouseRegion, Quad, SizeConstraint,
TextLayoutCache, ViewContext, WeakModelHandle, WindowContext,
}; };
use itertools::Itertools; use itertools::Itertools;
use language::CursorShape; use language::CursorShape;
@ -20,14 +10,17 @@ use terminal::{
alacritty_terminal::{ alacritty_terminal::{
ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor}, ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
grid::Dimensions, grid::Dimensions,
index::Point, index::Point as AlacPoint,
term::{cell::Flags, TermMode}, term::{cell::Flags, TermMode},
}, },
mappings::colors::convert_color, // mappings::colors::convert_color,
terminal_settings::TerminalSettings, terminal_settings::TerminalSettings,
IndexedCell, Terminal, TerminalContent, TerminalSize, IndexedCell,
Terminal,
TerminalContent,
TerminalSize,
}; };
use theme::{TerminalStyle, ThemeSettings}; use theme::ThemeSettings;
use util::ResultExt; use util::ResultExt;
use std::{fmt::Debug, ops::RangeInclusive}; use std::{fmt::Debug, ops::RangeInclusive};
@ -39,9 +32,9 @@ use crate::TerminalView;
pub struct LayoutState { pub struct LayoutState {
cells: Vec<LayoutCell>, cells: Vec<LayoutCell>,
rects: Vec<LayoutRect>, rects: Vec<LayoutRect>,
relative_highlighted_ranges: Vec<(RangeInclusive<Point>, Color)>, relative_highlighted_ranges: Vec<(RangeInclusive<AlacPoint>, Hsla)>,
cursor: Option<Cursor>, cursor: Option<Cursor>,
background_color: Color, background_color: Hsla,
size: TerminalSize, size: TerminalSize,
mode: TermMode, mode: TermMode,
display_offset: usize, display_offset: usize,
@ -56,7 +49,7 @@ struct DisplayCursor {
} }
impl DisplayCursor { impl DisplayCursor {
fn from(cursor_point: Point, display_offset: usize) -> Self { fn from(cursor_point: AlacPoint, display_offset: usize) -> Self {
Self { Self {
line: cursor_point.line.0 + display_offset as i32, line: cursor_point.line.0 + display_offset as i32,
col: cursor_point.column.0, col: cursor_point.column.0,
@ -74,45 +67,45 @@ impl DisplayCursor {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
struct LayoutCell { struct LayoutCell {
point: Point<i32, i32>, point: AlacPoint<i32, i32>,
text: Line, text: Line,
} }
impl LayoutCell { impl LayoutCell {
fn new(point: Point<i32, i32>, text: Line) -> LayoutCell { fn new(point: AlacPoint<i32, i32>, text: Line) -> LayoutCell {
LayoutCell { point, text } LayoutCell { point, text }
} }
fn paint( fn paint(
&self, &self,
origin: Vector2F, origin: Point<Pixels>,
layout: &LayoutState, layout: &LayoutState,
visible_bounds: RectF, _visible_bounds: Bounds<Pixels>,
_view: &mut TerminalView, _view: &mut TerminalView,
cx: &mut WindowContext, cx: &mut WindowContext,
) { ) {
let pos = { let pos = {
let point = self.point; let point = self.point;
vec2f(
(origin.x() + point.column as f32 * layout.size.cell_width).floor(), Point::new(
origin.y() + point.line as f32 * layout.size.line_height, (origin.x + point.column as f32 * layout.size.cell_width).floor(),
origin.y + point.line as f32 * layout.size.line_height,
) )
}; };
self.text self.text.paint(pos, layout.size.line_height, cx);
.paint(pos, visible_bounds, layout.size.line_height, cx);
} }
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
struct LayoutRect { struct LayoutRect {
point: Point<i32, i32>, point: AlacPoint<i32, i32>,
num_of_cells: usize, num_of_cells: usize,
color: Color, color: Hsla,
} }
impl LayoutRect { impl LayoutRect {
fn new(point: Point<i32, i32>, num_of_cells: usize, color: Color) -> LayoutRect { fn new(point: AlacPoint<i32, i32>, num_of_cells: usize, color: Hsla) -> LayoutRect {
LayoutRect { LayoutRect {
point, point,
num_of_cells, num_of_cells,
@ -130,7 +123,7 @@ impl LayoutRect {
fn paint( fn paint(
&self, &self,
origin: Vector2F, origin: Point<Pixels>,
layout: &LayoutState, layout: &LayoutState,
_view: &mut TerminalView, _view: &mut TerminalView,
cx: &mut ViewContext<TerminalView>, cx: &mut ViewContext<TerminalView>,
@ -147,19 +140,20 @@ impl LayoutRect {
layout.size.line_height, layout.size.line_height,
); );
cx.scene().push_quad(Quad { cx.paint_quad(
bounds: RectF::new(position, size), Bounds::new(position, size),
background: Some(self.color), Default::default(),
border: Default::default(), Some(self.color),
corner_radii: Default::default(), Default::default(),
}) Default::default(),
);
} }
} }
///The GPUI element that paints the terminal. ///The GPUI element that paints the terminal.
///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection? ///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection?
pub struct TerminalElement { pub struct TerminalElement {
terminal: WeakModelHandle<Terminal>, terminal: WeakModel<Terminal>,
focused: bool, focused: bool,
cursor_visible: bool, cursor_visible: bool,
can_navigate_to_selected_word: bool, can_navigate_to_selected_word: bool,
@ -167,7 +161,7 @@ pub struct TerminalElement {
impl TerminalElement { impl TerminalElement {
pub fn new( pub fn new(
terminal: WeakModelHandle<Terminal>, terminal: WeakModel<Terminal>,
focused: bool, focused: bool,
cursor_visible: bool, cursor_visible: bool,
can_navigate_to_selected_word: bool, can_navigate_to_selected_word: bool,
@ -180,7 +174,7 @@ impl TerminalElement {
} }
} }
//Vec<Range<Point>> -> Clip out the parts of the ranges //Vec<Range<AlacPoint>> -> Clip out the parts of the ranges
fn layout_grid( fn layout_grid(
grid: &Vec<IndexedCell>, grid: &Vec<IndexedCell>,
@ -188,7 +182,7 @@ impl TerminalElement {
terminal_theme: &TerminalStyle, terminal_theme: &TerminalStyle,
text_layout_cache: &TextLayoutCache, text_layout_cache: &TextLayoutCache,
font_cache: &FontCache, font_cache: &FontCache,
hyperlink: Option<(HighlightStyle, &RangeInclusive<Point>)>, hyperlink: Option<(HighlightStyle, &RangeInclusive<AlacPoint>)>,
) -> (Vec<LayoutCell>, Vec<LayoutRect>) { ) -> (Vec<LayoutCell>, Vec<LayoutRect>) {
let mut cells = vec![]; let mut cells = vec![];
let mut rects = vec![]; let mut rects = vec![];
@ -225,7 +219,10 @@ impl TerminalElement {
rects.push(cur_rect.take().unwrap()); rects.push(cur_rect.take().unwrap());
} }
cur_rect = Some(LayoutRect::new( cur_rect = Some(LayoutRect::new(
Point::new(line_index as i32, cell.point.column.0 as i32), AlacPoint::new(
line_index as i32,
cell.point.column.0 as i32,
),
1, 1,
convert_color(&bg, &terminal_theme), convert_color(&bg, &terminal_theme),
)); ));
@ -234,7 +231,7 @@ impl TerminalElement {
None => { None => {
cur_alac_color = Some(bg); cur_alac_color = Some(bg);
cur_rect = Some(LayoutRect::new( cur_rect = Some(LayoutRect::new(
Point::new(line_index as i32, cell.point.column.0 as i32), AlacPoint::new(line_index as i32, cell.point.column.0 as i32),
1, 1,
convert_color(&bg, &terminal_theme), convert_color(&bg, &terminal_theme),
)); ));
@ -263,7 +260,7 @@ impl TerminalElement {
); );
cells.push(LayoutCell::new( cells.push(LayoutCell::new(
Point::new(line_index as i32, cell.point.column.0 as i32), AlacPoint::new(line_index as i32, cell.point.column.0 as i32),
layout_cell, layout_cell,
)) ))
}; };
@ -312,7 +309,7 @@ impl TerminalElement {
style: &TerminalStyle, style: &TerminalStyle,
text_style: &TextStyle, text_style: &TextStyle,
font_cache: &FontCache, font_cache: &FontCache,
hyperlink: Option<(HighlightStyle, &RangeInclusive<Point>)>, hyperlink: Option<(HighlightStyle, &RangeInclusive<AlacPoint>)>,
) -> RunStyle { ) -> RunStyle {
let flags = indexed.cell.flags; let flags = indexed.cell.flags;
let fg = convert_color(&fg, &style); let fg = convert_color(&fg, &style);
@ -366,8 +363,8 @@ impl TerminalElement {
} }
fn generic_button_handler<E>( fn generic_button_handler<E>(
connection: WeakModelHandle<Terminal>, connection: WeakModel<Terminal>,
origin: Vector2F, origin: Point<Pixels>,
f: impl Fn(&mut Terminal, Vector2F, E, &mut ModelContext<Terminal>), f: impl Fn(&mut Terminal, Vector2F, E, &mut ModelContext<Terminal>),
) -> impl Fn(E, &mut TerminalView, &mut EventContext<TerminalView>) { ) -> impl Fn(E, &mut TerminalView, &mut EventContext<TerminalView>) {
move |event, _: &mut TerminalView, cx| { move |event, _: &mut TerminalView, cx| {
@ -384,8 +381,8 @@ impl TerminalElement {
fn attach_mouse_handlers( fn attach_mouse_handlers(
&self, &self,
origin: Vector2F, origin: Point<Pixels>,
visible_bounds: RectF, visible_bounds: Bounds,
mode: TermMode, mode: TermMode,
cx: &mut ViewContext<TerminalView>, cx: &mut ViewContext<TerminalView>,
) { ) {
@ -729,8 +726,8 @@ impl Element<TerminalView> for TerminalElement {
fn paint( fn paint(
&mut self, &mut self,
bounds: RectF, bounds: Bounds,
visible_bounds: RectF, visible_bounds: Bounds,
layout: &mut Self::LayoutState, layout: &mut Self::LayoutState,
view: &mut TerminalView, view: &mut TerminalView,
cx: &mut ViewContext<TerminalView>, cx: &mut ViewContext<TerminalView>,
@ -749,7 +746,7 @@ impl Element<TerminalView> for TerminalElement {
cx.scene().push_cursor_region(gpui::CursorRegion { cx.scene().push_cursor_region(gpui::CursorRegion {
bounds, bounds,
style: if layout.hyperlink_tooltip.is_some() { style: if layout.hyperlink_tooltip.is_some() {
CursorStyle::PointingHand CursorStyle::AlacPointingHand
} else { } else {
CursorStyle::IBeam CursorStyle::IBeam
}, },
@ -817,7 +814,7 @@ impl Element<TerminalView> for TerminalElement {
fn debug( fn debug(
&self, &self,
_: RectF, _: Bounds,
_: &Self::LayoutState, _: &Self::LayoutState,
_: &Self::PaintState, _: &Self::PaintState,
_: &TerminalView, _: &TerminalView,
@ -831,8 +828,8 @@ impl Element<TerminalView> for TerminalElement {
fn rect_for_text_range( fn rect_for_text_range(
&self, &self,
_: Range<usize>, _: Range<usize>,
bounds: RectF, bounds: Bounds,
_: RectF, _: Bounds,
layout: &Self::LayoutState, layout: &Self::LayoutState,
_: &Self::PaintState, _: &Self::PaintState,
_: &TerminalView, _: &TerminalView,
@ -875,9 +872,9 @@ fn is_blank(cell: &IndexedCell) -> bool {
} }
fn to_highlighted_range_lines( fn to_highlighted_range_lines(
range: &RangeInclusive<Point>, range: &RangeInclusive<AlacPoint>,
layout: &LayoutState, layout: &LayoutState,
origin: Vector2F, origin: Point<Pixels>,
) -> Option<(f32, Vec<HighlightedRangeLine>)> { ) -> Option<(f32, Vec<HighlightedRangeLine>)> {
// Step 1. Normalize the points to be viewport relative. // Step 1. Normalize the points to be viewport relative.
// When display_offset = 1, here's how the grid is arranged: // When display_offset = 1, here's how the grid is arranged:
@ -897,11 +894,12 @@ fn to_highlighted_range_lines(
// of the grid data we should be looking at. But for the rendering step, we don't // of the grid data we should be looking at. But for the rendering step, we don't
// want negatives. We want things relative to the 'viewport' (the area of the grid // want negatives. We want things relative to the 'viewport' (the area of the grid
// which is currently shown according to the display offset) // which is currently shown according to the display offset)
let unclamped_start = Point::new( let unclamped_start = AlacPoint::new(
range.start().line + layout.display_offset, range.start().line + layout.display_offset,
range.start().column, range.start().column,
); );
let unclamped_end = Point::new(range.end().line + layout.display_offset, range.end().column); let unclamped_end =
AlacPoint::new(range.end().line + layout.display_offset, range.end().column);
// Step 2. Clamp range to viewport, and return None if it doesn't overlap // Step 2. Clamp range to viewport, and return None if it doesn't overlap
if unclamped_end.line.0 < 0 || unclamped_start.line.0 > layout.size.num_lines() as i32 { if unclamped_end.line.0 < 0 || unclamped_start.line.0 > layout.size.num_lines() as i32 {
@ -911,7 +909,7 @@ fn to_highlighted_range_lines(
let clamped_start_line = unclamped_start.line.0.max(0) as usize; let clamped_start_line = unclamped_start.line.0.max(0) as usize;
let clamped_end_line = unclamped_end.line.0.min(layout.size.num_lines() as i32) as usize; let clamped_end_line = unclamped_end.line.0.min(layout.size.num_lines() as i32) as usize;
//Convert the start of the range to pixels //Convert the start of the range to pixels
let start_y = origin.y() + clamped_start_line as f32 * layout.size.line_height; let start_y = origin.y + clamped_start_line as f32 * layout.size.line_height;
// Step 3. Expand ranges that cross lines into a collection of single-line ranges. // Step 3. Expand ranges that cross lines into a collection of single-line ranges.
// (also convert to pixels) // (also convert to pixels)