Skip to content

Commit

Permalink
move gutter layout into gutter widget (#352)
Browse files Browse the repository at this point in the history
  • Loading branch information
andystopia authored Mar 7, 2024
1 parent 3c41a54 commit 764857c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 43 deletions.
71 changes: 62 additions & 9 deletions src/views/editor/gutter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
cosmic_text::{Attrs, AttrsList, TextLayout},
id::Id,
peniko::kurbo::Point,
style::Style,
view::{AnyWidget, View, ViewData, Widget},
Renderer,
};
Expand All @@ -15,7 +16,10 @@ use super::{color::EditorColor, Editor};
pub struct EditorGutterView {
data: ViewData,
editor: RwSignal<Editor>,
width: f64,
full_width: f64,
text_width: f64,
padding_left: f64,
padding_right: f64,
}

pub fn editor_gutter_view(editor: RwSignal<Editor>) -> EditorGutterView {
Expand All @@ -24,7 +28,11 @@ pub fn editor_gutter_view(editor: RwSignal<Editor>) -> EditorGutterView {
EditorGutterView {
data: ViewData::new(id),
editor,
width: 0.0,
full_width: 0.0,
text_width: 0.0,
// TODO: these are probably tuned for lapce?
padding_left: 25.0,
padding_right: 30.0,
}
}

Expand All @@ -50,9 +58,44 @@ impl Widget for EditorGutterView {
&mut self.data
}

fn layout(&mut self, cx: &mut crate::context::LayoutCx) -> taffy::prelude::NodeId {
cx.layout_node(self.id(), true, |cx| {
let (width, height) = (self.text_width, 10.0);
let layout_node = cx
.app_state_mut()
.taffy
.new_leaf(taffy::style::Style::DEFAULT)
.unwrap();

let style = Style::new()
.width(self.padding_left + width + self.padding_right)
.height(height)
.to_taffy_style();
let _ = cx.app_state_mut().taffy.set_style(layout_node, style);
vec![layout_node]
})
}
fn compute_layout(&mut self, cx: &mut crate::context::ComputeLayoutCx) -> Option<Rect> {
if let Some(width) = cx.get_layout(self.data.id()).map(|l| l.size.width as f64) {
self.width = width;
self.full_width = width;
}

let style = self.editor.get_untracked().style.get_untracked();
// TODO: don't assume font family is constant for each line
let family = style.font_family(0);
let attrs = Attrs::new()
.family(&family)
.color(style.color(EditorColor::Dim))
.font_size(style.font_size(0) as f32);

let attrs_list = AttrsList::new(attrs);

let widest_text_width = self.compute_widest_text_width(&attrs_list);
if (self.full_width - widest_text_width - self.padding_left - self.padding_right).abs()
> 1e-2
{
self.text_width = widest_text_width;
cx.app_state_mut().request_layout(self.id());
}
None
}
Expand Down Expand Up @@ -81,6 +124,8 @@ impl Widget for EditorGutterView {
&& editor.modal_relative_line_numbers.get_untracked()
&& mode != Mode::Insert;

self.text_width = self.compute_widest_text_width(&attrs_list);

editor.screen_lines.with_untracked(|screen_lines| {
for (line, y) in screen_lines.iter_lines_y() {
// If it ends up outside the bounds of the file, stop trying to display line numbers
Expand Down Expand Up @@ -110,14 +155,22 @@ impl Widget for EditorGutterView {
let size = text_layout.size();
let height = size.height;

cx.draw_text(
&text_layout,
Point::new(
(self.width - (size.width)).max(0.0),
y + (line_height - height) / 2.0 - viewport.y0,
),
let pos = Point::new(
(self.full_width - (size.width) - self.padding_right).max(0.0),
y + (line_height - height) / 2.0 - viewport.y0,
);

cx.draw_text(&text_layout, pos);
}
});
}
}

impl EditorGutterView {
fn compute_widest_text_width(&mut self, attrs_list: &AttrsList) -> f64 {
let last_line = self.editor.get_untracked().last_line() + 1;
let mut text = TextLayout::new();
text.set_text(&last_line.to_string(), attrs_list.clone());
text.size().width
}
}
44 changes: 10 additions & 34 deletions src/views/editor/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
style::{CursorStyle, Style},
taffy::tree::NodeId,
view::{AnyWidget, View, ViewData, Widget},
views::{clip, container, empty, label, scroll, stack, Decorators},
views::{container, empty, scroll, stack, Decorators},
EventPropagation, Renderer,
};
use floem_editor_core::{
Expand Down Expand Up @@ -1118,45 +1118,21 @@ pub fn editor_container_view(
/// Default editor gutter
/// Simply shows line numbers
pub fn editor_gutter(editor: RwSignal<Editor>) -> impl View {
// TODO: these are probably tuned for lapce?
let padding_left = 25.0;
let padding_right = 30.0;

let ed = editor.get_untracked();

let scroll_delta = ed.scroll_delta;

let gutter_rect = create_rw_signal(Rect::ZERO);

stack((
stack((
empty().style(move |s| s.width(padding_left)),
// TODO(minor): this could just track purely Doc
label(move || (editor.get().last_line() + 1).to_string()),
empty().style(move |s| s.width(padding_right)),
))
.style(|s| s.height_pct(100.0)),
clip(
stack((editor_gutter_view(editor)
.on_resize(move |rect| {
gutter_rect.set(rect);
})
.on_event_stop(EventListener::PointerWheel, move |event| {
if let Event::PointerWheel(pointer_event) = event {
scroll_delta.set(pointer_event.delta);
}
})
.style(|s| s.size_pct(100.0, 100.0)),))
.style(|s| s.size_pct(100.0, 100.0)),
)
.style(move |s| {
s.absolute()
.size_pct(100.0, 100.0)
.padding_left(padding_left)
.padding_right(padding_right)
}),
))
.style(|s| s.height_pct(100.0))
editor_gutter_view(editor)
.on_resize(move |rect| {
gutter_rect.set(rect);
})
.on_event_stop(EventListener::PointerWheel, move |event| {
if let Event::PointerWheel(pointer_event) = event {
scroll_delta.set(pointer_event.delta);
}
})
}

fn editor_content(
Expand Down

0 comments on commit 764857c

Please sign in to comment.