diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 8504d3de5e..bf753a1784 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -1584,27 +1584,34 @@ mod tests { } fn editor_blocks(editor: &View, cx: &mut WindowContext) -> Vec<(u32, SharedString)> { + let editor_view = editor.clone(); editor.update(cx, |editor, cx| { let snapshot = editor.snapshot(cx); snapshot .blocks_in_range(0..snapshot.max_point().row()) .enumerate() .filter_map(|(ix, (row, block))| { - let name = match block { - TransformBlock::Custom(block) => block - .render(&mut BlockContext { - view_context: cx, - anchor_x: px(0.), - gutter_padding: px(0.), - gutter_width: px(0.), - line_height: px(0.), - em_width: px(0.), - block_id: ix, - editor_style: &editor::EditorStyle::default(), - }) - .inner_id()? - .try_into() - .ok()?, + let name: SharedString = match block { + TransformBlock::Custom(block) => cx.with_element_context({ + let editor_view = editor_view.clone(); + |cx| -> Option { + block + .render(&mut BlockContext { + context: cx, + anchor_x: px(0.), + gutter_padding: px(0.), + gutter_width: px(0.), + line_height: px(0.), + em_width: px(0.), + block_id: ix, + view: editor_view, + editor_style: &editor::EditorStyle::default(), + }) + .inner_id()? + .try_into() + .ok() + } + })?, TransformBlock::ExcerptHeader { starts_new_buffer, .. diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index dbbcbccb6e..1b51e55352 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{Anchor, Editor, EditorStyle, ExcerptId, ExcerptRange, ToPoint as _}; use collections::{Bound, HashMap, HashSet}; -use gpui::{AnyElement, Pixels, ViewContext}; +use gpui::{AnyElement, ElementContext, Pixels, View}; use language::{BufferSnapshot, Chunk, Patch, Point}; use parking_lot::Mutex; use std::{ @@ -81,7 +81,8 @@ pub enum BlockStyle { } pub struct BlockContext<'a, 'b> { - pub view_context: &'b mut ViewContext<'a, Editor>, + pub context: &'b mut ElementContext<'a>, + pub view: View, pub anchor_x: Pixels, pub gutter_width: Pixels, pub gutter_padding: Pixels, @@ -933,16 +934,16 @@ impl BlockDisposition { } impl<'a> Deref for BlockContext<'a, '_> { - type Target = ViewContext<'a, Editor>; + type Target = ElementContext<'a>; fn deref(&self) -> &Self::Target { - self.view_context + self.context } } impl DerefMut for BlockContext<'_, '_> { fn deref_mut(&mut self) -> &mut Self::Target { - self.view_context + self.context } } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index bb0fd93f50..b5b5a87ca5 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -3912,7 +3912,7 @@ impl Editor { gutter_hovered: bool, _line_height: Pixels, _gutter_margin: Pixels, - cx: &mut ViewContext, + editor_view: View, ) -> Vec> { fold_data .iter() @@ -3922,14 +3922,19 @@ impl Editor { .map(|(fold_status, buffer_row, active)| { (active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| { IconButton::new(ix as usize, ui::IconName::ChevronDown) - .on_click(cx.listener(move |editor, _e, cx| match fold_status { - FoldStatus::Folded => { - editor.unfold_at(&UnfoldAt { buffer_row }, cx); + .on_click({ + let view = editor_view.clone(); + move |_e, cx| { + view.update(cx, |editor, cx| match fold_status { + FoldStatus::Folded => { + editor.unfold_at(&UnfoldAt { buffer_row }, cx); + } + FoldStatus::Foldable => { + editor.fold_at(&FoldAt { buffer_row }, cx); + } + }) } - FoldStatus::Foldable => { - editor.fold_at(&FoldAt { buffer_row }, cx); - } - })) + }) .icon_color(ui::Color::Muted) .icon_size(ui::IconSize::Small) .selected(fold_status == FoldStatus::Folded) @@ -9575,10 +9580,10 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren .size(ButtonSize::Compact) .style(ButtonStyle::Transparent) .visible_on_hover(group_id) - .on_click(cx.listener({ + .on_click({ let message = diagnostic.message.clone(); - move |_, _, cx| cx.write_to_clipboard(ClipboardItem::new(message.clone())) - })) + move |_click, cx| cx.write_to_clipboard(ClipboardItem::new(message.clone())) + }) .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), ) .into_any_element() diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index ad166bb42b..ab92dac595 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -25,12 +25,12 @@ use collections::{BTreeMap, HashMap}; 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, 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, + AnchorCorner, AnyElement, AvailableSpace, Bounds, ContentMask, Corners, 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; @@ -330,7 +330,7 @@ impl EditorElement { register_action(view, cx, Editor::display_cursor_names); } - fn register_key_listeners(&self, cx: &mut WindowContext) { + fn register_key_listeners(&self, cx: &mut ElementContext) { cx.on_key_event({ let editor = self.editor.clone(); move |event: &ModifiersChangedEvent, phase, cx| { @@ -628,7 +628,7 @@ impl EditorElement { gutter_bounds: Bounds, text_bounds: Bounds, layout: &LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let bounds = gutter_bounds.union(&text_bounds); let scroll_top = @@ -711,7 +711,7 @@ impl EditorElement { &mut self, bounds: Bounds, layout: &mut LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let line_height = layout.position_map.line_height; @@ -782,7 +782,7 @@ impl EditorElement { }); } - fn paint_diff_hunks(bounds: Bounds, layout: &LayoutState, cx: &mut WindowContext) { + fn paint_diff_hunks(bounds: Bounds, layout: &LayoutState, cx: &mut ElementContext) { let line_height = layout.position_map.line_height; let scroll_position = layout.position_map.snapshot.scroll_position(); @@ -886,7 +886,7 @@ impl EditorElement { &mut self, text_bounds: Bounds, layout: &mut LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let start_row = layout.visible_display_row_range.start; let content_origin = text_bounds.origin + point(layout.gutter_margin, Pixels::ZERO); @@ -1153,7 +1153,7 @@ impl EditorElement { &mut self, text_bounds: Bounds, layout: &mut LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let content_origin = text_bounds.origin + point(layout.gutter_margin, Pixels::ZERO); let start_row = layout.visible_display_row_range.start; @@ -1268,7 +1268,7 @@ impl EditorElement { &mut self, bounds: Bounds, layout: &mut LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { if layout.mode != EditorMode::Full { return; @@ -1512,7 +1512,7 @@ impl EditorElement { layout: &LayoutState, content_origin: gpui::Point, bounds: Bounds, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let start_row = layout.visible_display_row_range.start; let end_row = layout.visible_display_row_range.end; @@ -1564,7 +1564,7 @@ impl EditorElement { &mut self, bounds: Bounds, layout: &mut LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let scroll_position = layout.position_map.snapshot.scroll_position(); let scroll_left = scroll_position.x * layout.position_map.em_width; @@ -1814,7 +1814,7 @@ impl EditorElement { } } - fn compute_layout(&mut self, bounds: Bounds, cx: &mut WindowContext) -> LayoutState { + fn compute_layout(&mut self, bounds: Bounds, cx: &mut ElementContext) -> LayoutState { self.editor.update(cx, |editor, cx| { let snapshot = editor.snapshot(cx); let style = self.style.clone(); @@ -2083,7 +2083,9 @@ impl EditorElement { .width; let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.width; - let (scroll_width, blocks) = cx.with_element_id(Some("editor_blocks"), |cx| { + let editor_view = cx.view().clone(); + let (scroll_width, blocks) = cx.with_element_context(|cx| { + cx.with_element_id(Some("editor_blocks"), |cx| { self.layout_blocks( start_row..end_row, &snapshot, @@ -2097,8 +2099,10 @@ impl EditorElement { &style, &line_layouts, editor, + editor_view, cx, ) + }) }); let scroll_max = point( @@ -2174,15 +2178,19 @@ impl EditorElement { cx, ); - let fold_indicators = cx.with_element_id(Some("gutter_fold_indicators"), |cx| { + let editor_view = cx.view().clone(); + let fold_indicators = cx.with_element_context(|cx| { + + cx.with_element_id(Some("gutter_fold_indicators"), |_cx| { editor.render_fold_indicators( fold_statuses, &style, editor.gutter_hovered, line_height, gutter_margin, - cx, + editor_view, ) + }) }); let invisible_symbol_font_size = font_size / 2.; @@ -2273,7 +2281,8 @@ impl EditorElement { style: &EditorStyle, line_layouts: &[LineWithInvisibles], editor: &mut Editor, - cx: &mut ViewContext, + editor_view: View, + cx: &mut ElementContext, ) -> (Pixels, Vec) { let mut block_id = 0; let (fixed_blocks, non_fixed_blocks) = snapshot @@ -2287,7 +2296,7 @@ impl EditorElement { available_space: Size, block_id: usize, editor: &mut Editor, - cx: &mut ViewContext| { + cx: &mut ElementContext| { let mut element = match block { TransformBlock::Custom(block) => { let align_to = block @@ -2306,13 +2315,14 @@ impl EditorElement { }; block.render(&mut BlockContext { - view_context: cx, + context: cx, anchor_x, gutter_padding, line_height, gutter_width, em_width, block_id, + view: editor_view.clone(), editor_style: &self.style, }) } @@ -2504,7 +2514,7 @@ impl EditorElement { &mut self, interactive_bounds: &InteractiveBounds, layout: &LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { cx.on_mouse_event({ let position_map = layout.position_map.clone(); @@ -2564,7 +2574,7 @@ impl EditorElement { gutter_bounds: Bounds, text_bounds: Bounds, layout: &LayoutState, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let interactive_bounds = InteractiveBounds { bounds: bounds.intersect(&cx.content_mask().bounds), @@ -2787,7 +2797,7 @@ impl LineWithInvisibles { content_origin: gpui::Point, whitespace_setting: ShowWhitespaceSetting, selection_ranges: &[Range], - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let line_height = layout.position_map.line_height; let line_y = line_height * row as f32 - layout.position_map.scroll_position.y; @@ -2821,7 +2831,7 @@ impl LineWithInvisibles { row: u32, line_height: Pixels, whitespace_setting: ShowWhitespaceSetting, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let allowed_invisibles_regions = match whitespace_setting { ShowWhitespaceSetting::None => return, @@ -2870,7 +2880,7 @@ impl Element for EditorElement { fn request_layout( &mut self, _element_state: Option, - cx: &mut gpui::WindowContext, + cx: &mut gpui::ElementContext, ) -> (gpui::LayoutId, Self::State) { cx.with_view_id(self.editor.entity_id(), |cx| { self.editor.update(cx, |editor, cx| { @@ -2882,34 +2892,36 @@ impl Element for EditorElement { 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) + cx.with_element_context(|cx| 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() - }, - ) + cx.with_element_context(|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) + cx.with_element_context(|cx| cx.request_layout(&style, None)) } }; @@ -2922,7 +2934,7 @@ impl Element for EditorElement { &mut self, bounds: Bounds, _element_state: &mut Self::State, - cx: &mut gpui::WindowContext, + cx: &mut gpui::ElementContext, ) { let editor = self.editor.clone(); @@ -3204,7 +3216,7 @@ impl Cursor { } } - pub fn paint(&self, origin: gpui::Point, cx: &mut WindowContext) { + pub fn paint(&self, origin: gpui::Point, cx: &mut ElementContext) { let bounds = match self.shape { CursorShape::Bar => Bounds { origin: self.origin + origin, @@ -3284,7 +3296,7 @@ pub struct HighlightedRangeLine { } impl HighlightedRange { - pub fn paint(&self, bounds: Bounds, cx: &mut WindowContext) { + pub fn paint(&self, bounds: Bounds, cx: &mut ElementContext) { if self.lines.len() >= 2 && self.lines[0].start_x > self.lines[1].end_x { self.paint_lines(self.start_y, &self.lines[0..1], bounds, cx); self.paint_lines( @@ -3303,7 +3315,7 @@ impl HighlightedRange { start_y: Pixels, lines: &[HighlightedRangeLine], _bounds: Bounds, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { if lines.is_empty() { return; @@ -3521,14 +3533,16 @@ mod tests { .unwrap(); let state = cx .update_window(window.into(), |view, cx| { - cx.with_view_id(view.entity_id(), |cx| { - element.compute_layout( - Bounds { - origin: point(px(500.), px(500.)), - size: size(px(500.), px(500.)), - }, - cx, - ) + cx.with_element_context(|cx| { + cx.with_view_id(view.entity_id(), |cx| { + element.compute_layout( + Bounds { + origin: point(px(500.), px(500.)), + size: size(px(500.), px(500.)), + }, + cx, + ) + }) }) }) .unwrap(); @@ -3615,14 +3629,16 @@ mod tests { let state = cx .update_window(window.into(), |view, cx| { - cx.with_view_id(view.entity_id(), |cx| { - element.compute_layout( - Bounds { - origin: point(px(500.), px(500.)), - size: size(px(500.), px(500.)), - }, - cx, - ) + cx.with_element_context(|cx| { + cx.with_view_id(view.entity_id(), |cx| { + element.compute_layout( + Bounds { + origin: point(px(500.), px(500.)), + size: size(px(500.), px(500.)), + }, + cx, + ) + }) }) }) .unwrap(); @@ -3679,14 +3695,16 @@ mod tests { let mut element = EditorElement::new(&editor, style); let state = cx .update_window(window.into(), |view, cx| { - cx.with_view_id(view.entity_id(), |cx| { - element.compute_layout( - Bounds { - origin: point(px(500.), px(500.)), - size: size(px(500.), px(500.)), - }, - cx, - ) + cx.with_element_context(|cx| { + cx.with_view_id(view.entity_id(), |cx| { + element.compute_layout( + Bounds { + origin: point(px(500.), px(500.)), + size: size(px(500.), px(500.)), + }, + cx, + ) + }) }) }) .unwrap(); @@ -3704,8 +3722,10 @@ mod tests { // Don't panic. let bounds = Bounds::::new(Default::default(), size); - cx.update_window(window.into(), |_, cx| element.paint(bounds, &mut (), cx)) - .unwrap() + cx.update_window(window.into(), |_, cx| { + cx.with_element_context(|cx| element.paint(bounds, &mut (), cx)) + }) + .unwrap() } #[gpui::test] @@ -3880,13 +3900,15 @@ mod tests { .unwrap(); let layout_state = cx .update_window(window.into(), |_, cx| { - element.compute_layout( - Bounds { - origin: point(px(500.), px(500.)), - size: size(px(500.), px(500.)), - }, - cx, - ) + cx.with_element_context(|cx| { + element.compute_layout( + Bounds { + origin: point(px(500.), px(500.)), + size: size(px(500.), px(500.)), + }, + cx, + ) + }) }) .unwrap(); diff --git a/crates/gpui/src/window/element_cx.rs b/crates/gpui/src/window/element_cx.rs index 3c3c01e2f1..b7c6325751 100644 --- a/crates/gpui/src/window/element_cx.rs +++ b/crates/gpui/src/window/element_cx.rs @@ -30,10 +30,7 @@ pub struct ElementContext<'a> { } impl<'a> WindowContext<'a> { - pub(crate) fn with_element_context( - &mut self, - f: impl FnOnce(&mut ElementContext) -> R, - ) -> R { + pub fn with_element_context(&mut self, f: impl FnOnce(&mut ElementContext) -> R) -> R { f(&mut ElementContext { cx: WindowContext::new(self.app, self.window), }) @@ -176,7 +173,7 @@ impl<'a> ElementContext<'a> { /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is /// used to associate state with identified elements across separate frames. - pub(crate) fn with_element_id( + pub fn with_element_id( &mut self, id: Option>, f: impl FnOnce(&mut Self) -> R, @@ -195,7 +192,7 @@ impl<'a> ElementContext<'a> { /// Invoke the given function with the given content mask after intersecting it /// with the current mask. - pub(crate) fn with_content_mask( + pub fn with_content_mask( &mut self, mask: Option>, f: impl FnOnce(&mut Self) -> R, @@ -213,7 +210,7 @@ impl<'a> ElementContext<'a> { /// Invoke the given function with the content mask reset to that /// of the window. - pub(crate) fn break_content_mask(&mut self, f: impl FnOnce(&mut Self) -> R) -> R { + pub fn break_content_mask(&mut self, f: impl FnOnce(&mut Self) -> R) -> R { let mask = ContentMask { bounds: Bounds { origin: Point::default(), @@ -238,7 +235,7 @@ impl<'a> ElementContext<'a> { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. - pub(crate) fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { + pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { let new_stacking_order_id = post_inc(&mut self.window_mut().next_frame.next_stacking_order_id); let old_stacking_order_id = mem::replace( @@ -255,7 +252,7 @@ impl<'a> ElementContext<'a> { /// Updates the global element offset relative to the current offset. This is used to implement /// scrolling. - pub(crate) fn with_element_offset( + pub fn with_element_offset( &mut self, offset: Point, f: impl FnOnce(&mut Self) -> R, @@ -270,7 +267,7 @@ impl<'a> ElementContext<'a> { /// Updates the global element offset based on the given offset. This is used to implement /// drag handles and other manual painting of elements. - pub(crate) fn with_absolute_element_offset( + pub fn with_absolute_element_offset( &mut self, offset: Point, f: impl FnOnce(&mut Self) -> R, @@ -285,7 +282,7 @@ impl<'a> ElementContext<'a> { } /// Obtain the current element offset. - pub(crate) fn element_offset(&self) -> Point { + pub fn element_offset(&self) -> Point { self.window() .next_frame .element_offset_stack @@ -295,7 +292,7 @@ impl<'a> ElementContext<'a> { } /// Obtain the current content mask. - pub(crate) fn content_mask(&self) -> ContentMask { + pub fn content_mask(&self) -> ContentMask { self.window() .next_frame .content_mask_stack @@ -311,7 +308,7 @@ impl<'a> ElementContext<'a> { /// The size of an em for the base font of the application. Adjusting this value allows the /// UI to scale, just like zooming a web page. - pub(crate) fn rem_size(&self) -> Pixels { + pub fn rem_size(&self) -> Pixels { self.window().rem_size } @@ -319,7 +316,7 @@ impl<'a> ElementContext<'a> { /// frames. If an element with this ID existed in the rendered frame, its state will be passed /// to the given closure. The state returned by the closure will be stored so it can be referenced /// when drawing the next frame. - pub(crate) fn with_element_state( + pub fn with_element_state( &mut self, id: ElementId, f: impl FnOnce(Option, &mut Self) -> (R, S), diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index 9ab62947fd..cd35f9fdcc 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -1,11 +1,11 @@ use editor::{Cursor, HighlightedRange, HighlightedRangeLine}; use gpui::{ - div, fill, point, px, relative, AnyElement, AvailableSpace, BorrowWindow, Bounds, - DispatchPhase, Element, ElementId, FocusHandle, Font, FontStyle, FontWeight, HighlightStyle, - Hsla, InputHandler, InteractiveBounds, InteractiveElement, InteractiveElementState, - Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, - MouseMoveEvent, Pixels, Point, ShapedLine, StatefulInteractiveElement, Styled, TextRun, - TextStyle, TextSystem, UnderlineStyle, WeakView, WhiteSpace, WindowContext, + div, fill, point, px, relative, AnyElement, AvailableSpace, Bounds, DispatchPhase, Element, + ElementContext, ElementId, FocusHandle, Font, FontStyle, FontWeight, HighlightStyle, Hsla, + InputHandler, InteractiveBounds, InteractiveElement, InteractiveElementState, Interactivity, + IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, MouseMoveEvent, + Pixels, Point, ShapedLine, StatefulInteractiveElement, Styled, TextRun, TextStyle, TextSystem, + UnderlineStyle, WeakView, WhiteSpace, WindowContext, }; use itertools::Itertools; use language::CursorShape; @@ -81,7 +81,7 @@ impl LayoutCell { origin: Point, layout: &LayoutState, _visible_bounds: Bounds, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let pos = { let point = self.point; @@ -120,7 +120,7 @@ impl LayoutRect { } } - fn paint(&self, origin: Point, layout: &LayoutState, cx: &mut WindowContext) { + fn paint(&self, origin: Point, layout: &LayoutState, cx: &mut ElementContext) { let position = { let alac_point = self.point; point( @@ -590,7 +590,7 @@ impl TerminalElement { origin: Point, mode: TermMode, bounds: Bounds, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let focus = self.focus.clone(); let terminal = self.terminal.clone(); @@ -722,7 +722,7 @@ impl Element for TerminalElement { fn request_layout( &mut self, element_state: Option, - cx: &mut WindowContext<'_>, + cx: &mut ElementContext<'_>, ) -> (LayoutId, Self::State) { let (layout_id, interactive_state) = self.interactivity @@ -741,7 +741,7 @@ impl Element for TerminalElement { &mut self, bounds: Bounds, state: &mut Self::State, - cx: &mut WindowContext<'_>, + cx: &mut ElementContext<'_>, ) { let mut layout = self.compute_layout(bounds, cx); diff --git a/crates/ui/src/components/popover_menu.rs b/crates/ui/src/components/popover_menu.rs index 10c655909b..0bbbee2900 100644 --- a/crates/ui/src/components/popover_menu.rs +++ b/crates/ui/src/components/popover_menu.rs @@ -2,8 +2,9 @@ use std::{cell::RefCell, rc::Rc}; use gpui::{ overlay, point, prelude::FluentBuilder, px, rems, AnchorCorner, AnyElement, Bounds, - DismissEvent, DispatchPhase, Element, ElementId, InteractiveBounds, IntoElement, LayoutId, - ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, WindowContext, + DismissEvent, DispatchPhase, Element, ElementContext, ElementId, InteractiveBounds, + IntoElement, LayoutId, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View, + VisualContext, WindowContext, }; use crate::{Clickable, Selectable}; @@ -134,7 +135,7 @@ impl Element for PopoverMenu { fn request_layout( &mut self, element_state: Option, - cx: &mut WindowContext, + cx: &mut ElementContext, ) -> (gpui::LayoutId, Self::State) { let mut menu_layout_id = None; @@ -188,7 +189,7 @@ impl Element for PopoverMenu { &mut self, _: Bounds, element_state: &mut Self::State, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { if let Some(mut child) = element_state.child_element.take() { child.paint(cx); diff --git a/crates/ui/src/components/right_click_menu.rs b/crates/ui/src/components/right_click_menu.rs index ee1bd88015..b08f3911cb 100644 --- a/crates/ui/src/components/right_click_menu.rs +++ b/crates/ui/src/components/right_click_menu.rs @@ -1,9 +1,9 @@ use std::{cell::RefCell, rc::Rc}; use gpui::{ - overlay, AnchorCorner, AnyElement, BorrowWindow, Bounds, DismissEvent, DispatchPhase, Element, - ElementId, InteractiveBounds, IntoElement, LayoutId, ManagedView, MouseButton, MouseDownEvent, - ParentElement, Pixels, Point, View, VisualContext, WindowContext, + overlay, AnchorCorner, AnyElement, Bounds, DismissEvent, DispatchPhase, Element, + ElementContext, ElementId, InteractiveBounds, IntoElement, LayoutId, ManagedView, MouseButton, + MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, WindowContext, }; pub struct RightClickMenu { @@ -64,7 +64,7 @@ impl Element for RightClickMenu { fn request_layout( &mut self, element_state: Option, - cx: &mut WindowContext, + cx: &mut ElementContext, ) -> (gpui::LayoutId, Self::State) { let (menu, position) = if let Some(element_state) = element_state { (element_state.menu, element_state.position) @@ -116,7 +116,7 @@ impl Element for RightClickMenu { &mut self, bounds: Bounds, element_state: &mut Self::State, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { if let Some(mut child) = element_state.child_element.take() { child.paint(cx); diff --git a/crates/ui/src/prelude.rs b/crates/ui/src/prelude.rs index 837d93db2d..91e6ed2450 100644 --- a/crates/ui/src/prelude.rs +++ b/crates/ui/src/prelude.rs @@ -2,9 +2,9 @@ pub use gpui::prelude::*; pub use gpui::{ - div, px, relative, rems, AbsoluteLength, DefiniteLength, Div, Element, ElementId, - InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString, Styled, ViewContext, - WindowContext, + div, px, relative, rems, AbsoluteLength, DefiniteLength, Div, Element, ElementContext, + ElementId, InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString, Styled, + ViewContext, WindowContext, }; pub use crate::clickable::*; diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 64e09e67cb..6963ed3cae 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -710,7 +710,7 @@ mod element { pane_bounds: Bounds, axis_bounds: Bounds, workspace: WeakView, - cx: &mut WindowContext, + cx: &mut ElementContext, ) { let handle_bounds = Bounds { origin: pane_bounds.origin.apply_along(axis, |origin| { @@ -803,7 +803,7 @@ mod element { fn request_layout( &mut self, state: Option, - cx: &mut ui::prelude::WindowContext, + cx: &mut ui::prelude::ElementContext, ) -> (gpui::LayoutId, Self::State) { let mut style = Style::default(); style.flex_grow = 1.; @@ -820,7 +820,7 @@ mod element { &mut self, bounds: gpui::Bounds, state: &mut Self::State, - cx: &mut ui::prelude::WindowContext, + cx: &mut ui::prelude::ElementContext, ) { let flexes = self.flexes.lock().clone(); let len = self.children.len(); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index a95a143915..d10cef0c0f 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -26,12 +26,12 @@ use futures::{ }; use gpui::{ actions, canvas, div, impl_actions, point, px, size, Action, AnyElement, AnyModel, AnyView, - AnyWeakView, AppContext, AsyncAppContext, AsyncWindowContext, BorrowWindow, Bounds, Context, - Div, DragMoveEvent, Element, Entity, EntityId, EventEmitter, FocusHandle, FocusableView, - GlobalPixels, InteractiveElement, IntoElement, KeyContext, LayoutId, ManagedView, Model, - ModelContext, ParentElement, PathPromptOptions, Pixels, Point, PromptLevel, Render, Size, - Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds, - WindowContext, WindowHandle, WindowOptions, + AnyWeakView, AppContext, AsyncAppContext, AsyncWindowContext, Bounds, Context, Div, + DragMoveEvent, Element, ElementContext, Entity, EntityId, EventEmitter, FocusHandle, + FocusableView, GlobalPixels, InteractiveElement, IntoElement, KeyContext, LayoutId, + ManagedView, Model, ModelContext, ParentElement, PathPromptOptions, Pixels, Point, PromptLevel, + Render, Size, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, + WindowBounds, WindowContext, WindowHandle, WindowOptions, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem}; use itertools::Itertools; @@ -3539,9 +3539,14 @@ impl Render for Workspace { .border_b() .border_color(colors.border) .child( - canvas(cx.listener(|workspace, bounds, _| { - workspace.bounds = *bounds; - })) + canvas({ + let this = cx.view().clone(); + move |bounds, cx| { + this.update(cx, |this, _cx| { + this.bounds = *bounds; + }) + } + }) .absolute() .size_full(), ) @@ -4293,7 +4298,7 @@ impl Element for DisconnectedOverlay { fn request_layout( &mut self, _: Option, - cx: &mut WindowContext, + cx: &mut ElementContext, ) -> (LayoutId, Self::State) { let mut background = cx.theme().colors().elevated_surface_background; background.fade_out(0.2); @@ -4315,7 +4320,12 @@ impl Element for DisconnectedOverlay { (overlay.request_layout(cx), overlay) } - fn paint(&mut self, bounds: Bounds, overlay: &mut Self::State, cx: &mut WindowContext) { + fn paint( + &mut self, + bounds: Bounds, + overlay: &mut Self::State, + cx: &mut ElementContext, + ) { cx.with_z_index(u8::MAX, |cx| { cx.add_opaque_layer(bounds); overlay.paint(cx);