mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-09 21:26:14 +03:00
Ensure editor elements invalidate their parent views on notify
Co-Authored-By: Nathan Sobo <nathan@zed.dev> Co-Authored-By: Conrad Irwin <conrad@zed.dev>
This commit is contained in:
parent
a32ad3f907
commit
817b641c17
@ -26,11 +26,11 @@ use git::diff::DiffHunkStatus;
|
||||
use gpui::{
|
||||
div, fill, outline, overlay, point, px, quad, relative, size, transparent_black, Action,
|
||||
AnchorCorner, AnyElement, AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Hsla, InteractiveBounds,
|
||||
InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
||||
MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine,
|
||||
SharedString, Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun,
|
||||
TextStyle, View, ViewContext, WindowContext,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Hsla,
|
||||
InteractiveBounds, InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollDelta,
|
||||
ScrollWheelEvent, ShapedLine, SharedString, Size, StackingOrder, StatefulInteractiveElement,
|
||||
Style, Styled, TextRun, TextStyle, View, ViewContext, WindowContext,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::language_settings::ShowWhitespaceSetting;
|
||||
@ -2801,44 +2801,49 @@ impl Element for EditorElement {
|
||||
_element_state: Option<Self::State>,
|
||||
cx: &mut gpui::WindowContext,
|
||||
) -> (gpui::LayoutId, Self::State) {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.set_style(self.style.clone(), cx);
|
||||
cx.with_view_id(self.editor.entity_id(), |cx| {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.set_style(self.style.clone(), cx);
|
||||
|
||||
let layout_id = match editor.mode {
|
||||
EditorMode::SingleLine => {
|
||||
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, _, cx| {
|
||||
editor_handle
|
||||
.update(cx, |editor, cx| {
|
||||
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)
|
||||
}
|
||||
};
|
||||
let layout_id = match editor.mode {
|
||||
EditorMode::SingleLine => {
|
||||
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, _, cx| {
|
||||
editor_handle
|
||||
.update(cx, |editor, cx| {
|
||||
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)
|
||||
}
|
||||
};
|
||||
|
||||
(layout_id, ())
|
||||
(layout_id, ())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -2850,65 +2855,67 @@ impl Element for EditorElement {
|
||||
) {
|
||||
let editor = self.editor.clone();
|
||||
|
||||
cx.with_text_style(
|
||||
Some(gpui::TextStyleRefinement {
|
||||
font_size: Some(self.style.text.font_size),
|
||||
..Default::default()
|
||||
}),
|
||||
|cx| {
|
||||
let mut layout = self.compute_layout(bounds, cx);
|
||||
let gutter_bounds = Bounds {
|
||||
origin: bounds.origin,
|
||||
size: layout.gutter_size,
|
||||
};
|
||||
let text_bounds = Bounds {
|
||||
origin: gutter_bounds.upper_right(),
|
||||
size: layout.text_size,
|
||||
};
|
||||
cx.paint_view(self.editor.entity_id(), |cx| {
|
||||
cx.with_text_style(
|
||||
Some(gpui::TextStyleRefinement {
|
||||
font_size: Some(self.style.text.font_size),
|
||||
..Default::default()
|
||||
}),
|
||||
|cx| {
|
||||
let mut layout = self.compute_layout(bounds, cx);
|
||||
let gutter_bounds = Bounds {
|
||||
origin: bounds.origin,
|
||||
size: layout.gutter_size,
|
||||
};
|
||||
let text_bounds = Bounds {
|
||||
origin: gutter_bounds.upper_right(),
|
||||
size: layout.text_size,
|
||||
};
|
||||
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
let key_context = self.editor.read(cx).key_context(cx);
|
||||
cx.with_key_dispatch(Some(key_context), Some(focus_handle.clone()), |_, cx| {
|
||||
self.register_actions(cx);
|
||||
self.register_key_listeners(cx);
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
let key_context = self.editor.read(cx).key_context(cx);
|
||||
cx.with_key_dispatch(Some(key_context), Some(focus_handle.clone()), |_, cx| {
|
||||
self.register_actions(cx);
|
||||
self.register_key_listeners(cx);
|
||||
|
||||
cx.with_content_mask(Some(ContentMask { bounds }), |cx| {
|
||||
let input_handler =
|
||||
ElementInputHandler::new(bounds, self.editor.clone(), cx);
|
||||
cx.handle_input(&focus_handle, input_handler);
|
||||
cx.with_content_mask(Some(ContentMask { bounds }), |cx| {
|
||||
let input_handler =
|
||||
ElementInputHandler::new(bounds, self.editor.clone(), cx);
|
||||
cx.handle_input(&focus_handle, input_handler);
|
||||
|
||||
self.paint_background(gutter_bounds, text_bounds, &layout, cx);
|
||||
if layout.gutter_size.width > Pixels::ZERO {
|
||||
self.paint_gutter(gutter_bounds, &mut layout, cx);
|
||||
}
|
||||
self.paint_text(text_bounds, &mut layout, cx);
|
||||
self.paint_background(gutter_bounds, text_bounds, &layout, cx);
|
||||
if layout.gutter_size.width > Pixels::ZERO {
|
||||
self.paint_gutter(gutter_bounds, &mut layout, cx);
|
||||
}
|
||||
self.paint_text(text_bounds, &mut layout, cx);
|
||||
|
||||
cx.with_z_index(0, |cx| {
|
||||
self.paint_mouse_listeners(
|
||||
bounds,
|
||||
gutter_bounds,
|
||||
text_bounds,
|
||||
&layout,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
if !layout.blocks.is_empty() {
|
||||
cx.with_z_index(0, |cx| {
|
||||
cx.with_element_id(Some("editor_blocks"), |cx| {
|
||||
self.paint_blocks(bounds, &mut layout, cx);
|
||||
});
|
||||
})
|
||||
}
|
||||
self.paint_mouse_listeners(
|
||||
bounds,
|
||||
gutter_bounds,
|
||||
text_bounds,
|
||||
&layout,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
if !layout.blocks.is_empty() {
|
||||
cx.with_z_index(0, |cx| {
|
||||
cx.with_element_id(Some("editor_blocks"), |cx| {
|
||||
self.paint_blocks(bounds, &mut layout, cx);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
cx.with_z_index(1, |cx| {
|
||||
self.paint_overlays(text_bounds, &mut layout, cx);
|
||||
cx.with_z_index(1, |cx| {
|
||||
self.paint_overlays(text_bounds, &mut layout, cx);
|
||||
});
|
||||
|
||||
cx.with_z_index(2, |cx| self.paint_scrollbar(bounds, &mut layout, cx));
|
||||
});
|
||||
|
||||
cx.with_z_index(2, |cx| self.paint_scrollbar(bounds, &mut layout, cx));
|
||||
});
|
||||
})
|
||||
},
|
||||
);
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -3588,10 +3595,8 @@ mod tests {
|
||||
|
||||
// Don't panic.
|
||||
let bounds = Bounds::<Pixels>::new(Default::default(), size);
|
||||
cx.update_window(window.into(), |view, cx| {
|
||||
cx.paint_view(view.entity_id(), |cx| element.paint(bounds, &mut (), cx))
|
||||
})
|
||||
.unwrap()
|
||||
cx.update_window(window.into(), |view, cx| element.paint(bounds, &mut (), cx))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -2009,24 +2009,34 @@ impl<'a> WindowContext<'a> {
|
||||
pub fn with_view_id<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
let text_system = self.text_system().clone();
|
||||
text_system.with_view(view_id, || {
|
||||
self.window.next_frame.view_stack.push(view_id);
|
||||
let result = f(self);
|
||||
self.window.next_frame.view_stack.pop();
|
||||
result
|
||||
if self.window.next_frame.view_stack.last() == Some(&view_id) {
|
||||
return f(self);
|
||||
} else {
|
||||
self.window.next_frame.view_stack.push(view_id);
|
||||
let result = f(self);
|
||||
self.window.next_frame.view_stack.pop();
|
||||
result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Invoke the given function with the given view id present on the view stack.
|
||||
/// This is a fairly low-level method used to paint views.
|
||||
pub fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
self.with_view_id(view_id, |cx| {
|
||||
cx.window
|
||||
.next_frame
|
||||
.dispatch_tree
|
||||
.push_node(None, None, Some(view_id));
|
||||
let result = f(cx);
|
||||
cx.window.next_frame.dispatch_tree.pop_node();
|
||||
result
|
||||
let text_system = self.text_system().clone();
|
||||
text_system.with_view(view_id, || {
|
||||
if self.window.next_frame.view_stack.last() == Some(&view_id) {
|
||||
return f(self);
|
||||
} else {
|
||||
self.window.next_frame.view_stack.push(view_id);
|
||||
self.window
|
||||
.next_frame
|
||||
.dispatch_tree
|
||||
.push_node(None, None, Some(view_id));
|
||||
let result = f(self);
|
||||
self.window.next_frame.view_stack.pop();
|
||||
result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user