109 lines
2.7 KiB
Rust
109 lines
2.7 KiB
Rust
|
|
use std::{rc::Rc, sync::Arc};
|
||
|
|
|
||
|
|
use gpui::{IntoElement, ParentElement, Styled, div, list, px, rems};
|
||
|
|
|
||
|
|
use crate::app;
|
||
|
|
|
||
|
|
#[derive(gpui::IntoElement, Clone)]
|
||
|
|
pub(crate) struct Line {
|
||
|
|
line_number_col_width: gpui::Pixels,
|
||
|
|
line_number: usize,
|
||
|
|
content: gpui::SharedString,
|
||
|
|
diff_marker: DiffMarker,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Clone)]
|
||
|
|
enum DiffMarker {
|
||
|
|
Added,
|
||
|
|
Deleted,
|
||
|
|
Unchanged,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Clone)]
|
||
|
|
struct CodeViewState(gpui::ListState);
|
||
|
|
|
||
|
|
#[derive(Clone)]
|
||
|
|
struct Lines(Rc<Vec<Line>>);
|
||
|
|
|
||
|
|
struct CodeView {
|
||
|
|
state: CodeViewState,
|
||
|
|
lines: Lines,
|
||
|
|
}
|
||
|
|
|
||
|
|
pub(crate) fn line(
|
||
|
|
line_number: usize,
|
||
|
|
content: impl Into<Arc<str>>,
|
||
|
|
diff_marker: DiffMarker,
|
||
|
|
) -> Line {
|
||
|
|
Line {
|
||
|
|
line_number,
|
||
|
|
diff_marker,
|
||
|
|
content: gpui::SharedString::new(content),
|
||
|
|
line_number_col_width: px(0.),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub(crate) fn code_view(state: CodeViewState, lines: Lines) -> CodeView {
|
||
|
|
CodeView { state, lines }
|
||
|
|
}
|
||
|
|
|
||
|
|
impl FromIterator<Line> for Lines {
|
||
|
|
fn from_iter<T: IntoIterator<Item = Line>>(iter: T) -> Self {
|
||
|
|
Lines(Rc::new(iter.into_iter().collect()))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl gpui::RenderOnce for CodeView {
|
||
|
|
fn render(self, window: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
|
||
|
|
let digits = self
|
||
|
|
.lines
|
||
|
|
.0
|
||
|
|
.last()
|
||
|
|
.map(|l| l.line_number.to_string().len())
|
||
|
|
.unwrap_or(0);
|
||
|
|
|
||
|
|
let text_style = window.text_style();
|
||
|
|
let font_size = text_style.font_size.to_pixels(window.rem_size());
|
||
|
|
let font_id = window.text_system().resolve_font(&gpui::font("Menlo"));
|
||
|
|
|
||
|
|
let line_number_col_width = window
|
||
|
|
.text_system()
|
||
|
|
.ch_advance(font_id, font_size)
|
||
|
|
.unwrap_or(px(7.2))
|
||
|
|
* digits;
|
||
|
|
|
||
|
|
list(self.state.0, move |i, _window, _app| {
|
||
|
|
let mut line = self.lines.0[i].clone();
|
||
|
|
line.line_number_col_width = line_number_col_width;
|
||
|
|
|
||
|
|
div()
|
||
|
|
.flex()
|
||
|
|
.flex_row()
|
||
|
|
.items_start()
|
||
|
|
.w_full()
|
||
|
|
.child(line)
|
||
|
|
.into_any_element()
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl gpui::RenderOnce for Line {
|
||
|
|
fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement {
|
||
|
|
let theme = app::current_theme(cx);
|
||
|
|
|
||
|
|
div()
|
||
|
|
.flex()
|
||
|
|
.flex_row()
|
||
|
|
.font_family("Menlo")
|
||
|
|
.text_color(theme.colors.text)
|
||
|
|
.child(
|
||
|
|
div()
|
||
|
|
.bg(theme.colors.surface)
|
||
|
|
.w(self.line_number_col_width)
|
||
|
|
.text_align(gpui::TextAlign::Right)
|
||
|
|
.child(self.line_number.to_string()),
|
||
|
|
)
|
||
|
|
.child(self.content)
|
||
|
|
}
|
||
|
|
}
|