WIP: Start on rendering a left border on diagnostic blocks

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
Nathan Sobo 2021-11-29 18:26:17 -07:00
parent b9cee0cc53
commit b608d78b40
5 changed files with 78 additions and 40 deletions

View file

@ -439,7 +439,11 @@ impl ToDisplayPoint for Anchor {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DisplayRow {
Buffer(u32),
Block(BlockId, Option<BlockStyle>),
Block {
id: BlockId,
column: u32,
style: Option<BlockStyle>,
},
Wrap,
}

View file

@ -915,7 +915,11 @@ impl<'a> Iterator for BufferRows<'a> {
let style = self
.cx
.and_then(|cx| block.build_style.lock().as_ref().map(|f| f(cx)));
Some(DisplayRow::Block(block.id, style))
Some(DisplayRow::Block {
id: block.id,
style,
column: block.column,
})
} else {
Some(self.input_buffer_rows.next().unwrap())
}
@ -1217,12 +1221,24 @@ mod tests {
snapshot.buffer_rows(0, None).collect::<Vec<_>>(),
&[
DisplayRow::Buffer(0),
DisplayRow::Block(block_ids[0], None),
DisplayRow::Block(block_ids[1], None),
DisplayRow::Block {
id: block_ids[0],
style: None,
column: 0
},
DisplayRow::Block {
id: block_ids[1],
style: None,
column: 0
},
DisplayRow::Buffer(1),
DisplayRow::Buffer(2),
DisplayRow::Buffer(3),
DisplayRow::Block(block_ids[2], None)
DisplayRow::Block {
id: block_ids[2],
style: None,
column: 0
}
]
);

View file

@ -218,6 +218,7 @@ impl EditorElement {
cx: &mut PaintContext,
) {
let bounds = gutter_bounds.union_rect(text_bounds);
let content_origin = text_bounds.origin() + layout.text_offset;
let scroll_top = layout.snapshot.scroll_position().y() * layout.line_height;
let start_row = layout.snapshot.scroll_position().y() as u32;
let editor = self.view(cx.app);
@ -280,27 +281,30 @@ impl EditorElement {
}
// Draw block backgrounds
for (ixs, block_style) in &layout.block_layouts {
let row = start_row + ixs.start;
for block_layout in &layout.block_layouts {
let row = start_row + block_layout.line_layout_ixs.start;
let offset = vec2f(0., row as f32 * layout.line_height - scroll_top);
let height = ixs.len() as f32 * layout.line_height;
let height = block_layout.line_layout_ixs.len() as f32 * layout.line_height;
if let Some(border_left_color) = block_layout.style.border_left {
cx.scene.push_quad(Quad {
bounds: RectF::new(
content_origin + offset + vec2f(block_layout.left_edge, 0.),
vec2f(1., height),
),
background: Some(border_left_color),
border: Default::default(),
corner_radius: 0.,
})
}
cx.scene.push_quad(Quad {
bounds: RectF::new(
text_bounds.origin() + offset,
vec2f(text_bounds.width(), height),
),
background: block_style.background,
border: block_style
.border
.map_or(Default::default(), |color| Border {
width: 1.,
color,
overlay: true,
top: true,
right: false,
bottom: true,
left: false,
}),
background: block_layout.style.background,
border: Default::default(),
corner_radius: 0.,
});
cx.scene.push_quad(Quad {
@ -308,8 +312,9 @@ impl EditorElement {
gutter_bounds.origin() + offset,
vec2f(gutter_bounds.width(), height),
),
background: block_style.gutter_background,
border: block_style
background: block_layout.style.gutter_background,
border: block_layout
.style
.gutter_border
.map_or(Default::default(), |color| Border {
width: 1.,
@ -484,17 +489,15 @@ impl EditorElement {
fn layout_rows(
&self,
rows: Range<u32>,
line_layouts: &[text_layout::Line],
active_rows: &BTreeMap<u32, bool>,
snapshot: &Snapshot,
cx: &LayoutContext,
) -> (
Vec<Option<text_layout::Line>>,
Vec<(Range<u32>, BlockStyle)>,
) {
) -> (Vec<Option<text_layout::Line>>, Vec<BlockLayout>) {
let style = &self.settings.style;
let include_line_numbers = snapshot.mode == EditorMode::Full;
let mut last_block_id = None;
let mut blocks = Vec::<(Range<u32>, BlockStyle)>::new();
let mut blocks = Vec::<BlockLayout>::new();
let mut line_number_layouts = Vec::with_capacity(rows.len());
let mut line_number = String::new();
for (ix, row) in snapshot
@ -528,17 +531,21 @@ impl EditorElement {
}
last_block_id = None;
}
DisplayRow::Block(block_id, style) => {
DisplayRow::Block { id, style, column } => {
let ix = ix as u32;
if last_block_id == Some(block_id) {
if let Some((row_range, _)) = blocks.last_mut() {
row_range.end += 1;
if last_block_id == Some(id) {
if let Some(block_layout) = blocks.last_mut() {
block_layout.line_layout_ixs.end += 1;
}
} else if let Some(style) = style {
blocks.push((ix..ix + 1, style));
blocks.push(BlockLayout {
line_layout_ixs: ix..ix + 1,
left_edge: line_layouts[ix as usize].x_for_index(column as usize),
style,
});
}
line_number_layouts.push(None);
last_block_id = Some(block_id);
last_block_id = Some(id);
}
DisplayRow::Wrap => {
line_number_layouts.push(None);
@ -773,9 +780,6 @@ impl Element for EditorElement {
}
});
let (line_number_layouts, block_layouts) =
self.layout_rows(start_row..end_row, &active_rows, &snapshot, cx);
let mut max_visible_line_width = 0.0;
let line_layouts = self.layout_lines(start_row..end_row, &mut snapshot, cx);
for line in &line_layouts {
@ -784,6 +788,14 @@ impl Element for EditorElement {
}
}
let (line_number_layouts, block_layouts) = self.layout_rows(
start_row..end_row,
&line_layouts,
&active_rows,
&snapshot,
cx,
);
let mut layout = LayoutState {
size,
gutter_size,
@ -927,7 +939,7 @@ pub struct LayoutState {
highlighted_row: Option<u32>,
line_layouts: Vec<text_layout::Line>,
line_number_layouts: Vec<Option<text_layout::Line>>,
block_layouts: Vec<(Range<u32>, BlockStyle)>,
block_layouts: Vec<BlockLayout>,
line_height: f32,
em_width: f32,
em_advance: f32,
@ -937,6 +949,12 @@ pub struct LayoutState {
max_visible_line_width: f32,
}
struct BlockLayout {
line_layout_ixs: Range<u32>,
left_edge: f32,
style: BlockStyle,
}
impl LayoutState {
fn scroll_width(&self, layout_cache: &TextLayoutCache) -> f32 {
let row = self.snapshot.longest_row();
@ -1189,7 +1207,7 @@ mod tests {
let snapshot = editor.snapshot(cx);
let mut presenter = cx.build_presenter(window_id, 30.);
let mut layout_cx = presenter.build_layout_context(false, cx);
element.layout_rows(0..6, &Default::default(), &snapshot, &mut layout_cx)
element.layout_rows(0..6, &[], &Default::default(), &snapshot, &mut layout_cx)
});
assert_eq!(layouts.len(), 6);
}

View file

@ -276,7 +276,7 @@ pub struct InputEditorStyle {
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Eq)]
pub struct BlockStyle {
pub background: Option<Color>,
pub border: Option<Color>,
pub border_left: Option<Color>,
pub gutter_background: Option<Color>,
pub gutter_border: Option<Color>,
}

View file

@ -249,7 +249,7 @@ line_number_active = "$text.0.color"
selection = "$selection.host"
guest_selections = "$selection.guests"
error_color = "$status.bad"
error_diagnostic = { text = { color = "$status.bad", italic = true } }
error_diagnostic = { border_left = "$status.bad", text = { color = "$status.bad", italic = true } }
invalid_error_diagnostic = { text = { color = "$text.3.color", italic = true } }
warning_diagnostic = { text = { color = "$status.warn", italic = true } }
invalid_warning_diagnostic = { text = { color = "$text.3.color", italic = true } }