editor: Use measure_indent_width for indent guides width. (#1428)
Continue #1426, this changes I was forgotten to push before #1426 merged.
This commit is contained in:
parent
178269be63
commit
6ebb9418a0
3 changed files with 42 additions and 12 deletions
|
|
@ -9,7 +9,7 @@ use std::{
|
|||
use anyhow::Ok;
|
||||
use gpui::{prelude::FluentBuilder, *};
|
||||
use gpui_component::{
|
||||
ActiveTheme, ContextModal, IconName, IndexPath, Selectable, Sizable,
|
||||
ActiveTheme, ContextModal, IconName, IndexPath, Sizable,
|
||||
button::{Button, ButtonVariants as _},
|
||||
dropdown::{Dropdown, DropdownEvent, DropdownState},
|
||||
h_flex,
|
||||
|
|
@ -998,16 +998,18 @@ impl Render for Example {
|
|||
Button::new("soft-wrap")
|
||||
.ghost()
|
||||
.xsmall()
|
||||
.when(self.soft_wrap, |this| this.icon(IconName::Check))
|
||||
.label("Soft Wrap")
|
||||
.selected(self.soft_wrap)
|
||||
.on_click(cx.listener(Self::toggle_soft_wrap))
|
||||
})
|
||||
.child({
|
||||
Button::new("indent-guides")
|
||||
.ghost()
|
||||
.xsmall()
|
||||
.when(self.indent_guides, |this| {
|
||||
this.icon(IconName::Check)
|
||||
})
|
||||
.label("Indent Guides")
|
||||
.selected(self.indent_guides)
|
||||
.on_click(cx.listener(Self::toggle_indent_guides))
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1084,7 +1084,8 @@ impl Element for TextElement {
|
|||
};
|
||||
|
||||
let hover_definition_hitbox = self.layout_hover_definition_hitbox(state, window, cx);
|
||||
let indent_guides_path = self.layout_indent_guides(state, &last_layout);
|
||||
let indent_guides_path =
|
||||
self.layout_indent_guides(state, &last_layout, &text_style, window);
|
||||
|
||||
PrepaintState {
|
||||
bounds,
|
||||
|
|
@ -1194,7 +1195,7 @@ impl Element for TextElement {
|
|||
|
||||
// Paint indent guides
|
||||
if let Some(path) = prepaint.indent_guides_path.take() {
|
||||
window.paint_path(path, cx.theme().secondary);
|
||||
window.paint_path(path, cx.theme().border.opacity(0.85));
|
||||
}
|
||||
|
||||
// Paint selections
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use gpui::{
|
||||
point, px, Context, EntityInputHandler as _, Path, PathBuilder, Pixels, SharedString, Window,
|
||||
point, px, Context, EntityInputHandler as _, Hsla, Path, PathBuilder, Pixels, SharedString,
|
||||
TextRun, TextStyle, Window,
|
||||
};
|
||||
use ropey::RopeSlice;
|
||||
|
||||
|
|
@ -80,21 +81,46 @@ impl InputMode {
|
|||
}
|
||||
|
||||
impl TextElement {
|
||||
/// Measure the indent width in pixels for given column count.
|
||||
fn measure_indent_width(&self, style: &TextStyle, column: usize, window: &Window) -> Pixels {
|
||||
let font_size = style.font_size.to_pixels(window.rem_size());
|
||||
let layout = window.text_system().shape_line(
|
||||
SharedString::from(" ".repeat(column)),
|
||||
font_size,
|
||||
&[TextRun {
|
||||
len: column,
|
||||
font: style.font(),
|
||||
color: Hsla::default(),
|
||||
background_color: None,
|
||||
strikethrough: None,
|
||||
underline: None,
|
||||
}],
|
||||
None,
|
||||
);
|
||||
|
||||
layout.width
|
||||
}
|
||||
|
||||
pub(super) fn layout_indent_guides(
|
||||
&self,
|
||||
state: &InputState,
|
||||
last_layout: &LastLayout,
|
||||
text_style: &TextStyle,
|
||||
window: &mut Window,
|
||||
) -> Option<Path<Pixels>> {
|
||||
if !state.mode.has_indent_guides() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let indent_width =
|
||||
self.measure_indent_width(text_style, state.mode.tab_size().tab_size, window);
|
||||
|
||||
let tab_size = state.mode.tab_size();
|
||||
let line_height = last_layout.line_height;
|
||||
let visible_range = last_layout.visible_range.clone();
|
||||
let mut builder = PathBuilder::stroke(px(1.));
|
||||
let mut offset_y =
|
||||
last_layout.visible_top + state.scroll_handle.offset().y + (line_height * 2 - px(3.));
|
||||
last_layout.visible_top + state.scroll_handle.offset().y + (line_height * 2 - px(3.5));
|
||||
let mut last_indents = vec![];
|
||||
for ix in visible_range {
|
||||
let line = state.text.slice_line(ix);
|
||||
|
|
@ -103,12 +129,13 @@ impl TextElement {
|
|||
if line.len() > 0 {
|
||||
let indent_count = tab_size.indent_count(&line);
|
||||
for offset in (0..indent_count).step_by(tab_size.tab_size) {
|
||||
let mut pos = line_layout
|
||||
.position_for_index(offset, line_height)
|
||||
.unwrap_or(point(px(0.), px(0.)));
|
||||
let x = if indent_count > 0 {
|
||||
indent_width * offset as f32 / tab_size.tab_size as f32
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
|
||||
pos.x += last_layout.line_number_width;
|
||||
pos.y += offset_y;
|
||||
let pos = point(x + last_layout.line_number_width, offset_y);
|
||||
|
||||
builder.move_to(pos);
|
||||
builder.line_to(point(pos.x, pos.y + line_height));
|
||||
|
|
|
|||
Loading…
Reference in a new issue