ui: Redo selection rendering.

pull/8/head
Blaž Hrastnik 4 years ago
parent c408e7e01a
commit 8e1a59c140

@ -100,20 +100,6 @@ impl EditorView {
let mut spans = Vec::new(); let mut spans = Vec::new();
let mut visual_x = 0; let mut visual_x = 0;
let mut line = 0u16; let mut line = 0u16;
let visible_selections: Vec<Range> = if is_focused {
view.doc
.state
.selection()
.ranges()
.iter()
// TODO: limit selection to one in viewport
// .filter(|range| !range.is_empty()) // && range.overlaps(&Range::new(start, end + 1))
.copied()
.collect()
} else {
// don't render selections on unfocused windows
Vec::new()
};
'outer: for event in highlights { 'outer: for event in highlights {
match event.unwrap() { match event.unwrap() {
@ -174,26 +160,6 @@ impl EditorView {
let grapheme = Cow::from(grapheme); let grapheme = Cow::from(grapheme);
let width = grapheme_width(&grapheme) as u16; let width = grapheme_width(&grapheme) as u16;
// TODO: this should really happen as an after pass
let style = if visible_selections
.iter()
.any(|range| range.contains(char_index))
{
// cedar
style.clone().bg(Color::Rgb(128, 47, 0))
} else {
style
};
let style = if visible_selections
.iter()
.any(|range| range.head == char_index)
{
style.clone().bg(Color::Rgb(255, 255, 255))
} else {
style
};
// ugh, improve with a traverse method // ugh, improve with a traverse method
// or interleave highlight spans with selection and diagnostic spans // or interleave highlight spans with selection and diagnostic spans
let is_diagnostic = view.doc.diagnostics.iter().any(|diagnostic| { let is_diagnostic = view.doc.diagnostics.iter().any(|diagnostic| {
@ -206,8 +172,6 @@ impl EditorView {
style style
}; };
// TODO: paint cursor heads except primary
surface.set_string( surface.set_string(
viewport.x + visual_x, viewport.x + visual_x,
viewport.y + line, viewport.y + line,
@ -224,18 +188,102 @@ impl EditorView {
} }
} }
// render selections
if is_focused {
let text = view.doc.text().slice(..);
let screen = {
let start = text.line_to_char(view.first_line);
let end = text.line_to_char(last_line + 1);
Range::new(start, end)
};
let cursor_style = Style::default().bg(Color::Rgb(255, 255, 255));
// cedar
let selection_style = Style::default().bg(Color::Rgb(128, 47, 0));
for selection in view
.doc
.state
.selection()
.ranges()
.iter()
.filter(|range| range.overlaps(&screen))
{
// TODO: render also if only one of the ranges is in viewport
let mut start = view.screen_coords_at_pos(&text, selection.anchor);
let mut end = view.screen_coords_at_pos(&text, selection.head);
// cursor
if let Some(end) = end {
surface.set_style(
Rect::new(
viewport.x + end.col as u16,
viewport.y + end.row as u16,
1,
1,
),
cursor_style,
);
}
if selection.head < selection.anchor {
std::mem::swap(&mut start, &mut end);
}
let start = start.unwrap_or_else(|| Position::new(0, 0));
let end = end.unwrap_or_else(|| {
Position::new(viewport.height as usize, viewport.width as usize)
});
if start.row == end.row {
surface.set_style(
Rect::new(
viewport.x + start.col as u16,
viewport.y + start.row as u16,
(end.col - start.col) as u16,
1,
),
selection_style,
);
} else {
surface.set_style(
Rect::new(
viewport.x + start.col as u16,
viewport.y + start.row as u16,
// text.line(view.first_line).len_chars() as u16 - start.col as u16,
viewport.width - start.col as u16,
1,
),
selection_style,
);
for i in start.row + 1..end.row {
surface.set_style(
Rect::new(
viewport.x,
viewport.y + i as u16,
// text.line(view.first_line + i).len_chars() as u16,
viewport.width,
1,
),
selection_style,
);
}
surface.set_style(
Rect::new(viewport.x, viewport.y + end.row as u16, end.col as u16, 1),
selection_style,
);
}
}
}
// render gutters
let style: Style = theme.get("ui.linenr"); let style: Style = theme.get("ui.linenr");
let warning: Style = theme.get("warning"); let warning: Style = theme.get("warning");
let last_line = view.last_line(); let last_line = view.last_line();
for (i, line) in (view.first_line..last_line).enumerate() { for (i, line) in (view.first_line..last_line).enumerate() {
if view.doc.diagnostics.iter().any(|d| d.line == line) { if view.doc.diagnostics.iter().any(|d| d.line == line) {
surface.set_stringn( surface.set_stringn(viewport.x - OFFSET, viewport.y + i as u16, "●", 1, warning);
viewport.x + 0 - OFFSET,
viewport.y + i as u16,
"●",
1,
warning,
);
} }
surface.set_stringn( surface.set_stringn(

Loading…
Cancel
Save