@@ -1734,21 +1734,11 @@ impl Editor {
// Self::new(EditorMode::Full, buffer, None, field_editor_style, cx)
// }
- // pub fn auto_height(
- // max_lines: usize,
- // field_editor_style: Option<Arc<GetFieldEditorTheme>>,
- // cx: &mut ViewContext<Self>,
- // ) -> Self {
- // let buffer = cx.build_model(|cx| Buffer::new(0, cx.model_id() as u64, String::new()));
- // let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
- // Self::new(
- // EditorMode::AutoHeight { max_lines },
- // buffer,
- // None,
- // field_editor_style,
- // cx,
- // )
- // }
+ pub fn auto_height(max_lines: usize, cx: &mut ViewContext<Self>) -> Self {
+ let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
+ let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
+ Self::new(EditorMode::AutoHeight { max_lines }, buffer, None, cx)
+ }
pub fn for_buffer(
buffer: Model<Buffer>,
@@ -2908,6 +2898,7 @@ impl Editor {
}
pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext<Self>) {
+ dbg!("!!!!!!!!!!");
self.transact(cx, |this, cx| {
let (edits, selection_fixup_info): (Vec<_>, Vec<_>) = {
let selections = this.selections.all::<usize>(cx);
@@ -8374,6 +8365,18 @@ impl Editor {
cx.notify();
}
+ pub fn set_style(&mut self, style: EditorStyle, cx: &mut ViewContext<Self>) {
+ let rem_size = cx.rem_size();
+ self.display_map.update(cx, |map, cx| {
+ map.set_font(
+ style.text.font(),
+ style.text.font_size.to_pixels(rem_size),
+ cx,
+ )
+ });
+ self.style = Some(style);
+ }
+
pub fn set_wrap_width(&self, width: Option<Pixels>, cx: &mut AppContext) -> bool {
self.display_map
.update(cx, |map, cx| map.set_wrap_width(width, cx))
@@ -9397,7 +9400,7 @@ impl Render for Editor {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let settings = ThemeSettings::get_global(cx);
let text_style = match self.mode {
- EditorMode::SingleLine => TextStyle {
+ EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
color: cx.theme().colors().text,
font_family: settings.ui_font.family.clone(),
font_features: settings.ui_font.features,
@@ -9410,8 +9413,6 @@ impl Render for Editor {
white_space: WhiteSpace::Normal,
},
- EditorMode::AutoHeight { max_lines } => todo!(),
-
EditorMode::Full => TextStyle {
color: cx.theme().colors().text,
font_family: settings.buffer_font.family.clone(),
@@ -20,9 +20,9 @@ use crate::{
use anyhow::Result;
use collections::{BTreeMap, HashMap};
use gpui::{
- div, point, px, relative, size, transparent_black, Action, AnyElement, AvailableSpace,
- BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase, Edges, Element, ElementId,
- ElementInputHandler, Entity, EntityId, Hsla, InteractiveBounds, InteractiveElement,
+ div, point, px, relative, size, transparent_black, Action, AnyElement, AsyncWindowContext,
+ AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase, Edges, Element,
+ ElementId, ElementInputHandler, Entity, EntityId, Hsla, InteractiveBounds, InteractiveElement,
IntoElement, LineLayout, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
ParentElement, Pixels, RenderOnce, ScrollWheelEvent, ShapedLine, SharedString, Size,
StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, View,
@@ -1662,11 +1662,6 @@ impl EditorElement {
cx: &mut WindowContext,
) -> LayoutState {
self.editor.update(cx, |editor, cx| {
- // let mut size = constraint.max;
- // if size.x.is_infinite() {
- // unimplemented!("we don't yet handle an infinite width constraint on buffer elements");
- // }
-
let snapshot = editor.snapshot(cx);
let style = self.style.clone();
@@ -1702,6 +1697,7 @@ impl EditorElement {
};
editor.gutter_width = gutter_width;
+
let text_width = bounds.size.width - gutter_width;
let overscroll = size(em_width, px(0.));
let snapshot = {
@@ -1714,6 +1710,8 @@ impl EditorElement {
SoftWrap::Column(column) => editor_width.min(column as f32 * em_advance),
};
+ dbg!(bounds.size.width, gutter_width, gutter_margin, overscroll.width, em_width, em_advance, wrap_width);
+ println!("setting wrap width during paint: {wrap_width:?}");
if editor.set_wrap_width(Some(wrap_width), cx) {
editor.snapshot(cx)
} else {
@@ -1728,25 +1726,6 @@ impl EditorElement {
.collect::<SmallVec<[_; 2]>>();
let scroll_height = Pixels::from(snapshot.max_point().row() + 1) * line_height;
- // todo!("this should happen during layout")
- let editor_mode = snapshot.mode;
- if let EditorMode::AutoHeight { max_lines } = editor_mode {
- todo!()
- // size.set_y(
- // scroll_height
- // .min(constraint.max_along(Axis::Vertical))
- // .max(constraint.min_along(Axis::Vertical))
- // .max(line_height)
- // .min(line_height * max_lines as f32),
- // )
- } else if let EditorMode::SingleLine = editor_mode {
- bounds.size.height = line_height.min(bounds.size.height);
- }
- // todo!()
- // else if size.y.is_infinite() {
- // // size.set_y(scroll_height);
- // }
- //
let gutter_size = size(gutter_width, bounds.size.height);
let text_size = size(text_width, bounds.size.height);
@@ -2064,7 +2043,7 @@ impl EditorElement {
.unwrap();
LayoutState {
- mode: editor_mode,
+ mode: snapshot.mode,
position_map: Arc::new(PositionMap {
size: bounds.size,
scroll_position: point(
@@ -2617,19 +2596,44 @@ impl Element for EditorElement {
cx: &mut gpui::WindowContext,
) -> (gpui::LayoutId, Self::State) {
self.editor.update(cx, |editor, cx| {
- editor.style = Some(self.style.clone()); // Long-term, we'd like to eliminate this.
+ editor.set_style(self.style.clone(), cx);
- let rem_size = cx.rem_size();
- let mut style = Style::default();
- style.size.width = relative(1.).into();
- style.size.height = match editor.mode {
+ let layout_id = match editor.mode {
EditorMode::SingleLine => {
- self.style.text.line_height_in_pixels(cx.rem_size()).into()
+ let rem_size = cx.rem_size();
+ let mut style = Style::default();
+ style.size.width = relative(1.).into();
+ style.size.height = self.style.text.line_height_in_pixels(rem_size).into();
+ cx.request_layout(&style, None)
+ }
+ EditorMode::AutoHeight { max_lines } => {
+ let editor_handle = cx.view().clone();
+ let max_line_number_width =
+ self.max_line_number_width(&editor.snapshot(cx), cx);
+ cx.request_measured_layout(
+ Style::default(),
+ move |known_dimensions, available_space, cx| {
+ editor_handle
+ .update(cx, |editor, cx| {
+ dbg!(compute_auto_height_layout(
+ editor,
+ max_lines,
+ max_line_number_width,
+ known_dimensions,
+ cx,
+ ))
+ })
+ .unwrap_or_default()
+ },
+ )
+ }
+ EditorMode::Full => {
+ let mut style = Style::default();
+ style.size.width = relative(1.).into();
+ style.size.height = relative(1.).into();
+ cx.request_layout(&style, None)
}
- EditorMode::AutoHeight { .. } => todo!(),
- EditorMode::Full => relative(1.).into(),
};
- let layout_id = cx.request_layout(&style, None);
(layout_id, ())
})
@@ -4134,3 +4138,60 @@ pub fn register_action<T: Action>(
}
})
}
+
+fn compute_auto_height_layout(
+ editor: &mut Editor,
+ max_lines: usize,
+ max_line_number_width: Pixels,
+ known_dimensions: Size<Option<Pixels>>,
+ cx: &mut ViewContext<Editor>,
+) -> Option<Size<Pixels>> {
+ let mut width = known_dimensions.width?;
+ if let Some(height) = known_dimensions.height {
+ return Some(size(width, height));
+ }
+
+ let style = editor.style.as_ref().unwrap();
+ let font_id = cx.text_system().font_id(&style.text.font()).unwrap();
+ let font_size = style.text.font_size.to_pixels(cx.rem_size());
+ let line_height = style.text.line_height_in_pixels(cx.rem_size());
+ let em_width = cx
+ .text_system()
+ .typographic_bounds(font_id, font_size, 'm')
+ .unwrap()
+ .size
+ .width;
+
+ let mut snapshot = editor.snapshot(cx);
+ let gutter_padding;
+ let gutter_width;
+ let gutter_margin;
+ if snapshot.show_gutter {
+ let descent = cx.text_system().descent(font_id, font_size).unwrap();
+ let gutter_padding_factor = 3.5;
+ gutter_padding = (em_width * gutter_padding_factor).round();
+ gutter_width = max_line_number_width + gutter_padding * 2.0;
+ gutter_margin = -descent;
+ } else {
+ gutter_padding = Pixels::ZERO;
+ gutter_width = Pixels::ZERO;
+ gutter_margin = Pixels::ZERO;
+ };
+
+ editor.gutter_width = gutter_width;
+ let text_width = width - gutter_width;
+ let overscroll = size(em_width, px(0.));
+
+ let editor_width = text_width - gutter_margin - overscroll.width - em_width;
+ println!("setting wrap width during layout: {editor_width:?}");
+ if editor.set_wrap_width(Some(editor_width), cx) {
+ snapshot = editor.snapshot(cx);
+ }
+
+ let scroll_height = Pixels::from(snapshot.max_point().row() + 1) * line_height;
+ let height = scroll_height
+ .max(line_height)
+ .min(line_height * max_lines as f32);
+
+ Some(size(width, height))
+}