Merge ElementContext into WindowContext (#10979)

The new `ElementContext` was originally introduced to ensure the element
APIs could only be used inside of elements. Unfortunately, there were
many places where some of those APIs needed to be used, so
`WindowContext::with_element_context` was introduced, which defeated the
original safety purposes of having a specific context for elements.

This pull request merges `ElementContext` into `WindowContext` and adds
(debug) runtime checks to APIs that can only be used during certain
phases of element drawing.

Release Notes:

- N/A

---------

Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-04-25 12:54:39 +02:00 committed by GitHub
parent 031580f4dc
commit 6a7761e620
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 2378 additions and 2367 deletions

View File

@ -912,7 +912,7 @@ mod tests {
display_map::{BlockContext, TransformBlock}, display_map::{BlockContext, TransformBlock},
DisplayPoint, GutterDimensions, DisplayPoint, GutterDimensions,
}; };
use gpui::{px, Stateful, TestAppContext, VisualTestContext, WindowContext}; use gpui::{px, AvailableSpace, Stateful, TestAppContext, VisualTestContext};
use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16, Unclipped}; use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16, Unclipped};
use project::FakeFs; use project::FakeFs;
use serde_json::json; use serde_json::json;
@ -1049,67 +1049,66 @@ mod tests {
cx, cx,
) )
}); });
let editor = view.update(cx, |view, _| view.editor.clone());
view.next_notification(cx).await; view.next_notification(cx).await;
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), (15, "collapsed context".into()),
(15, "collapsed context".into()), (16, "diagnostic header".into()),
(16, "diagnostic header".into()), (25, "collapsed context".into()),
(25, "collapsed context".into()), ]
] );
); assert_eq!(
assert_eq!( editor.update(cx, |editor, cx| editor.display_text(cx)),
view.editor.update(cx, |editor, cx| editor.display_text(cx)), concat!(
concat!( //
// // main.rs
// main.rs //
// "\n", // filename
"\n", // filename "\n", // padding
"\n", // padding // diagnostic group 1
// diagnostic group 1 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding " let x = vec![];\n",
" let x = vec![];\n", " let y = vec![];\n",
" let y = vec![];\n", "\n", // supporting diagnostic
"\n", // supporting diagnostic " a(x);\n",
" a(x);\n", " b(y);\n",
" b(y);\n", "\n", // supporting diagnostic
"\n", // supporting diagnostic " // comment 1\n",
" // comment 1\n", " // comment 2\n",
" // comment 2\n", " c(y);\n",
" c(y);\n", "\n", // supporting diagnostic
"\n", // supporting diagnostic " d(x);\n",
" d(x);\n", "\n", // context ellipsis
"\n", // context ellipsis // diagnostic group 2
// diagnostic group 2 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "fn main() {\n",
"fn main() {\n", " let x = vec![];\n",
" let x = vec![];\n", "\n", // supporting diagnostic
"\n", // supporting diagnostic " let y = vec![];\n",
" let y = vec![];\n", " a(x);\n",
" a(x);\n", "\n", // supporting diagnostic
"\n", // supporting diagnostic " b(y);\n",
" b(y);\n", "\n", // context ellipsis
"\n", // context ellipsis " c(y);\n",
" c(y);\n", " d(x);\n",
" d(x);\n", "\n", // supporting diagnostic
"\n", // supporting diagnostic "}"
"}" )
) );
);
// Cursor is at the first diagnostic // Cursor is at the first diagnostic
view.editor.update(cx, |editor, cx| { editor.update(cx, |editor, cx| {
assert_eq!( assert_eq!(
editor.selections.display_ranges(cx), editor.selections.display_ranges(cx),
[DisplayPoint::new(12, 6)..DisplayPoint::new(12, 6)] [DisplayPoint::new(12, 6)..DisplayPoint::new(12, 6)]
); );
});
}); });
// Diagnostics are added for another earlier path. // Diagnostics are added for another earlier path.
@ -1138,78 +1137,77 @@ mod tests {
}); });
view.next_notification(cx).await; view.next_notification(cx).await;
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), (7, "path header block".into()),
(7, "path header block".into()), (9, "diagnostic header".into()),
(9, "diagnostic header".into()), (22, "collapsed context".into()),
(22, "collapsed context".into()), (23, "diagnostic header".into()),
(23, "diagnostic header".into()), (32, "collapsed context".into()),
(32, "collapsed context".into()), ]
] );
);
assert_eq!(
view.editor.update(cx, |editor, cx| editor.display_text(cx)),
concat!(
//
// consts.rs
//
"\n", // filename
"\n", // padding
// diagnostic group 1
"\n", // primary message
"\n", // padding
"const a: i32 = 'a';\n",
"\n", // supporting diagnostic
"const b: i32 = c;\n",
//
// main.rs
//
"\n", // filename
"\n", // padding
// diagnostic group 1
"\n", // primary message
"\n", // padding
" let x = vec![];\n",
" let y = vec![];\n",
"\n", // supporting diagnostic
" a(x);\n",
" b(y);\n",
"\n", // supporting diagnostic
" // comment 1\n",
" // comment 2\n",
" c(y);\n",
"\n", // supporting diagnostic
" d(x);\n",
"\n", // collapsed context
// diagnostic group 2
"\n", // primary message
"\n", // filename
"fn main() {\n",
" let x = vec![];\n",
"\n", // supporting diagnostic
" let y = vec![];\n",
" a(x);\n",
"\n", // supporting diagnostic
" b(y);\n",
"\n", // context ellipsis
" c(y);\n",
" d(x);\n",
"\n", // supporting diagnostic
"}"
)
);
// Cursor keeps its position. assert_eq!(
view.editor.update(cx, |editor, cx| { editor.update(cx, |editor, cx| editor.display_text(cx)),
assert_eq!( concat!(
editor.selections.display_ranges(cx), //
[DisplayPoint::new(19, 6)..DisplayPoint::new(19, 6)] // consts.rs
); //
}); "\n", // filename
"\n", // padding
// diagnostic group 1
"\n", // primary message
"\n", // padding
"const a: i32 = 'a';\n",
"\n", // supporting diagnostic
"const b: i32 = c;\n",
//
// main.rs
//
"\n", // filename
"\n", // padding
// diagnostic group 1
"\n", // primary message
"\n", // padding
" let x = vec![];\n",
" let y = vec![];\n",
"\n", // supporting diagnostic
" a(x);\n",
" b(y);\n",
"\n", // supporting diagnostic
" // comment 1\n",
" // comment 2\n",
" c(y);\n",
"\n", // supporting diagnostic
" d(x);\n",
"\n", // collapsed context
// diagnostic group 2
"\n", // primary message
"\n", // filename
"fn main() {\n",
" let x = vec![];\n",
"\n", // supporting diagnostic
" let y = vec![];\n",
" a(x);\n",
"\n", // supporting diagnostic
" b(y);\n",
"\n", // context ellipsis
" c(y);\n",
" d(x);\n",
"\n", // supporting diagnostic
"}"
)
);
// Cursor keeps its position.
editor.update(cx, |editor, cx| {
assert_eq!(
editor.selections.display_ranges(cx),
[DisplayPoint::new(19, 6)..DisplayPoint::new(19, 6)]
);
}); });
// Diagnostics are added to the first path // Diagnostics are added to the first path
@ -1254,80 +1252,79 @@ mod tests {
}); });
view.next_notification(cx).await; view.next_notification(cx).await;
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), (7, "collapsed context".into()),
(7, "collapsed context".into()), (8, "diagnostic header".into()),
(8, "diagnostic header".into()), (13, "path header block".into()),
(13, "path header block".into()), (15, "diagnostic header".into()),
(15, "diagnostic header".into()), (28, "collapsed context".into()),
(28, "collapsed context".into()), (29, "diagnostic header".into()),
(29, "diagnostic header".into()), (38, "collapsed context".into()),
(38, "collapsed context".into()), ]
] );
);
assert_eq!( assert_eq!(
view.editor.update(cx, |editor, cx| editor.display_text(cx)), editor.update(cx, |editor, cx| editor.display_text(cx)),
concat!( concat!(
// //
// consts.rs // consts.rs
// //
"\n", // filename "\n", // filename
"\n", // padding "\n", // padding
// diagnostic group 1 // diagnostic group 1
"\n", // primary message "\n", // primary message
"\n", // padding "\n", // padding
"const a: i32 = 'a';\n", "const a: i32 = 'a';\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
"const b: i32 = c;\n", "const b: i32 = c;\n",
"\n", // context ellipsis "\n", // context ellipsis
// diagnostic group 2 // diagnostic group 2
"\n", // primary message "\n", // primary message
"\n", // padding "\n", // padding
"const a: i32 = 'a';\n", "const a: i32 = 'a';\n",
"const b: i32 = c;\n", "const b: i32 = c;\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
// //
// main.rs // main.rs
// //
"\n", // filename "\n", // filename
"\n", // padding "\n", // padding
// diagnostic group 1 // diagnostic group 1
"\n", // primary message "\n", // primary message
"\n", // padding "\n", // padding
" let x = vec![];\n", " let x = vec![];\n",
" let y = vec![];\n", " let y = vec![];\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
" a(x);\n", " a(x);\n",
" b(y);\n", " b(y);\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
" // comment 1\n", " // comment 1\n",
" // comment 2\n", " // comment 2\n",
" c(y);\n", " c(y);\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
" d(x);\n", " d(x);\n",
"\n", // context ellipsis "\n", // context ellipsis
// diagnostic group 2 // diagnostic group 2
"\n", // primary message "\n", // primary message
"\n", // filename "\n", // filename
"fn main() {\n", "fn main() {\n",
" let x = vec![];\n", " let x = vec![];\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
" let y = vec![];\n", " let y = vec![];\n",
" a(x);\n", " a(x);\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
" b(y);\n", " b(y);\n",
"\n", // context ellipsis "\n", // context ellipsis
" c(y);\n", " c(y);\n",
" d(x);\n", " d(x);\n",
"\n", // supporting diagnostic "\n", // supporting diagnostic
"}" "}"
) )
); );
});
} }
#[gpui::test] #[gpui::test]
@ -1364,6 +1361,7 @@ mod tests {
cx, cx,
) )
}); });
let editor = view.update(cx, |view, _| view.editor.clone());
// Two language servers start updating diagnostics // Two language servers start updating diagnostics
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
@ -1397,27 +1395,25 @@ mod tests {
// Only the first language server's diagnostics are shown. // Only the first language server's diagnostics are shown.
cx.executor().run_until_parked(); cx.executor().run_until_parked();
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), ]
] );
); assert_eq!(
assert_eq!( editor.update(cx, |editor, cx| editor.display_text(cx)),
view.editor.update(cx, |editor, cx| editor.display_text(cx)), concat!(
concat!( "\n", // filename
"\n", // filename "\n", // padding
"\n", // padding // diagnostic group 1
// diagnostic group 1 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "a();\n", //
"a();\n", // "b();",
"b();", )
) );
);
});
// The second language server finishes // The second language server finishes
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
@ -1445,36 +1441,34 @@ mod tests {
// Both language server's diagnostics are shown. // Both language server's diagnostics are shown.
cx.executor().run_until_parked(); cx.executor().run_until_parked();
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), (6, "collapsed context".into()),
(6, "collapsed context".into()), (7, "diagnostic header".into()),
(7, "diagnostic header".into()), ]
] );
); assert_eq!(
assert_eq!( editor.update(cx, |editor, cx| editor.display_text(cx)),
view.editor.update(cx, |editor, cx| editor.display_text(cx)), concat!(
concat!( "\n", // filename
"\n", // filename "\n", // padding
"\n", // padding // diagnostic group 1
// diagnostic group 1 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "a();\n", // location
"a();\n", // location "b();\n", //
"b();\n", // "\n", // collapsed context
"\n", // collapsed context // diagnostic group 2
// diagnostic group 2 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "a();\n", // context
"a();\n", // context "b();\n", //
"b();\n", // "c();", // context
"c();", // context )
) );
);
});
// Both language servers start updating diagnostics, and the first server finishes. // Both language servers start updating diagnostics, and the first server finishes.
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
@ -1513,37 +1507,35 @@ mod tests {
// Only the first language server's diagnostics are updated. // Only the first language server's diagnostics are updated.
cx.executor().run_until_parked(); cx.executor().run_until_parked();
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), (7, "collapsed context".into()),
(7, "collapsed context".into()), (8, "diagnostic header".into()),
(8, "diagnostic header".into()), ]
] );
); assert_eq!(
assert_eq!( editor.update(cx, |editor, cx| editor.display_text(cx)),
view.editor.update(cx, |editor, cx| editor.display_text(cx)), concat!(
concat!( "\n", // filename
"\n", // filename "\n", // padding
"\n", // padding // diagnostic group 1
// diagnostic group 1 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "a();\n", // location
"a();\n", // location "b();\n", //
"b();\n", // "c();\n", // context
"c();\n", // context "\n", // collapsed context
"\n", // collapsed context // diagnostic group 2
// diagnostic group 2 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "b();\n", // context
"b();\n", // context "c();\n", //
"c();\n", // "d();", // context
"d();", // context )
) );
);
});
// The second language server finishes. // The second language server finishes.
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
@ -1571,37 +1563,35 @@ mod tests {
// Both language servers' diagnostics are updated. // Both language servers' diagnostics are updated.
cx.executor().run_until_parked(); cx.executor().run_until_parked();
view.update(cx, |view, cx| { assert_eq!(
assert_eq!( editor_blocks(&editor, cx),
editor_blocks(&view.editor, cx), [
[ (0, "path header block".into()),
(0, "path header block".into()), (2, "diagnostic header".into()),
(2, "diagnostic header".into()), (7, "collapsed context".into()),
(7, "collapsed context".into()), (8, "diagnostic header".into()),
(8, "diagnostic header".into()), ]
] );
); assert_eq!(
assert_eq!( editor.update(cx, |editor, cx| editor.display_text(cx)),
view.editor.update(cx, |editor, cx| editor.display_text(cx)), concat!(
concat!( "\n", // filename
"\n", // filename "\n", // padding
"\n", // padding // diagnostic group 1
// diagnostic group 1 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "b();\n", // location
"b();\n", // location "c();\n", //
"c();\n", // "d();\n", // context
"d();\n", // context "\n", // collapsed context
"\n", // collapsed context // diagnostic group 2
// diagnostic group 2 "\n", // primary message
"\n", // primary message "\n", // padding
"\n", // padding "c();\n", // context
"c();\n", // context "d();\n", //
"d();\n", // "e();", // context
"e();", // context )
) );
);
});
} }
fn init_test(cx: &mut TestAppContext) { fn init_test(cx: &mut TestAppContext) {
@ -1618,45 +1608,58 @@ mod tests {
}); });
} }
fn editor_blocks(editor: &View<Editor>, cx: &mut WindowContext) -> Vec<(u32, SharedString)> { fn editor_blocks(
editor.update(cx, |editor, cx| { editor: &View<Editor>,
let snapshot = editor.snapshot(cx); cx: &mut VisualTestContext,
snapshot ) -> Vec<(u32, SharedString)> {
.blocks_in_range(0..snapshot.max_point().row()) let mut blocks = Vec::new();
.enumerate() cx.draw(gpui::Point::default(), AvailableSpace::min_size(), |cx| {
.filter_map(|(ix, (row, block))| { editor.update(cx, |editor, cx| {
let name: SharedString = match block { let snapshot = editor.snapshot(cx);
TransformBlock::Custom(block) => cx.with_element_context({ blocks.extend(
|cx| -> Option<SharedString> { snapshot
let mut element = block.render(&mut BlockContext { .blocks_in_range(0..snapshot.max_point().row())
context: cx, .enumerate()
anchor_x: px(0.), .filter_map(|(ix, (row, block))| {
gutter_dimensions: &GutterDimensions::default(), let name: SharedString = match block {
line_height: px(0.), TransformBlock::Custom(block) => {
em_width: px(0.), let mut element = block.render(&mut BlockContext {
max_width: px(0.), context: cx,
block_id: ix, anchor_x: px(0.),
editor_style: &editor::EditorStyle::default(), gutter_dimensions: &GutterDimensions::default(),
}); line_height: px(0.),
let element = element.downcast_mut::<Stateful<Div>>().unwrap(); em_width: px(0.),
element.interactivity().element_id.clone()?.try_into().ok() max_width: px(0.),
} block_id: ix,
})?, editor_style: &editor::EditorStyle::default(),
});
let element = element.downcast_mut::<Stateful<Div>>().unwrap();
element
.interactivity()
.element_id
.clone()?
.try_into()
.ok()?
}
TransformBlock::ExcerptHeader { TransformBlock::ExcerptHeader {
starts_new_buffer, .. starts_new_buffer, ..
} => { } => {
if *starts_new_buffer { if *starts_new_buffer {
"path header block".into() "path header block".into()
} else { } else {
"collapsed context".into() "collapsed context".into()
} }
} }
}; };
Some((row, name)) Some((row, name))
}) }),
.collect() )
}) });
div().into_any()
});
blocks
} }
} }

View File

@ -39,17 +39,15 @@ impl<'a> CommitAvatar<'a> {
let avatar_url = CommitAvatarAsset::new(remote.clone(), self.sha); let avatar_url = CommitAvatarAsset::new(remote.clone(), self.sha);
let element = cx.with_element_context(|cx| { let element = match cx.use_cached_asset::<CommitAvatarAsset>(&avatar_url) {
match cx.use_cached_asset::<CommitAvatarAsset>(&avatar_url) { // Loading or no avatar found
// Loading or no avatar found None | Some(None) => Icon::new(IconName::Person)
None | Some(None) => Icon::new(IconName::Person) .color(Color::Muted)
.color(Color::Muted) .into_element()
.into_element() .into_any(),
.into_any(), // Found
// Found Some(Some(url)) => Avatar::new(url.to_string()).into_element().into_any(),
Some(Some(url)) => Avatar::new(url.to_string()).into_element().into_any(), };
}
});
Some(element) Some(element)
} }
} }

View File

@ -4,7 +4,7 @@ use super::{
}; };
use crate::{EditorStyle, GutterDimensions}; use crate::{EditorStyle, GutterDimensions};
use collections::{Bound, HashMap, HashSet}; use collections::{Bound, HashMap, HashSet};
use gpui::{AnyElement, ElementContext, Pixels}; use gpui::{AnyElement, Pixels, WindowContext};
use language::{BufferSnapshot, Chunk, Patch, Point}; use language::{BufferSnapshot, Chunk, Patch, Point};
use multi_buffer::{Anchor, ExcerptId, ExcerptRange, ToPoint as _}; use multi_buffer::{Anchor, ExcerptId, ExcerptRange, ToPoint as _};
use parking_lot::Mutex; use parking_lot::Mutex;
@ -82,7 +82,7 @@ pub enum BlockStyle {
} }
pub struct BlockContext<'a, 'b> { pub struct BlockContext<'a, 'b> {
pub context: &'b mut ElementContext<'a>, pub context: &'b mut WindowContext<'a>,
pub anchor_x: Pixels, pub anchor_x: Pixels,
pub max_width: Pixels, pub max_width: Pixels,
pub gutter_dimensions: &'b GutterDimensions, pub gutter_dimensions: &'b GutterDimensions,
@ -934,7 +934,7 @@ impl BlockDisposition {
} }
impl<'a> Deref for BlockContext<'a, '_> { impl<'a> Deref for BlockContext<'a, '_> {
type Target = ElementContext<'a>; type Target = WindowContext<'a>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.context self.context

View File

@ -23,12 +23,11 @@ use git::{blame::BlameEntry, diff::DiffHunkStatus, Oid};
use gpui::{ use gpui::{
anchored, deferred, div, fill, outline, point, px, quad, relative, size, svg, anchored, deferred, div, fill, outline, point, px, quad, relative, size, svg,
transparent_black, Action, AnchorCorner, AnyElement, AvailableSpace, Bounds, ClipboardItem, transparent_black, Action, AnchorCorner, AnyElement, AvailableSpace, Bounds, ClipboardItem,
ContentMask, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementContext, ContentMask, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Hitbox,
ElementInputHandler, Entity, Hitbox, Hsla, InteractiveElement, IntoElement, Hsla, InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton, MouseDownEvent,
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent,
ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size, Stateful, ShapedLine, SharedString, Size, Stateful, StatefulInteractiveElement, Style, Styled, TextRun,
StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, TextStyleRefinement, View, TextStyle, TextStyleRefinement, View, ViewContext, WeakView, WindowContext,
ViewContext, WeakView, WindowContext,
}; };
use itertools::Itertools; use itertools::Itertools;
use language::language_settings::ShowWhitespaceSetting; use language::language_settings::ShowWhitespaceSetting;
@ -367,7 +366,7 @@ impl EditorElement {
register_action(view, cx, Editor::open_active_item_in_terminal) register_action(view, cx, Editor::open_active_item_in_terminal)
} }
fn register_key_listeners(&self, cx: &mut ElementContext, layout: &EditorLayout) { fn register_key_listeners(&self, cx: &mut WindowContext, layout: &EditorLayout) {
let position_map = layout.position_map.clone(); let position_map = layout.position_map.clone();
cx.on_key_event({ cx.on_key_event({
let editor = self.editor.clone(); let editor = self.editor.clone();
@ -691,7 +690,7 @@ impl EditorElement {
snapshot: &EditorSnapshot, snapshot: &EditorSnapshot,
start_row: u32, start_row: u32,
end_row: u32, end_row: u32,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> ( ) -> (
Vec<(PlayerColor, Vec<SelectionLayout>)>, Vec<(PlayerColor, Vec<SelectionLayout>)>,
BTreeMap<u32, bool>, BTreeMap<u32, bool>,
@ -819,7 +818,7 @@ impl EditorElement {
scroll_pixel_position: gpui::Point<Pixels>, scroll_pixel_position: gpui::Point<Pixels>,
line_height: Pixels, line_height: Pixels,
line_layouts: &[LineWithInvisibles], line_layouts: &[LineWithInvisibles],
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Vec<FoldLayout> { ) -> Vec<FoldLayout> {
snapshot snapshot
.folds_in_range(visible_anchor_range.clone()) .folds_in_range(visible_anchor_range.clone())
@ -887,7 +886,7 @@ impl EditorElement {
line_height: Pixels, line_height: Pixels,
em_width: Pixels, em_width: Pixels,
autoscroll_containing_element: bool, autoscroll_containing_element: bool,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Vec<CursorLayout> { ) -> Vec<CursorLayout> {
let mut autoscroll_bounds = None; let mut autoscroll_bounds = None;
let cursor_layouts = self.editor.update(cx, |editor, cx| { let cursor_layouts = self.editor.update(cx, |editor, cx| {
@ -993,7 +992,7 @@ impl EditorElement {
color: self.style.background, color: self.style.background,
is_top_row: cursor_position.row() == 0, is_top_row: cursor_position.row() == 0,
}); });
cx.with_element_context(|cx| cursor.layout(content_origin, cursor_name, cx)); cursor.layout(content_origin, cursor_name, cx);
cursors.push(cursor); cursors.push(cursor);
} }
} }
@ -1013,7 +1012,7 @@ impl EditorElement {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
scroll_position: gpui::Point<f32>, scroll_position: gpui::Point<f32>,
rows_per_page: f32, rows_per_page: f32,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<ScrollbarLayout> { ) -> Option<ScrollbarLayout> {
let scrollbar_settings = EditorSettings::get_global(cx).scrollbar; let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
let show_scrollbars = match scrollbar_settings.show { let show_scrollbars = match scrollbar_settings.show {
@ -1082,7 +1081,7 @@ impl EditorElement {
gutter_settings: crate::editor_settings::Gutter, gutter_settings: crate::editor_settings::Gutter,
scroll_pixel_position: gpui::Point<Pixels>, scroll_pixel_position: gpui::Point<Pixels>,
gutter_hitbox: &Hitbox, gutter_hitbox: &Hitbox,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Vec<Option<AnyElement>> { ) -> Vec<Option<AnyElement>> {
let mut indicators = self.editor.update(cx, |editor, cx| { let mut indicators = self.editor.update(cx, |editor, cx| {
editor.render_fold_indicators( editor.render_fold_indicators(
@ -1155,7 +1154,7 @@ impl EditorElement {
content_origin: gpui::Point<Pixels>, content_origin: gpui::Point<Pixels>,
scroll_pixel_position: gpui::Point<Pixels>, scroll_pixel_position: gpui::Point<Pixels>,
line_height: Pixels, line_height: Pixels,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<AnyElement> { ) -> Option<AnyElement> {
if !self if !self
.editor .editor
@ -1220,7 +1219,7 @@ impl EditorElement {
line_height: Pixels, line_height: Pixels,
gutter_hitbox: &Hitbox, gutter_hitbox: &Hitbox,
max_width: Option<Pixels>, max_width: Option<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<Vec<AnyElement>> { ) -> Option<Vec<AnyElement>> {
if !self if !self
.editor .editor
@ -1285,7 +1284,7 @@ impl EditorElement {
scroll_pixel_position: gpui::Point<Pixels>, scroll_pixel_position: gpui::Point<Pixels>,
gutter_dimensions: &GutterDimensions, gutter_dimensions: &GutterDimensions,
gutter_hitbox: &Hitbox, gutter_hitbox: &Hitbox,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<AnyElement> { ) -> Option<AnyElement> {
let mut active = false; let mut active = false;
let mut button = None; let mut button = None;
@ -1372,7 +1371,7 @@ impl EditorElement {
active_rows: &BTreeMap<u32, bool>, active_rows: &BTreeMap<u32, bool>,
newest_selection_head: Option<DisplayPoint>, newest_selection_head: Option<DisplayPoint>,
snapshot: &EditorSnapshot, snapshot: &EditorSnapshot,
cx: &ElementContext, cx: &WindowContext,
) -> ( ) -> (
Vec<Option<ShapedLine>>, Vec<Option<ShapedLine>>,
Vec<Option<(FoldStatus, BufferRow, bool)>>, Vec<Option<(FoldStatus, BufferRow, bool)>>,
@ -1465,7 +1464,7 @@ impl EditorElement {
rows: Range<u32>, rows: Range<u32>,
line_number_layouts: &[Option<ShapedLine>], line_number_layouts: &[Option<ShapedLine>],
snapshot: &EditorSnapshot, snapshot: &EditorSnapshot,
cx: &ElementContext, cx: &WindowContext,
) -> Vec<LineWithInvisibles> { ) -> Vec<LineWithInvisibles> {
if rows.start >= rows.end { if rows.start >= rows.end {
return Vec::new(); return Vec::new();
@ -1530,7 +1529,7 @@ impl EditorElement {
text_x: Pixels, text_x: Pixels,
line_height: Pixels, line_height: Pixels,
line_layouts: &[LineWithInvisibles], line_layouts: &[LineWithInvisibles],
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Vec<BlockLayout> { ) -> Vec<BlockLayout> {
let mut block_id = 0; let mut block_id = 0;
let (fixed_blocks, non_fixed_blocks) = snapshot let (fixed_blocks, non_fixed_blocks) = snapshot
@ -1544,7 +1543,7 @@ impl EditorElement {
available_space: Size<AvailableSpace>, available_space: Size<AvailableSpace>,
block_id: usize, block_id: usize,
block_row_start: u32, block_row_start: u32,
cx: &mut ElementContext| { cx: &mut WindowContext| {
let mut element = match block { let mut element = match block {
TransformBlock::Custom(block) => { TransformBlock::Custom(block) => {
let align_to = block let align_to = block
@ -1865,7 +1864,7 @@ impl EditorElement {
hitbox: &Hitbox, hitbox: &Hitbox,
line_height: Pixels, line_height: Pixels,
scroll_pixel_position: gpui::Point<Pixels>, scroll_pixel_position: gpui::Point<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
for block in blocks { for block in blocks {
let mut origin = hitbox.origin let mut origin = hitbox.origin
@ -1893,7 +1892,7 @@ impl EditorElement {
scroll_pixel_position: gpui::Point<Pixels>, scroll_pixel_position: gpui::Point<Pixels>,
line_layouts: &[LineWithInvisibles], line_layouts: &[LineWithInvisibles],
newest_selection_head: DisplayPoint, newest_selection_head: DisplayPoint,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> bool { ) -> bool {
let max_height = cmp::min( let max_height = cmp::min(
12. * line_height, 12. * line_height,
@ -1933,7 +1932,7 @@ impl EditorElement {
true true
} }
fn layout_mouse_context_menu(&self, cx: &mut ElementContext) -> Option<AnyElement> { fn layout_mouse_context_menu(&self, cx: &mut WindowContext) -> Option<AnyElement> {
let mouse_context_menu = self.editor.read(cx).mouse_context_menu.as_ref()?; let mouse_context_menu = self.editor.read(cx).mouse_context_menu.as_ref()?;
let mut element = deferred( let mut element = deferred(
anchored() anchored()
@ -1961,7 +1960,7 @@ impl EditorElement {
line_layouts: &[LineWithInvisibles], line_layouts: &[LineWithInvisibles],
line_height: Pixels, line_height: Pixels,
em_width: Pixels, em_width: Pixels,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
struct MeasuredHoverPopover { struct MeasuredHoverPopover {
element: AnyElement, element: AnyElement,
@ -2021,7 +2020,7 @@ impl EditorElement {
} }
overall_height += HOVER_POPOVER_GAP; overall_height += HOVER_POPOVER_GAP;
fn draw_occluder(width: Pixels, origin: gpui::Point<Pixels>, cx: &mut ElementContext) { fn draw_occluder(width: Pixels, origin: gpui::Point<Pixels>, cx: &mut WindowContext) {
let mut occlusion = div() let mut occlusion = div()
.size_full() .size_full()
.occlude() .occlude()
@ -2067,7 +2066,7 @@ impl EditorElement {
} }
} }
fn paint_background(&self, layout: &EditorLayout, cx: &mut ElementContext) { fn paint_background(&self, layout: &EditorLayout, cx: &mut WindowContext) {
cx.paint_layer(layout.hitbox.bounds, |cx| { cx.paint_layer(layout.hitbox.bounds, |cx| {
let scroll_top = layout.position_map.snapshot.scroll_position().y; let scroll_top = layout.position_map.snapshot.scroll_position().y;
let gutter_bg = cx.theme().colors().editor_gutter_background; let gutter_bg = cx.theme().colors().editor_gutter_background;
@ -2188,7 +2187,7 @@ impl EditorElement {
}) })
} }
fn paint_gutter(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_gutter(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
let line_height = layout.position_map.line_height; let line_height = layout.position_map.line_height;
let scroll_position = layout.position_map.snapshot.scroll_position(); let scroll_position = layout.position_map.snapshot.scroll_position();
@ -2236,7 +2235,7 @@ impl EditorElement {
}) })
} }
fn paint_diff_hunks(layout: &EditorLayout, cx: &mut ElementContext) { fn paint_diff_hunks(layout: &EditorLayout, cx: &mut WindowContext) {
if layout.display_hunks.is_empty() { if layout.display_hunks.is_empty() {
return; return;
} }
@ -2342,7 +2341,7 @@ impl EditorElement {
}) })
} }
fn paint_blamed_display_rows(&self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_blamed_display_rows(&self, layout: &mut EditorLayout, cx: &mut WindowContext) {
let Some(blamed_display_rows) = layout.blamed_display_rows.take() else { let Some(blamed_display_rows) = layout.blamed_display_rows.take() else {
return; return;
}; };
@ -2354,7 +2353,7 @@ impl EditorElement {
}) })
} }
fn paint_text(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_text(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
cx.with_content_mask( cx.with_content_mask(
Some(ContentMask { Some(ContentMask {
bounds: layout.text_hitbox.bounds, bounds: layout.text_hitbox.bounds,
@ -2386,7 +2385,7 @@ impl EditorElement {
fn paint_highlights( fn paint_highlights(
&mut self, &mut self,
layout: &mut EditorLayout, layout: &mut EditorLayout,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> SmallVec<[Range<DisplayPoint>; 32]> { ) -> SmallVec<[Range<DisplayPoint>; 32]> {
cx.paint_layer(layout.text_hitbox.bounds, |cx| { cx.paint_layer(layout.text_hitbox.bounds, |cx| {
let mut invisible_display_ranges = SmallVec::<[Range<DisplayPoint>; 32]>::new(); let mut invisible_display_ranges = SmallVec::<[Range<DisplayPoint>; 32]>::new();
@ -2428,7 +2427,7 @@ impl EditorElement {
&mut self, &mut self,
invisible_display_ranges: &[Range<DisplayPoint>], invisible_display_ranges: &[Range<DisplayPoint>],
layout: &EditorLayout, layout: &EditorLayout,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let whitespace_setting = self let whitespace_setting = self
.editor .editor
@ -2451,7 +2450,7 @@ impl EditorElement {
} }
} }
fn paint_redactions(&mut self, layout: &EditorLayout, cx: &mut ElementContext) { fn paint_redactions(&mut self, layout: &EditorLayout, cx: &mut WindowContext) {
if layout.redacted_ranges.is_empty() { if layout.redacted_ranges.is_empty() {
return; return;
} }
@ -2475,13 +2474,13 @@ impl EditorElement {
}); });
} }
fn paint_cursors(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_cursors(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
for cursor in &mut layout.cursors { for cursor in &mut layout.cursors {
cursor.paint(layout.content_origin, cx); cursor.paint(layout.content_origin, cx);
} }
} }
fn paint_scrollbar(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_scrollbar(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
let Some(scrollbar_layout) = layout.scrollbar_layout.as_ref() else { let Some(scrollbar_layout) = layout.scrollbar_layout.as_ref() else {
return; return;
}; };
@ -2617,7 +2616,7 @@ impl EditorElement {
&self, &self,
layout: &EditorLayout, layout: &EditorLayout,
scrollbar_layout: &ScrollbarLayout, scrollbar_layout: &ScrollbarLayout,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.editor.update(cx, |editor, cx| { self.editor.update(cx, |editor, cx| {
if !editor.is_singleton(cx) if !editor.is_singleton(cx)
@ -2775,7 +2774,7 @@ impl EditorElement {
corner_radius: Pixels, corner_radius: Pixels,
line_end_overshoot: Pixels, line_end_overshoot: Pixels,
layout: &EditorLayout, layout: &EditorLayout,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let start_row = layout.visible_display_row_range.start; let start_row = layout.visible_display_row_range.start;
let end_row = layout.visible_display_row_range.end; let end_row = layout.visible_display_row_range.end;
@ -2824,7 +2823,7 @@ impl EditorElement {
} }
} }
fn paint_folds(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_folds(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
if layout.folds.is_empty() { if layout.folds.is_empty() {
return; return;
} }
@ -2855,7 +2854,7 @@ impl EditorElement {
}) })
} }
fn paint_inline_blame(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_inline_blame(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
if let Some(mut inline_blame) = layout.inline_blame.take() { if let Some(mut inline_blame) = layout.inline_blame.take() {
cx.paint_layer(layout.text_hitbox.bounds, |cx| { cx.paint_layer(layout.text_hitbox.bounds, |cx| {
inline_blame.paint(cx); inline_blame.paint(cx);
@ -2863,19 +2862,19 @@ impl EditorElement {
} }
} }
fn paint_blocks(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_blocks(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
for mut block in layout.blocks.drain(..) { for mut block in layout.blocks.drain(..) {
block.element.paint(cx); block.element.paint(cx);
} }
} }
fn paint_mouse_context_menu(&mut self, layout: &mut EditorLayout, cx: &mut ElementContext) { fn paint_mouse_context_menu(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
if let Some(mouse_context_menu) = layout.mouse_context_menu.as_mut() { if let Some(mouse_context_menu) = layout.mouse_context_menu.as_mut() {
mouse_context_menu.paint(cx); mouse_context_menu.paint(cx);
} }
} }
fn paint_scroll_wheel_listener(&mut self, layout: &EditorLayout, cx: &mut ElementContext) { fn paint_scroll_wheel_listener(&mut self, layout: &EditorLayout, cx: &mut WindowContext) {
cx.on_mouse_event({ cx.on_mouse_event({
let position_map = layout.position_map.clone(); let position_map = layout.position_map.clone();
let editor = self.editor.clone(); let editor = self.editor.clone();
@ -2925,7 +2924,7 @@ impl EditorElement {
}); });
} }
fn paint_mouse_listeners(&mut self, layout: &EditorLayout, cx: &mut ElementContext) { fn paint_mouse_listeners(&mut self, layout: &EditorLayout, cx: &mut WindowContext) {
self.paint_scroll_wheel_listener(layout, cx); self.paint_scroll_wheel_listener(layout, cx);
cx.on_mouse_event({ cx.on_mouse_event({
@ -3042,7 +3041,7 @@ fn render_inline_blame_entry(
blame_entry: BlameEntry, blame_entry: BlameEntry,
style: &EditorStyle, style: &EditorStyle,
workspace: Option<WeakView<Workspace>>, workspace: Option<WeakView<Workspace>>,
cx: &mut ElementContext<'_>, cx: &mut WindowContext<'_>,
) -> AnyElement { ) -> AnyElement {
let relative_timestamp = blame_entry_relative_timestamp(&blame_entry, cx); let relative_timestamp = blame_entry_relative_timestamp(&blame_entry, cx);
@ -3073,7 +3072,7 @@ fn render_blame_entry(
style: &EditorStyle, style: &EditorStyle,
last_used_color: &mut Option<(PlayerColor, Oid)>, last_used_color: &mut Option<(PlayerColor, Oid)>,
editor: View<Editor>, editor: View<Editor>,
cx: &mut ElementContext<'_>, cx: &mut WindowContext<'_>,
) -> AnyElement { ) -> AnyElement {
let mut sha_color = cx let mut sha_color = cx
.theme() .theme()
@ -3286,7 +3285,7 @@ impl LineWithInvisibles {
content_origin: gpui::Point<Pixels>, content_origin: gpui::Point<Pixels>,
whitespace_setting: ShowWhitespaceSetting, whitespace_setting: ShowWhitespaceSetting,
selection_ranges: &[Range<DisplayPoint>], selection_ranges: &[Range<DisplayPoint>],
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let line_height = layout.position_map.line_height; let line_height = layout.position_map.line_height;
let line_y = let line_y =
@ -3318,7 +3317,7 @@ impl LineWithInvisibles {
row: u32, row: u32,
line_height: Pixels, line_height: Pixels,
whitespace_setting: ShowWhitespaceSetting, whitespace_setting: ShowWhitespaceSetting,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let allowed_invisibles_regions = match whitespace_setting { let allowed_invisibles_regions = match whitespace_setting {
ShowWhitespaceSetting::None => return, ShowWhitespaceSetting::None => return,
@ -3365,7 +3364,7 @@ impl Element for EditorElement {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = EditorLayout; type PrepaintState = EditorLayout;
fn request_layout(&mut self, cx: &mut ElementContext) -> (gpui::LayoutId, ()) { fn request_layout(&mut self, cx: &mut WindowContext) -> (gpui::LayoutId, ()) {
self.editor.update(cx, |editor, cx| { self.editor.update(cx, |editor, cx| {
editor.set_style(self.style.clone(), cx); editor.set_style(self.style.clone(), cx);
@ -3375,36 +3374,31 @@ impl Element for EditorElement {
let mut style = Style::default(); let mut style = Style::default();
style.size.width = relative(1.).into(); style.size.width = relative(1.).into();
style.size.height = self.style.text.line_height_in_pixels(rem_size).into(); style.size.height = self.style.text.line_height_in_pixels(rem_size).into();
cx.with_element_context(|cx| cx.request_layout(&style, None)) cx.request_layout(&style, None)
} }
EditorMode::AutoHeight { max_lines } => { EditorMode::AutoHeight { max_lines } => {
let editor_handle = cx.view().clone(); let editor_handle = cx.view().clone();
let max_line_number_width = let max_line_number_width =
self.max_line_number_width(&editor.snapshot(cx), cx); self.max_line_number_width(&editor.snapshot(cx), cx);
cx.with_element_context(|cx| { cx.request_measured_layout(Style::default(), move |known_dimensions, _, cx| {
cx.request_measured_layout( editor_handle
Style::default(), .update(cx, |editor, cx| {
move |known_dimensions, _, cx| { compute_auto_height_layout(
editor_handle editor,
.update(cx, |editor, cx| { max_lines,
compute_auto_height_layout( max_line_number_width,
editor, known_dimensions,
max_lines, cx,
max_line_number_width, )
known_dimensions, })
cx, .unwrap_or_default()
)
})
.unwrap_or_default()
},
)
}) })
} }
EditorMode::Full => { EditorMode::Full => {
let mut style = Style::default(); let mut style = Style::default();
style.size.width = relative(1.).into(); style.size.width = relative(1.).into();
style.size.height = relative(1.).into(); style.size.height = relative(1.).into();
cx.with_element_context(|cx| cx.request_layout(&style, None)) cx.request_layout(&style, None)
} }
}; };
@ -3416,7 +3410,7 @@ impl Element for EditorElement {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Self::PrepaintState { ) -> Self::PrepaintState {
let text_style = TextStyleRefinement { let text_style = TextStyleRefinement {
font_size: Some(self.style.text.font_size), font_size: Some(self.style.text.font_size),
@ -3847,13 +3841,12 @@ impl Element for EditorElement {
bounds: Bounds<gpui::Pixels>, bounds: Bounds<gpui::Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
layout: &mut Self::PrepaintState, layout: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let focus_handle = self.editor.focus_handle(cx); let focus_handle = self.editor.focus_handle(cx);
let key_context = self.editor.read(cx).key_context(cx); let key_context = self.editor.read(cx).key_context(cx);
cx.set_focus_handle(&focus_handle); cx.set_focus_handle(&focus_handle);
cx.set_key_context(key_context); cx.set_key_context(key_context);
cx.set_view_id(self.editor.entity_id());
cx.handle_input( cx.handle_input(
&focus_handle, &focus_handle,
ElementInputHandler::new(bounds, self.editor.clone()), ElementInputHandler::new(bounds, self.editor.clone()),
@ -4206,7 +4199,7 @@ impl CursorLayout {
&mut self, &mut self,
origin: gpui::Point<Pixels>, origin: gpui::Point<Pixels>,
cursor_name: Option<CursorName>, cursor_name: Option<CursorName>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
if let Some(cursor_name) = cursor_name { if let Some(cursor_name) = cursor_name {
let bounds = self.bounds(origin); let bounds = self.bounds(origin);
@ -4236,7 +4229,7 @@ impl CursorLayout {
} }
} }
pub fn paint(&mut self, origin: gpui::Point<Pixels>, cx: &mut ElementContext) { pub fn paint(&mut self, origin: gpui::Point<Pixels>, cx: &mut WindowContext) {
let bounds = self.bounds(origin); let bounds = self.bounds(origin);
//Draw background or border quad //Draw background or border quad
@ -4280,7 +4273,7 @@ pub struct HighlightedRangeLine {
} }
impl HighlightedRange { impl HighlightedRange {
pub fn paint(&self, bounds: Bounds<Pixels>, cx: &mut ElementContext) { pub fn paint(&self, bounds: Bounds<Pixels>, cx: &mut WindowContext) {
if self.lines.len() >= 2 && self.lines[0].start_x > self.lines[1].end_x { 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(self.start_y, &self.lines[0..1], bounds, cx);
self.paint_lines( self.paint_lines(
@ -4299,7 +4292,7 @@ impl HighlightedRange {
start_y: Pixels, start_y: Pixels,
lines: &[HighlightedRangeLine], lines: &[HighlightedRangeLine],
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
if lines.is_empty() { if lines.is_empty() {
return; return;
@ -4416,7 +4409,7 @@ mod tests {
editor_tests::{init_test, update_test_language_settings}, editor_tests::{init_test, update_test_language_settings},
Editor, MultiBuffer, Editor, MultiBuffer,
}; };
use gpui::TestAppContext; use gpui::{TestAppContext, VisualTestContext};
use language::language_settings; use language::language_settings;
use log::info; use log::info;
use std::num::NonZeroU32; use std::num::NonZeroU32;
@ -4437,18 +4430,16 @@ mod tests {
let layouts = cx let layouts = cx
.update_window(*window, |_, cx| { .update_window(*window, |_, cx| {
cx.with_element_context(|cx| { element
element .layout_line_numbers(
.layout_line_numbers( 0..6,
0..6, (0..6).map(Some),
(0..6).map(Some), &Default::default(),
&Default::default(), Some(DisplayPoint::new(0, 0)),
Some(DisplayPoint::new(0, 0)), &snapshot,
&snapshot, cx,
cx, )
) .0
.0
})
}) })
.unwrap(); .unwrap();
assert_eq!(layouts.len(), 6); assert_eq!(layouts.len(), 6);
@ -4487,9 +4478,9 @@ mod tests {
let buffer = MultiBuffer::build_simple(&(sample_text(6, 6, 'a') + "\n"), cx); let buffer = MultiBuffer::build_simple(&(sample_text(6, 6, 'a') + "\n"), cx);
Editor::new(EditorMode::Full, buffer, None, cx) Editor::new(EditorMode::Full, buffer, None, cx)
}); });
let cx = &mut VisualTestContext::from_window(*window, cx);
let editor = window.root(cx).unwrap(); let editor = window.root(cx).unwrap();
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone()); let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
let mut element = EditorElement::new(&editor, style);
window window
.update(cx, |editor, cx| { .update(cx, |editor, cx| {
@ -4503,20 +4494,10 @@ mod tests {
}); });
}) })
.unwrap(); .unwrap();
let state = cx
.update_window(window.into(), |_view, cx| { let (_, state) = cx.draw(point(px(500.), px(500.)), size(px(500.), px(500.)), |_| {
cx.with_element_context(|cx| { EditorElement::new(&editor, style)
element.prepaint( });
Bounds {
origin: point(px(500.), px(500.)),
size: size(px(500.), px(500.)),
},
&mut (),
cx,
)
})
})
.unwrap();
assert_eq!(state.selections.len(), 1); assert_eq!(state.selections.len(), 1);
let local_selections = &state.selections[0].1; let local_selections = &state.selections[0].1;
@ -4587,7 +4568,6 @@ mod tests {
}); });
let editor = window.root(cx).unwrap(); let editor = window.root(cx).unwrap();
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone()); let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
let mut element = EditorElement::new(&editor, style);
let _state = window.update(cx, |editor, cx| { let _state = window.update(cx, |editor, cx| {
editor.cursor_shape = CursorShape::Block; editor.cursor_shape = CursorShape::Block;
editor.change_selections(None, cx, |s| { editor.change_selections(None, cx, |s| {
@ -4598,20 +4578,9 @@ mod tests {
}); });
}); });
let state = cx let (_, state) = cx.draw(point(px(500.), px(500.)), size(px(500.), px(500.)), |_| {
.update_window(window.into(), |_view, cx| { EditorElement::new(&editor, style)
cx.with_element_context(|cx| { });
element.prepaint(
Bounds {
origin: point(px(500.), px(500.)),
size: size(px(500.), px(500.)),
},
&mut (),
cx,
)
})
})
.unwrap();
assert_eq!(state.selections.len(), 1); assert_eq!(state.selections.len(), 1);
let local_selections = &state.selections[0].1; let local_selections = &state.selections[0].1;
assert_eq!(local_selections.len(), 2); assert_eq!(local_selections.len(), 2);
@ -4640,6 +4609,7 @@ mod tests {
let buffer = MultiBuffer::build_simple("", cx); let buffer = MultiBuffer::build_simple("", cx);
Editor::new(EditorMode::Full, buffer, None, cx) Editor::new(EditorMode::Full, buffer, None, cx)
}); });
let cx = &mut VisualTestContext::from_window(*window, cx);
let editor = window.root(cx).unwrap(); let editor = window.root(cx).unwrap();
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone()); let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
window window
@ -4662,22 +4632,9 @@ mod tests {
}) })
.unwrap(); .unwrap();
let mut element = EditorElement::new(&editor, style); let (_, state) = cx.draw(point(px(500.), px(500.)), size(px(500.), px(500.)), |_| {
let state = cx EditorElement::new(&editor, style)
.update_window(window.into(), |_view, cx| { });
cx.with_element_context(|cx| {
element.prepaint(
Bounds {
origin: point(px(500.), px(500.)),
size: size(px(500.), px(500.)),
},
&mut (),
cx,
)
})
})
.unwrap();
assert_eq!(state.position_map.line_layouts.len(), 4); assert_eq!(state.position_map.line_layouts.len(), 4);
assert_eq!( assert_eq!(
state state
@ -4850,31 +4807,19 @@ mod tests {
let buffer = MultiBuffer::build_simple(&input_text, cx); let buffer = MultiBuffer::build_simple(&input_text, cx);
Editor::new(editor_mode, buffer, None, cx) Editor::new(editor_mode, buffer, None, cx)
}); });
let cx = &mut VisualTestContext::from_window(*window, cx);
let editor = window.root(cx).unwrap(); let editor = window.root(cx).unwrap();
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone()); let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
let mut element = EditorElement::new(&editor, style);
window window
.update(cx, |editor, cx| { .update(cx, |editor, cx| {
editor.set_soft_wrap_mode(language_settings::SoftWrap::EditorWidth, cx); editor.set_soft_wrap_mode(language_settings::SoftWrap::EditorWidth, cx);
editor.set_wrap_width(Some(editor_width), cx); editor.set_wrap_width(Some(editor_width), cx);
}) })
.unwrap(); .unwrap();
let layout_state = cx let (_, state) = cx.draw(point(px(500.), px(500.)), size(px(500.), px(500.)), |_| {
.update_window(window.into(), |_, cx| { EditorElement::new(&editor, style)
cx.with_element_context(|cx| { });
element.prepaint( state
Bounds {
origin: point(px(500.), px(500.)),
size: size(px(500.), px(500.)),
},
&mut (),
cx,
)
})
})
.unwrap();
layout_state
.position_map .position_map
.line_layouts .line_layouts
.iter() .iter()

View File

@ -1,10 +1,11 @@
use crate::{ use crate::{
Action, AnyElement, AnyView, AnyWindowHandle, AppCell, AppContext, AsyncAppContext, Action, AnyView, AnyWindowHandle, AppCell, AppContext, AsyncAppContext, AvailableSpace,
AvailableSpace, BackgroundExecutor, BorrowAppContext, Bounds, ClipboardItem, Context, Empty, BackgroundExecutor, BorrowAppContext, Bounds, ClipboardItem, Context, DrawPhase, Drawable,
Entity, EventEmitter, ForegroundExecutor, Global, InputEvent, Keystroke, Model, ModelContext, Element, Empty, Entity, EventEmitter, ForegroundExecutor, Global, InputEvent, Keystroke, Model,
Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ModelContext, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent,
Pixels, Platform, Point, Render, Result, Size, Task, TestDispatcher, TestPlatform, TestWindow, MouseUpEvent, Pixels, Platform, Point, Render, Result, Size, Task, TestDispatcher,
TextSystem, View, ViewContext, VisualContext, WindowContext, WindowHandle, WindowOptions, TestPlatform, TestWindow, TextSystem, View, ViewContext, VisualContext, WindowContext,
WindowHandle, WindowOptions,
}; };
use anyhow::{anyhow, bail}; use anyhow::{anyhow, bail};
use futures::{channel::oneshot, Stream, StreamExt}; use futures::{channel::oneshot, Stream, StreamExt};
@ -725,21 +726,28 @@ impl VisualTestContext {
} }
/// Draw an element to the window. Useful for simulating events or actions /// Draw an element to the window. Useful for simulating events or actions
pub fn draw( pub fn draw<E>(
&mut self, &mut self,
origin: Point<Pixels>, origin: Point<Pixels>,
space: Size<AvailableSpace>, space: impl Into<Size<AvailableSpace>>,
f: impl FnOnce(&mut WindowContext) -> AnyElement, f: impl FnOnce(&mut WindowContext) -> E,
) { ) -> (E::RequestLayoutState, E::PrepaintState)
where
E: Element,
{
self.update(|cx| { self.update(|cx| {
cx.with_element_context(|cx| { cx.window.draw_phase = DrawPhase::Prepaint;
let mut element = f(cx); let mut element = Drawable::new(f(cx));
element.layout_as_root(space, cx); element.layout_as_root(space.into(), cx);
cx.with_absolute_element_offset(origin, |cx| element.prepaint(cx)); cx.with_absolute_element_offset(origin, |cx| element.prepaint(cx));
element.paint(cx);
});
cx.window.draw_phase = DrawPhase::Paint;
let (request_layout_state, prepaint_state) = element.paint(cx);
cx.window.draw_phase = DrawPhase::None;
cx.refresh(); cx.refresh();
(request_layout_state, prepaint_state)
}) })
} }

View File

@ -32,12 +32,12 @@
//! your own custom layout algorithm or rendering a code editor. //! your own custom layout algorithm or rendering a code editor.
use crate::{ use crate::{
util::FluentBuilder, ArenaBox, AvailableSpace, Bounds, DispatchNodeId, ElementContext, util::FluentBuilder, ArenaBox, AvailableSpace, Bounds, DispatchNodeId, ElementId, LayoutId,
ElementId, LayoutId, Pixels, Point, Size, ViewContext, WindowContext, ELEMENT_ARENA, Pixels, Point, Size, Style, ViewContext, WindowContext, ELEMENT_ARENA,
}; };
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec; pub(crate) use smallvec::SmallVec;
use std::{any::Any, fmt::Debug, mem, ops::DerefMut}; use std::{any::Any, fmt::Debug, mem};
/// Implemented by types that participate in laying out and painting the contents of a window. /// Implemented by types that participate in laying out and painting the contents of a window.
/// Elements form a tree and are laid out according to web-based layout rules, as implemented by Taffy. /// Elements form a tree and are laid out according to web-based layout rules, as implemented by Taffy.
@ -54,7 +54,7 @@ pub trait Element: 'static + IntoElement {
/// Before an element can be painted, we need to know where it's going to be and how big it is. /// Before an element can be painted, we need to know where it's going to be and how big it is.
/// Use this method to request a layout from Taffy and initialize the element's state. /// Use this method to request a layout from Taffy and initialize the element's state.
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState); fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState);
/// After laying out an element, we need to commit its bounds to the current frame for hitbox /// After laying out an element, we need to commit its bounds to the current frame for hitbox
/// purposes. The state argument is the same state that was returned from [`Element::request_layout()`]. /// purposes. The state argument is the same state that was returned from [`Element::request_layout()`].
@ -62,7 +62,7 @@ pub trait Element: 'static + IntoElement {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Self::PrepaintState; ) -> Self::PrepaintState;
/// Once layout has been completed, this method will be called to paint the element to the screen. /// Once layout has been completed, this method will be called to paint the element to the screen.
@ -72,7 +72,7 @@ pub trait Element: 'static + IntoElement {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
prepaint: &mut Self::PrepaintState, prepaint: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
); );
/// Convert this element into a dynamically-typed [`AnyElement`]. /// Convert this element into a dynamically-typed [`AnyElement`].
@ -164,18 +164,13 @@ impl<C: RenderOnce> Element for Component<C> {
type RequestLayoutState = AnyElement; type RequestLayoutState = AnyElement;
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let mut element = self let mut element = self.0.take().unwrap().render(cx).into_any_element();
.0
.take()
.unwrap()
.render(cx.deref_mut())
.into_any_element();
let layout_id = element.request_layout(cx); let layout_id = element.request_layout(cx);
(layout_id, element) (layout_id, element)
} }
fn prepaint(&mut self, _: Bounds<Pixels>, element: &mut AnyElement, cx: &mut ElementContext) { fn prepaint(&mut self, _: Bounds<Pixels>, element: &mut AnyElement, cx: &mut WindowContext) {
element.prepaint(cx); element.prepaint(cx);
} }
@ -184,7 +179,7 @@ impl<C: RenderOnce> Element for Component<C> {
_: Bounds<Pixels>, _: Bounds<Pixels>,
element: &mut Self::RequestLayoutState, element: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
element.paint(cx) element.paint(cx)
} }
@ -205,16 +200,16 @@ pub(crate) struct GlobalElementId(SmallVec<[ElementId; 32]>);
trait ElementObject { trait ElementObject {
fn inner_element(&mut self) -> &mut dyn Any; fn inner_element(&mut self) -> &mut dyn Any;
fn request_layout(&mut self, cx: &mut ElementContext) -> LayoutId; fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId;
fn prepaint(&mut self, cx: &mut ElementContext); fn prepaint(&mut self, cx: &mut WindowContext);
fn paint(&mut self, cx: &mut ElementContext); fn paint(&mut self, cx: &mut WindowContext);
fn layout_as_root( fn layout_as_root(
&mut self, &mut self,
available_space: Size<AvailableSpace>, available_space: Size<AvailableSpace>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Size<Pixels>; ) -> Size<Pixels>;
} }
@ -249,14 +244,14 @@ enum ElementDrawPhase<RequestLayoutState, PrepaintState> {
/// A wrapper around an implementer of [`Element`] that allows it to be drawn in a window. /// A wrapper around an implementer of [`Element`] that allows it to be drawn in a window.
impl<E: Element> Drawable<E> { impl<E: Element> Drawable<E> {
fn new(element: E) -> Self { pub(crate) fn new(element: E) -> Self {
Drawable { Drawable {
element, element,
phase: ElementDrawPhase::Start, phase: ElementDrawPhase::Start,
} }
} }
fn request_layout(&mut self, cx: &mut ElementContext) -> LayoutId { fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId {
match mem::take(&mut self.phase) { match mem::take(&mut self.phase) {
ElementDrawPhase::Start => { ElementDrawPhase::Start => {
let (layout_id, request_layout) = self.element.request_layout(cx); let (layout_id, request_layout) = self.element.request_layout(cx);
@ -270,7 +265,7 @@ impl<E: Element> Drawable<E> {
} }
} }
fn prepaint(&mut self, cx: &mut ElementContext) { pub(crate) fn prepaint(&mut self, cx: &mut WindowContext) {
match mem::take(&mut self.phase) { match mem::take(&mut self.phase) {
ElementDrawPhase::RequestLayoutState { ElementDrawPhase::RequestLayoutState {
layout_id, layout_id,
@ -296,7 +291,10 @@ impl<E: Element> Drawable<E> {
} }
} }
fn paint(&mut self, cx: &mut ElementContext) -> E::RequestLayoutState { pub(crate) fn paint(
&mut self,
cx: &mut WindowContext,
) -> (E::RequestLayoutState, E::PrepaintState) {
match mem::take(&mut self.phase) { match mem::take(&mut self.phase) {
ElementDrawPhase::PrepaintState { ElementDrawPhase::PrepaintState {
node_id, node_id,
@ -309,16 +307,16 @@ impl<E: Element> Drawable<E> {
self.element self.element
.paint(bounds, &mut request_layout, &mut prepaint, cx); .paint(bounds, &mut request_layout, &mut prepaint, cx);
self.phase = ElementDrawPhase::Painted; self.phase = ElementDrawPhase::Painted;
request_layout (request_layout, prepaint)
} }
_ => panic!("must call prepaint before paint"), _ => panic!("must call prepaint before paint"),
} }
} }
fn layout_as_root( pub(crate) fn layout_as_root(
&mut self, &mut self,
available_space: Size<AvailableSpace>, available_space: Size<AvailableSpace>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Size<Pixels> { ) -> Size<Pixels> {
if matches!(&self.phase, ElementDrawPhase::Start) { if matches!(&self.phase, ElementDrawPhase::Start) {
self.request_layout(cx); self.request_layout(cx);
@ -368,22 +366,22 @@ where
&mut self.element &mut self.element
} }
fn request_layout(&mut self, cx: &mut ElementContext) -> LayoutId { fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId {
Drawable::request_layout(self, cx) Drawable::request_layout(self, cx)
} }
fn prepaint(&mut self, cx: &mut ElementContext) { fn prepaint(&mut self, cx: &mut WindowContext) {
Drawable::prepaint(self, cx); Drawable::prepaint(self, cx);
} }
fn paint(&mut self, cx: &mut ElementContext) { fn paint(&mut self, cx: &mut WindowContext) {
Drawable::paint(self, cx); Drawable::paint(self, cx);
} }
fn layout_as_root( fn layout_as_root(
&mut self, &mut self,
available_space: Size<AvailableSpace>, available_space: Size<AvailableSpace>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Size<Pixels> { ) -> Size<Pixels> {
Drawable::layout_as_root(self, available_space, cx) Drawable::layout_as_root(self, available_space, cx)
} }
@ -411,18 +409,18 @@ impl AnyElement {
/// Request the layout ID of the element stored in this `AnyElement`. /// Request the layout ID of the element stored in this `AnyElement`.
/// Used for laying out child elements in a parent element. /// Used for laying out child elements in a parent element.
pub fn request_layout(&mut self, cx: &mut ElementContext) -> LayoutId { pub fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId {
self.0.request_layout(cx) self.0.request_layout(cx)
} }
/// Prepares the element to be painted by storing its bounds, giving it a chance to draw hitboxes and /// Prepares the element to be painted by storing its bounds, giving it a chance to draw hitboxes and
/// request autoscroll before the final paint pass is confirmed. /// request autoscroll before the final paint pass is confirmed.
pub fn prepaint(&mut self, cx: &mut ElementContext) { pub fn prepaint(&mut self, cx: &mut WindowContext) {
self.0.prepaint(cx) self.0.prepaint(cx)
} }
/// Paints the element stored in this `AnyElement`. /// Paints the element stored in this `AnyElement`.
pub fn paint(&mut self, cx: &mut ElementContext) { pub fn paint(&mut self, cx: &mut WindowContext) {
self.0.paint(cx) self.0.paint(cx)
} }
@ -430,13 +428,13 @@ impl AnyElement {
pub fn layout_as_root( pub fn layout_as_root(
&mut self, &mut self,
available_space: Size<AvailableSpace>, available_space: Size<AvailableSpace>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Size<Pixels> { ) -> Size<Pixels> {
self.0.layout_as_root(available_space, cx) self.0.layout_as_root(available_space, cx)
} }
/// Prepaints this element at the given absolute origin. /// Prepaints this element at the given absolute origin.
pub fn prepaint_at(&mut self, origin: Point<Pixels>, cx: &mut ElementContext) { pub fn prepaint_at(&mut self, origin: Point<Pixels>, cx: &mut WindowContext) {
cx.with_absolute_element_offset(origin, |cx| self.0.prepaint(cx)); cx.with_absolute_element_offset(origin, |cx| self.0.prepaint(cx));
} }
@ -445,7 +443,7 @@ impl AnyElement {
&mut self, &mut self,
origin: Point<Pixels>, origin: Point<Pixels>,
available_space: Size<AvailableSpace>, available_space: Size<AvailableSpace>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.layout_as_root(available_space, cx); self.layout_as_root(available_space, cx);
cx.with_absolute_element_offset(origin, |cx| self.0.prepaint(cx)); cx.with_absolute_element_offset(origin, |cx| self.0.prepaint(cx));
@ -456,7 +454,7 @@ impl Element for AnyElement {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let layout_id = self.request_layout(cx); let layout_id = self.request_layout(cx);
(layout_id, ()) (layout_id, ())
} }
@ -465,7 +463,7 @@ impl Element for AnyElement {
&mut self, &mut self,
_: Bounds<Pixels>, _: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.prepaint(cx) self.prepaint(cx)
} }
@ -475,7 +473,7 @@ impl Element for AnyElement {
_: Bounds<Pixels>, _: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.paint(cx) self.paint(cx)
} }
@ -508,15 +506,15 @@ impl Element for Empty {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
(cx.request_layout(&crate::Style::default(), None), ()) (cx.request_layout(&Style::default(), None), ())
} }
fn prepaint( fn prepaint(
&mut self, &mut self,
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_state: &mut Self::RequestLayoutState, _state: &mut Self::RequestLayoutState,
_cx: &mut ElementContext, _cx: &mut WindowContext,
) { ) {
} }
@ -525,7 +523,7 @@ impl Element for Empty {
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
_prepaint: &mut Self::PrepaintState, _prepaint: &mut Self::PrepaintState,
_cx: &mut ElementContext, _cx: &mut WindowContext,
) { ) {
} }
} }

View File

@ -2,8 +2,8 @@ use smallvec::SmallVec;
use taffy::style::{Display, Position}; use taffy::style::{Display, Position};
use crate::{ use crate::{
point, AnyElement, Bounds, Element, ElementContext, IntoElement, LayoutId, ParentElement, point, AnyElement, Bounds, Element, IntoElement, LayoutId, ParentElement, Pixels, Point, Size,
Pixels, Point, Size, Style, Style, WindowContext,
}; };
/// The state that the anchored element element uses to track its children. /// The state that the anchored element element uses to track its children.
@ -74,7 +74,7 @@ impl Element for Anchored {
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> (crate::LayoutId, Self::RequestLayoutState) { ) -> (crate::LayoutId, Self::RequestLayoutState) {
let child_layout_ids = self let child_layout_ids = self
.children .children
@ -97,7 +97,7 @@ impl Element for Anchored {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
if request_layout.child_layout_ids.is_empty() { if request_layout.child_layout_ids.is_empty() {
return; return;
@ -180,7 +180,7 @@ impl Element for Anchored {
_bounds: crate::Bounds<crate::Pixels>, _bounds: crate::Bounds<crate::Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
_prepaint: &mut Self::PrepaintState, _prepaint: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
for child in &mut self.children { for child in &mut self.children {
child.paint(cx); child.paint(cx);

View File

@ -91,7 +91,7 @@ impl<E: IntoElement + 'static> Element for AnimationElement<E> {
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut crate::ElementContext, cx: &mut crate::WindowContext,
) -> (crate::LayoutId, Self::RequestLayoutState) { ) -> (crate::LayoutId, Self::RequestLayoutState) {
cx.with_element_state(Some(self.id.clone()), |state, cx| { cx.with_element_state(Some(self.id.clone()), |state, cx| {
let state = state.unwrap().unwrap_or_else(|| AnimationState { let state = state.unwrap().unwrap_or_else(|| AnimationState {
@ -138,7 +138,7 @@ impl<E: IntoElement + 'static> Element for AnimationElement<E> {
&mut self, &mut self,
_bounds: crate::Bounds<crate::Pixels>, _bounds: crate::Bounds<crate::Pixels>,
element: &mut Self::RequestLayoutState, element: &mut Self::RequestLayoutState,
cx: &mut crate::ElementContext, cx: &mut crate::WindowContext,
) -> Self::PrepaintState { ) -> Self::PrepaintState {
element.prepaint(cx); element.prepaint(cx);
} }
@ -148,7 +148,7 @@ impl<E: IntoElement + 'static> Element for AnimationElement<E> {
_bounds: crate::Bounds<crate::Pixels>, _bounds: crate::Bounds<crate::Pixels>,
element: &mut Self::RequestLayoutState, element: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut crate::ElementContext, cx: &mut crate::WindowContext,
) { ) {
element.paint(cx); element.paint(cx);
} }

View File

@ -1,12 +1,12 @@
use refineable::Refineable as _; use refineable::Refineable as _;
use crate::{Bounds, Element, ElementContext, IntoElement, Pixels, Style, StyleRefinement, Styled}; use crate::{Bounds, Element, IntoElement, Pixels, Style, StyleRefinement, Styled, WindowContext};
/// Construct a canvas element with the given paint callback. /// Construct a canvas element with the given paint callback.
/// Useful for adding short term custom drawing to a view. /// Useful for adding short term custom drawing to a view.
pub fn canvas<T>( pub fn canvas<T>(
prepaint: impl 'static + FnOnce(Bounds<Pixels>, &mut ElementContext) -> T, prepaint: impl 'static + FnOnce(Bounds<Pixels>, &mut WindowContext) -> T,
paint: impl 'static + FnOnce(Bounds<Pixels>, T, &mut ElementContext), paint: impl 'static + FnOnce(Bounds<Pixels>, T, &mut WindowContext),
) -> Canvas<T> { ) -> Canvas<T> {
Canvas { Canvas {
prepaint: Some(Box::new(prepaint)), prepaint: Some(Box::new(prepaint)),
@ -18,8 +18,8 @@ pub fn canvas<T>(
/// A canvas element, meant for accessing the low level paint API without defining a whole /// A canvas element, meant for accessing the low level paint API without defining a whole
/// custom element /// custom element
pub struct Canvas<T> { pub struct Canvas<T> {
prepaint: Option<Box<dyn FnOnce(Bounds<Pixels>, &mut ElementContext) -> T>>, prepaint: Option<Box<dyn FnOnce(Bounds<Pixels>, &mut WindowContext) -> T>>,
paint: Option<Box<dyn FnOnce(Bounds<Pixels>, T, &mut ElementContext)>>, paint: Option<Box<dyn FnOnce(Bounds<Pixels>, T, &mut WindowContext)>>,
style: StyleRefinement, style: StyleRefinement,
} }
@ -37,7 +37,7 @@ impl<T: 'static> Element for Canvas<T> {
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> (crate::LayoutId, Self::RequestLayoutState) { ) -> (crate::LayoutId, Self::RequestLayoutState) {
let mut style = Style::default(); let mut style = Style::default();
style.refine(&self.style); style.refine(&self.style);
@ -49,7 +49,7 @@ impl<T: 'static> Element for Canvas<T> {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_request_layout: &mut Style, _request_layout: &mut Style,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<T> { ) -> Option<T> {
Some(self.prepaint.take().unwrap()(bounds, cx)) Some(self.prepaint.take().unwrap()(bounds, cx))
} }
@ -59,7 +59,7 @@ impl<T: 'static> Element for Canvas<T> {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
style: &mut Style, style: &mut Style,
prepaint: &mut Self::PrepaintState, prepaint: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let prepaint = prepaint.take().unwrap(); let prepaint = prepaint.take().unwrap();
style.paint(bounds, cx, |cx| { style.paint(bounds, cx, |cx| {

View File

@ -1,4 +1,4 @@
use crate::{AnyElement, Bounds, Element, ElementContext, IntoElement, LayoutId, Pixels}; use crate::{AnyElement, Bounds, Element, IntoElement, LayoutId, Pixels, WindowContext};
/// Builds a `Deferred` element, which delays the layout and paint of its child. /// Builds a `Deferred` element, which delays the layout and paint of its child.
pub fn deferred(child: impl IntoElement) -> Deferred { pub fn deferred(child: impl IntoElement) -> Deferred {
@ -29,7 +29,7 @@ impl Element for Deferred {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, ()) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, ()) {
let layout_id = self.child.as_mut().unwrap().request_layout(cx); let layout_id = self.child.as_mut().unwrap().request_layout(cx);
(layout_id, ()) (layout_id, ())
} }
@ -38,7 +38,7 @@ impl Element for Deferred {
&mut self, &mut self,
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let child = self.child.take().unwrap(); let child = self.child.take().unwrap();
let element_offset = cx.element_offset(); let element_offset = cx.element_offset();
@ -50,7 +50,7 @@ impl Element for Deferred {
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
_prepaint: &mut Self::PrepaintState, _prepaint: &mut Self::PrepaintState,
_cx: &mut ElementContext, _cx: &mut WindowContext,
) { ) {
} }
} }

View File

@ -17,11 +17,11 @@
use crate::{ use crate::{
point, px, size, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, Bounds, point, px, size, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, Bounds,
ClickEvent, DispatchPhase, Element, ElementContext, ElementId, FocusHandle, Global, Hitbox, ClickEvent, DispatchPhase, Element, ElementId, FocusHandle, Global, Hitbox, HitboxId,
HitboxId, IntoElement, IsZero, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, IntoElement, IsZero, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, ModifiersChangedEvent,
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point,
ParentElement, Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, Style, Render, ScrollWheelEvent, SharedString, Size, Style, StyleRefinement, Styled, Task, TooltipId,
StyleRefinement, Styled, Task, TooltipId, View, Visibility, WindowContext, View, Visibility, WindowContext,
}; };
use collections::HashMap; use collections::HashMap;
use refineable::Refineable; use refineable::Refineable;
@ -1123,7 +1123,7 @@ impl Element for Div {
type RequestLayoutState = DivFrameState; type RequestLayoutState = DivFrameState;
type PrepaintState = Option<Hitbox>; type PrepaintState = Option<Hitbox>;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let mut child_layout_ids = SmallVec::new(); let mut child_layout_ids = SmallVec::new();
let layout_id = self.interactivity.request_layout(cx, |style, cx| { let layout_id = self.interactivity.request_layout(cx, |style, cx| {
cx.with_text_style(style.text_style().cloned(), |cx| { cx.with_text_style(style.text_style().cloned(), |cx| {
@ -1142,7 +1142,7 @@ impl Element for Div {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<Hitbox> { ) -> Option<Hitbox> {
let mut child_min = point(Pixels::MAX, Pixels::MAX); let mut child_min = point(Pixels::MAX, Pixels::MAX);
let mut child_max = Point::default(); let mut child_max = Point::default();
@ -1197,7 +1197,7 @@ impl Element for Div {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
hitbox: &mut Option<Hitbox>, hitbox: &mut Option<Hitbox>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.interactivity self.interactivity
.paint(bounds, hitbox.as_ref(), cx, |_style, cx| { .paint(bounds, hitbox.as_ref(), cx, |_style, cx| {
@ -1276,8 +1276,8 @@ impl Interactivity {
/// Layout this element according to this interactivity state's configured styles /// Layout this element according to this interactivity state's configured styles
pub fn request_layout( pub fn request_layout(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
f: impl FnOnce(Style, &mut ElementContext) -> LayoutId, f: impl FnOnce(Style, &mut WindowContext) -> LayoutId,
) -> LayoutId { ) -> LayoutId {
cx.with_element_state::<InteractiveElementState, _>( cx.with_element_state::<InteractiveElementState, _>(
self.element_id.clone(), self.element_id.clone(),
@ -1341,8 +1341,8 @@ impl Interactivity {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
content_size: Size<Pixels>, content_size: Size<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
f: impl FnOnce(&Style, Point<Pixels>, Option<Hitbox>, &mut ElementContext) -> R, f: impl FnOnce(&Style, Point<Pixels>, Option<Hitbox>, &mut WindowContext) -> R,
) -> R { ) -> R {
self.content_size = content_size; self.content_size = content_size;
cx.with_element_state::<InteractiveElementState, _>( cx.with_element_state::<InteractiveElementState, _>(
@ -1406,7 +1406,7 @@ impl Interactivity {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
style: &Style, style: &Style,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Point<Pixels> { ) -> Point<Pixels> {
if let Some(scroll_offset) = self.scroll_offset.as_ref() { if let Some(scroll_offset) = self.scroll_offset.as_ref() {
if let Some(scroll_handle) = &self.tracked_scroll_handle { if let Some(scroll_handle) = &self.tracked_scroll_handle {
@ -1456,8 +1456,8 @@ impl Interactivity {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
hitbox: Option<&Hitbox>, hitbox: Option<&Hitbox>,
cx: &mut ElementContext, cx: &mut WindowContext,
f: impl FnOnce(&Style, &mut ElementContext), f: impl FnOnce(&Style, &mut WindowContext),
) { ) {
self.hovered = hitbox.map(|hitbox| hitbox.is_hovered(cx)); self.hovered = hitbox.map(|hitbox| hitbox.is_hovered(cx));
cx.with_element_state::<InteractiveElementState, _>( cx.with_element_state::<InteractiveElementState, _>(
@ -1482,7 +1482,7 @@ impl Interactivity {
return ((), element_state); return ((), element_state);
} }
style.paint(bounds, cx, |cx: &mut ElementContext| { style.paint(bounds, cx, |cx: &mut WindowContext| {
cx.with_text_style(style.text_style().cloned(), |cx| { cx.with_text_style(style.text_style().cloned(), |cx| {
cx.with_content_mask(style.overflow_mask(bounds, cx.rem_size()), |cx| { cx.with_content_mask(style.overflow_mask(bounds, cx.rem_size()), |cx| {
if let Some(hitbox) = hitbox { if let Some(hitbox) = hitbox {
@ -1521,7 +1521,7 @@ impl Interactivity {
} }
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
fn paint_debug_info(&mut self, hitbox: &Hitbox, style: &Style, cx: &mut ElementContext) { fn paint_debug_info(&mut self, hitbox: &Hitbox, style: &Style, cx: &mut WindowContext) {
if self.element_id.is_some() if self.element_id.is_some()
&& (style.debug || style.debug_below || cx.has_global::<crate::DebugBelow>()) && (style.debug || style.debug_below || cx.has_global::<crate::DebugBelow>())
&& hitbox.is_hovered(cx) && hitbox.is_hovered(cx)
@ -1530,7 +1530,7 @@ impl Interactivity {
let element_id = format!("{:?}", self.element_id.as_ref().unwrap()); let element_id = format!("{:?}", self.element_id.as_ref().unwrap());
let str_len = element_id.len(); let str_len = element_id.len();
let render_debug_text = |cx: &mut ElementContext| { let render_debug_text = |cx: &mut WindowContext| {
if let Some(text) = cx if let Some(text) = cx
.text_system() .text_system()
.shape_text( .shape_text(
@ -1629,7 +1629,7 @@ impl Interactivity {
&mut self, &mut self,
hitbox: &Hitbox, hitbox: &Hitbox,
element_state: Option<&mut InteractiveElementState>, element_state: Option<&mut InteractiveElementState>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
// If this element can be focused, register a mouse down listener // If this element can be focused, register a mouse down listener
// that will automatically transfer focus when hitting the element. // that will automatically transfer focus when hitting the element.
@ -1712,11 +1712,11 @@ impl Interactivity {
let mut can_drop = true; let mut can_drop = true;
if let Some(predicate) = &can_drop_predicate { if let Some(predicate) = &can_drop_predicate {
can_drop = predicate(drag.value.as_ref(), cx.deref_mut()); can_drop = predicate(drag.value.as_ref(), cx);
} }
if can_drop { if can_drop {
listener(drag.value.as_ref(), cx.deref_mut()); listener(drag.value.as_ref(), cx);
cx.refresh(); cx.refresh();
cx.stop_propagation(); cx.stop_propagation();
} }
@ -1840,7 +1840,7 @@ impl Interactivity {
*was_hovered = is_hovered; *was_hovered = is_hovered;
drop(was_hovered); drop(was_hovered);
hover_listener(&is_hovered, cx.deref_mut()); hover_listener(&is_hovered, cx);
} }
}); });
} }
@ -1969,7 +1969,7 @@ impl Interactivity {
} }
} }
fn paint_keyboard_listeners(&mut self, cx: &mut ElementContext) { fn paint_keyboard_listeners(&mut self, cx: &mut WindowContext) {
let key_down_listeners = mem::take(&mut self.key_down_listeners); let key_down_listeners = mem::take(&mut self.key_down_listeners);
let key_up_listeners = mem::take(&mut self.key_up_listeners); let key_up_listeners = mem::take(&mut self.key_up_listeners);
let modifiers_changed_listeners = mem::take(&mut self.modifiers_changed_listeners); let modifiers_changed_listeners = mem::take(&mut self.modifiers_changed_listeners);
@ -2004,7 +2004,7 @@ impl Interactivity {
} }
} }
fn paint_hover_group_handler(&self, cx: &mut ElementContext) { fn paint_hover_group_handler(&self, cx: &mut WindowContext) {
let group_hitbox = self let group_hitbox = self
.group_hover_style .group_hover_style
.as_ref() .as_ref()
@ -2021,7 +2021,7 @@ impl Interactivity {
} }
} }
fn paint_scroll_listener(&self, hitbox: &Hitbox, style: &Style, cx: &mut ElementContext) { fn paint_scroll_listener(&self, hitbox: &Hitbox, style: &Style, cx: &mut WindowContext) {
if let Some(scroll_offset) = self.scroll_offset.clone() { if let Some(scroll_offset) = self.scroll_offset.clone() {
let overflow = style.overflow; let overflow = style.overflow;
let line_height = cx.line_height(); let line_height = cx.line_height();
@ -2064,7 +2064,7 @@ impl Interactivity {
} }
/// Compute the visual style for this element, based on the current bounds and the element's state. /// Compute the visual style for this element, based on the current bounds and the element's state.
pub fn compute_style(&self, hitbox: Option<&Hitbox>, cx: &mut ElementContext) -> Style { pub fn compute_style(&self, hitbox: Option<&Hitbox>, cx: &mut WindowContext) -> Style {
cx.with_element_state(self.element_id.clone(), |element_state, cx| { cx.with_element_state(self.element_id.clone(), |element_state, cx| {
let mut element_state = let mut element_state =
element_state.map(|element_state| element_state.unwrap_or_default()); element_state.map(|element_state| element_state.unwrap_or_default());
@ -2078,7 +2078,7 @@ impl Interactivity {
&self, &self,
hitbox: Option<&Hitbox>, hitbox: Option<&Hitbox>,
element_state: Option<&mut InteractiveElementState>, element_state: Option<&mut InteractiveElementState>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Style { ) -> Style {
let mut style = Style::default(); let mut style = Style::default();
style.refine(&self.base_style); style.refine(&self.base_style);
@ -2119,7 +2119,7 @@ impl Interactivity {
if let Some(drag) = cx.active_drag.take() { if let Some(drag) = cx.active_drag.take() {
let mut can_drop = true; let mut can_drop = true;
if let Some(can_drop_predicate) = &self.can_drop_predicate { if let Some(can_drop_predicate) = &self.can_drop_predicate {
can_drop = can_drop_predicate(drag.value.as_ref(), cx.deref_mut()); can_drop = can_drop_predicate(drag.value.as_ref(), cx);
} }
if can_drop { if can_drop {
@ -2264,7 +2264,7 @@ where
type RequestLayoutState = E::RequestLayoutState; type RequestLayoutState = E::RequestLayoutState;
type PrepaintState = E::PrepaintState; type PrepaintState = E::PrepaintState;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
self.element.request_layout(cx) self.element.request_layout(cx)
} }
@ -2272,7 +2272,7 @@ where
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
state: &mut Self::RequestLayoutState, state: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> E::PrepaintState { ) -> E::PrepaintState {
self.element.prepaint(bounds, state, cx) self.element.prepaint(bounds, state, cx)
} }
@ -2282,7 +2282,7 @@ where
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
prepaint: &mut Self::PrepaintState, prepaint: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.element.paint(bounds, request_layout, prepaint, cx) self.element.paint(bounds, request_layout, prepaint, cx)
} }
@ -2347,7 +2347,7 @@ where
type RequestLayoutState = E::RequestLayoutState; type RequestLayoutState = E::RequestLayoutState;
type PrepaintState = E::PrepaintState; type PrepaintState = E::PrepaintState;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
self.element.request_layout(cx) self.element.request_layout(cx)
} }
@ -2355,7 +2355,7 @@ where
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
state: &mut Self::RequestLayoutState, state: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> E::PrepaintState { ) -> E::PrepaintState {
self.element.prepaint(bounds, state, cx) self.element.prepaint(bounds, state, cx)
} }
@ -2365,7 +2365,7 @@ where
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
prepaint: &mut Self::PrepaintState, prepaint: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.element.paint(bounds, request_layout, prepaint, cx); self.element.paint(bounds, request_layout, prepaint, cx);
} }

View File

@ -3,9 +3,9 @@ use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use crate::{ use crate::{
point, px, size, AbsoluteLength, Asset, Bounds, DefiniteLength, DevicePixels, Element, point, px, size, AbsoluteLength, Asset, Bounds, DefiniteLength, DevicePixels, Element, Hitbox,
ElementContext, Hitbox, ImageData, InteractiveElement, Interactivity, IntoElement, LayoutId, ImageData, InteractiveElement, Interactivity, IntoElement, LayoutId, Length, Pixels, SharedUri,
Length, Pixels, SharedUri, Size, StyleRefinement, Styled, SvgSize, UriOrPath, WindowContext, Size, StyleRefinement, Styled, SvgSize, UriOrPath, WindowContext,
}; };
use futures::{AsyncReadExt, Future}; use futures::{AsyncReadExt, Future};
use image::{ImageBuffer, ImageError}; use image::{ImageBuffer, ImageError};
@ -232,7 +232,7 @@ impl Element for Img {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = Option<Hitbox>; type PrepaintState = Option<Hitbox>;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let layout_id = self.interactivity.request_layout(cx, |mut style, cx| { let layout_id = self.interactivity.request_layout(cx, |mut style, cx| {
if let Some(data) = self.source.data(cx) { if let Some(data) = self.source.data(cx) {
let image_size = data.size(); let image_size = data.size();
@ -260,7 +260,7 @@ impl Element for Img {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<Hitbox> { ) -> Option<Hitbox> {
self.interactivity self.interactivity
.prepaint(bounds, bounds.size, cx, |_, _, hitbox, _| hitbox) .prepaint(bounds, bounds.size, cx, |_, _, hitbox, _| hitbox)
@ -271,7 +271,7 @@ impl Element for Img {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
hitbox: &mut Self::PrepaintState, hitbox: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let source = self.source.clone(); let source = self.source.clone();
self.interactivity self.interactivity
@ -319,7 +319,7 @@ impl InteractiveElement for Img {
} }
impl ImageSource { impl ImageSource {
fn data(&self, cx: &mut ElementContext) -> Option<Arc<ImageData>> { fn data(&self, cx: &mut WindowContext) -> Option<Arc<ImageData>> {
match self { match self {
ImageSource::Uri(_) | ImageSource::File(_) => { ImageSource::Uri(_) | ImageSource::File(_) => {
let uri_or_path: UriOrPath = match self { let uri_or_path: UriOrPath = match self {

View File

@ -8,8 +8,8 @@
use crate::{ use crate::{
point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, DispatchPhase, Edges, point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, DispatchPhase, Edges,
Element, ElementContext, FocusHandle, Hitbox, IntoElement, Pixels, Point, ScrollWheelEvent, Element, FocusHandle, Hitbox, IntoElement, Pixels, Point, ScrollWheelEvent, Size, Style,
Size, Style, StyleRefinement, Styled, WindowContext, StyleRefinement, Styled, WindowContext,
}; };
use collections::VecDeque; use collections::VecDeque;
use refineable::Refineable as _; use refineable::Refineable as _;
@ -434,7 +434,7 @@ impl StateInner {
available_width: Option<Pixels>, available_width: Option<Pixels>,
available_height: Pixels, available_height: Pixels,
padding: &Edges<Pixels>, padding: &Edges<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> LayoutItemsResponse { ) -> LayoutItemsResponse {
let old_items = self.items.clone(); let old_items = self.items.clone();
let mut measured_items = VecDeque::new(); let mut measured_items = VecDeque::new();
@ -609,7 +609,7 @@ impl StateInner {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
padding: Edges<Pixels>, padding: Edges<Pixels>,
autoscroll: bool, autoscroll: bool,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Result<LayoutItemsResponse, ListOffset> { ) -> Result<LayoutItemsResponse, ListOffset> {
cx.transact(|cx| { cx.transact(|cx| {
let mut layout_response = let mut layout_response =
@ -706,7 +706,7 @@ impl Element for List {
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut crate::ElementContext, cx: &mut crate::WindowContext,
) -> (crate::LayoutId, Self::RequestLayoutState) { ) -> (crate::LayoutId, Self::RequestLayoutState) {
let layout_id = match self.sizing_behavior { let layout_id = match self.sizing_behavior {
ListSizingBehavior::Infer => { ListSizingBehavior::Infer => {
@ -772,7 +772,7 @@ impl Element for List {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> ListPrepaintState { ) -> ListPrepaintState {
let state = &mut *self.state.0.borrow_mut(); let state = &mut *self.state.0.borrow_mut();
state.reset = false; state.reset = false;
@ -815,7 +815,7 @@ impl Element for List {
bounds: Bounds<crate::Pixels>, bounds: Bounds<crate::Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
prepaint: &mut Self::PrepaintState, prepaint: &mut Self::PrepaintState,
cx: &mut crate::ElementContext, cx: &mut crate::WindowContext,
) { ) {
cx.with_content_mask(Some(ContentMask { bounds }), |cx| { cx.with_content_mask(Some(ContentMask { bounds }), |cx| {
for item in &mut prepaint.layout.item_layouts { for item in &mut prepaint.layout.item_layouts {
@ -951,11 +951,9 @@ mod test {
}); });
// Paint // Paint
cx.draw( cx.draw(point(px(0.), px(0.)), size(px(100.), px(20.)), |_| {
point(px(0.), px(0.)), list(state.clone()).w_full().h_full()
size(px(100.), px(20.)).into(), });
|_| list(state.clone()).w_full().h_full().into_any(),
);
// Reset // Reset
state.reset(5); state.reset(5);

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
geometry::Negate as _, point, px, radians, size, Bounds, Element, ElementContext, Hitbox, geometry::Negate as _, point, px, radians, size, Bounds, Element, Hitbox, InteractiveElement,
InteractiveElement, Interactivity, IntoElement, LayoutId, Pixels, Point, Radians, SharedString, Interactivity, IntoElement, LayoutId, Pixels, Point, Radians, SharedString, Size,
Size, StyleRefinement, Styled, TransformationMatrix, StyleRefinement, Styled, TransformationMatrix, WindowContext,
}; };
use util::ResultExt; use util::ResultExt;
@ -40,7 +40,7 @@ impl Element for Svg {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = Option<Hitbox>; type PrepaintState = Option<Hitbox>;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let layout_id = self let layout_id = self
.interactivity .interactivity
.request_layout(cx, |style, cx| cx.request_layout(&style, None)); .request_layout(cx, |style, cx| cx.request_layout(&style, None));
@ -51,7 +51,7 @@ impl Element for Svg {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<Hitbox> { ) -> Option<Hitbox> {
self.interactivity self.interactivity
.prepaint(bounds, bounds.size, cx, |_, _, hitbox, _| hitbox) .prepaint(bounds, bounds.size, cx, |_, _, hitbox, _| hitbox)
@ -62,7 +62,7 @@ impl Element for Svg {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState, _request_layout: &mut Self::RequestLayoutState,
hitbox: &mut Option<Hitbox>, hitbox: &mut Option<Hitbox>,
cx: &mut ElementContext, cx: &mut WindowContext,
) where ) where
Self: Sized, Self: Sized,
{ {

View File

@ -1,8 +1,7 @@
use crate::{ use crate::{
ActiveTooltip, AnyTooltip, AnyView, Bounds, DispatchPhase, Element, ElementContext, ElementId, ActiveTooltip, AnyTooltip, AnyView, Bounds, DispatchPhase, Element, ElementId, HighlightStyle,
HighlightStyle, Hitbox, IntoElement, LayoutId, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Hitbox, IntoElement, LayoutId, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point,
Pixels, Point, SharedString, Size, TextRun, TextStyle, WhiteSpace, WindowContext, WrappedLine, SharedString, Size, TextRun, TextStyle, WhiteSpace, WindowContext, WrappedLine, TOOLTIP_DELAY,
TOOLTIP_DELAY,
}; };
use anyhow::anyhow; use anyhow::anyhow;
use parking_lot::{Mutex, MutexGuard}; use parking_lot::{Mutex, MutexGuard};
@ -20,7 +19,7 @@ impl Element for &'static str {
type RequestLayoutState = TextState; type RequestLayoutState = TextState;
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let mut state = TextState::default(); let mut state = TextState::default();
let layout_id = state.layout(SharedString::from(*self), None, cx); let layout_id = state.layout(SharedString::from(*self), None, cx);
(layout_id, state) (layout_id, state)
@ -30,7 +29,7 @@ impl Element for &'static str {
&mut self, &mut self,
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_text_state: &mut Self::RequestLayoutState, _text_state: &mut Self::RequestLayoutState,
_cx: &mut ElementContext, _cx: &mut WindowContext,
) { ) {
} }
@ -39,7 +38,7 @@ impl Element for &'static str {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
text_state: &mut TextState, text_state: &mut TextState,
_: &mut (), _: &mut (),
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
text_state.paint(bounds, self, cx) text_state.paint(bounds, self, cx)
} }
@ -65,7 +64,7 @@ impl Element for SharedString {
type RequestLayoutState = TextState; type RequestLayoutState = TextState;
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let mut state = TextState::default(); let mut state = TextState::default();
let layout_id = state.layout(self.clone(), None, cx); let layout_id = state.layout(self.clone(), None, cx);
(layout_id, state) (layout_id, state)
@ -75,7 +74,7 @@ impl Element for SharedString {
&mut self, &mut self,
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_text_state: &mut Self::RequestLayoutState, _text_state: &mut Self::RequestLayoutState,
_cx: &mut ElementContext, _cx: &mut WindowContext,
) { ) {
} }
@ -84,7 +83,7 @@ impl Element for SharedString {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
text_state: &mut Self::RequestLayoutState, text_state: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let text_str: &str = self.as_ref(); let text_str: &str = self.as_ref();
text_state.paint(bounds, text_str, cx) text_state.paint(bounds, text_str, cx)
@ -151,7 +150,7 @@ impl Element for StyledText {
type RequestLayoutState = TextState; type RequestLayoutState = TextState;
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let mut state = TextState::default(); let mut state = TextState::default();
let layout_id = state.layout(self.text.clone(), self.runs.take(), cx); let layout_id = state.layout(self.text.clone(), self.runs.take(), cx);
(layout_id, state) (layout_id, state)
@ -161,7 +160,7 @@ impl Element for StyledText {
&mut self, &mut self,
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_state: &mut Self::RequestLayoutState, _state: &mut Self::RequestLayoutState,
_cx: &mut ElementContext, _cx: &mut WindowContext,
) { ) {
} }
@ -170,7 +169,7 @@ impl Element for StyledText {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
text_state: &mut Self::RequestLayoutState, text_state: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
text_state.paint(bounds, &self.text, cx) text_state.paint(bounds, &self.text, cx)
} }
@ -204,7 +203,7 @@ impl TextState {
&mut self, &mut self,
text: SharedString, text: SharedString,
runs: Option<Vec<TextRun>>, runs: Option<Vec<TextRun>>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> LayoutId { ) -> LayoutId {
let text_style = cx.text_style(); let text_style = cx.text_style();
let font_size = text_style.font_size.to_pixels(cx.rem_size()); let font_size = text_style.font_size.to_pixels(cx.rem_size());
@ -279,7 +278,7 @@ impl TextState {
layout_id layout_id
} }
fn paint(&mut self, bounds: Bounds<Pixels>, text: &str, cx: &mut ElementContext) { fn paint(&mut self, bounds: Bounds<Pixels>, text: &str, cx: &mut WindowContext) {
let element_state = self.lock(); let element_state = self.lock();
let element_state = element_state let element_state = element_state
.as_ref() .as_ref()
@ -405,7 +404,7 @@ impl Element for InteractiveText {
type RequestLayoutState = TextState; type RequestLayoutState = TextState;
type PrepaintState = Hitbox; type PrepaintState = Hitbox;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
self.text.request_layout(cx) self.text.request_layout(cx)
} }
@ -413,7 +412,7 @@ impl Element for InteractiveText {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
state: &mut Self::RequestLayoutState, state: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Hitbox { ) -> Hitbox {
cx.with_element_state::<InteractiveTextState, _>( cx.with_element_state::<InteractiveTextState, _>(
Some(self.element_id.clone()), Some(self.element_id.clone()),
@ -442,7 +441,7 @@ impl Element for InteractiveText {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
text_state: &mut Self::RequestLayoutState, text_state: &mut Self::RequestLayoutState,
hitbox: &mut Hitbox, hitbox: &mut Hitbox,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
cx.with_element_state::<InteractiveTextState, _>( cx.with_element_state::<InteractiveTextState, _>(
Some(self.element_id.clone()), Some(self.element_id.clone()),

View File

@ -5,9 +5,9 @@
//! elements with uniform height. //! elements with uniform height.
use crate::{ use crate::{
point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, Element, ElementContext, point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, Element, ElementId, Hitbox,
ElementId, Hitbox, InteractiveElement, Interactivity, IntoElement, LayoutId, Pixels, Render, InteractiveElement, Interactivity, IntoElement, LayoutId, Pixels, Render, ScrollHandle, Size,
ScrollHandle, Size, StyleRefinement, Styled, View, ViewContext, WindowContext, StyleRefinement, Styled, View, ViewContext, WindowContext,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{cell::RefCell, cmp, ops::Range, rc::Rc}; use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@ -107,7 +107,7 @@ impl Element for UniformList {
type RequestLayoutState = UniformListFrameState; type RequestLayoutState = UniformListFrameState;
type PrepaintState = Option<Hitbox>; type PrepaintState = Option<Hitbox>;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let max_items = self.item_count; let max_items = self.item_count;
let item_size = self.measure_item(None, cx); let item_size = self.measure_item(None, cx);
let layout_id = self.interactivity.request_layout(cx, |style, cx| { let layout_id = self.interactivity.request_layout(cx, |style, cx| {
@ -141,7 +141,7 @@ impl Element for UniformList {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
frame_state: &mut Self::RequestLayoutState, frame_state: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<Hitbox> { ) -> Option<Hitbox> {
let style = self.interactivity.compute_style(None, cx); let style = self.interactivity.compute_style(None, cx);
let border = style.border_widths.to_pixels(cx.rem_size()); let border = style.border_widths.to_pixels(cx.rem_size());
@ -239,7 +239,7 @@ impl Element for UniformList {
bounds: Bounds<crate::Pixels>, bounds: Bounds<crate::Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
hitbox: &mut Option<Hitbox>, hitbox: &mut Option<Hitbox>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.interactivity self.interactivity
.paint(bounds, hitbox.as_ref(), cx, |_, cx| { .paint(bounds, hitbox.as_ref(), cx, |_, cx| {
@ -265,7 +265,7 @@ impl UniformList {
self self
} }
fn measure_item(&self, list_width: Option<Pixels>, cx: &mut ElementContext) -> Size<Pixels> { fn measure_item(&self, list_width: Option<Pixels>, cx: &mut WindowContext) -> Size<Pixels> {
if self.item_count == 0 { if self.item_count == 0 {
return Size::default(); return Size::default();
} }

View File

@ -50,9 +50,8 @@
/// KeyBinding::new("cmd-k left", pane::SplitLeft, Some("Pane")) /// KeyBinding::new("cmd-k left", pane::SplitLeft, Some("Pane"))
/// ///
use crate::{ use crate::{
Action, ActionRegistry, DispatchPhase, ElementContext, EntityId, FocusId, KeyBinding, Action, ActionRegistry, DispatchPhase, EntityId, FocusId, KeyBinding, KeyContext, Keymap,
KeyContext, Keymap, KeymatchResult, Keystroke, KeystrokeMatcher, ModifiersChangedEvent, KeymatchResult, Keystroke, KeystrokeMatcher, ModifiersChangedEvent, WindowContext,
WindowContext,
}; };
use collections::FxHashMap; use collections::FxHashMap;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -107,8 +106,8 @@ impl ReusedSubtree {
} }
} }
type KeyListener = Rc<dyn Fn(&dyn Any, DispatchPhase, &mut ElementContext)>; type KeyListener = Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
type ModifiersChangedListener = Rc<dyn Fn(&ModifiersChangedEvent, &mut ElementContext)>; type ModifiersChangedListener = Rc<dyn Fn(&ModifiersChangedEvent, &mut WindowContext)>;
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct DispatchActionListener { pub(crate) struct DispatchActionListener {

View File

@ -2,9 +2,9 @@ use std::{iter, mem, ops::Range};
use crate::{ use crate::{
black, phi, point, quad, rems, AbsoluteLength, Bounds, ContentMask, Corners, CornersRefinement, black, phi, point, quad, rems, AbsoluteLength, Bounds, ContentMask, Corners, CornersRefinement,
CursorStyle, DefiniteLength, Edges, EdgesRefinement, ElementContext, Font, FontFeatures, CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures, FontStyle, FontWeight,
FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba, SharedString, Size, Hsla, Length, Pixels, Point, PointRefinement, Rgba, SharedString, Size, SizeRefinement, Styled,
SizeRefinement, Styled, TextRun, TextRun, WindowContext,
}; };
use collections::HashSet; use collections::HashSet;
use refineable::Refineable; use refineable::Refineable;
@ -391,8 +391,8 @@ impl Style {
pub fn paint( pub fn paint(
&self, &self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
continuation: impl FnOnce(&mut ElementContext), continuation: impl FnOnce(&mut WindowContext),
) { ) {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
if self.debug_below { if self.debug_below {

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
black, fill, point, px, size, Bounds, ElementContext, Hsla, LineLayout, Pixels, Point, Result, black, fill, point, px, size, Bounds, Hsla, LineLayout, Pixels, Point, Result, SharedString,
SharedString, StrikethroughStyle, UnderlineStyle, WrapBoundary, WrappedLineLayout, StrikethroughStyle, UnderlineStyle, WindowContext, WrapBoundary, WrappedLineLayout,
}; };
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use smallvec::SmallVec; use smallvec::SmallVec;
@ -48,7 +48,7 @@ impl ShapedLine {
&self, &self,
origin: Point<Pixels>, origin: Point<Pixels>,
line_height: Pixels, line_height: Pixels,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Result<()> { ) -> Result<()> {
paint_line( paint_line(
origin, origin,
@ -86,7 +86,7 @@ impl WrappedLine {
&self, &self,
origin: Point<Pixels>, origin: Point<Pixels>,
line_height: Pixels, line_height: Pixels,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Result<()> { ) -> Result<()> {
paint_line( paint_line(
origin, origin,
@ -107,7 +107,7 @@ fn paint_line(
line_height: Pixels, line_height: Pixels,
decoration_runs: &[DecorationRun], decoration_runs: &[DecorationRun],
wrap_boundaries: &[WrapBoundary], wrap_boundaries: &[WrapBoundary],
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Result<()> { ) -> Result<()> {
let line_bounds = Bounds::new(origin, size(layout.width, line_height)); let line_bounds = Bounds::new(origin, size(layout.width, line_height));
cx.paint_layer(line_bounds, |cx| { cx.paint_layer(line_bounds, |cx| {

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
seal::Sealed, AnyElement, AnyModel, AnyWeakModel, AppContext, Bounds, ContentMask, Element, seal::Sealed, AnyElement, AnyModel, AnyWeakModel, AppContext, Bounds, ContentMask, Element,
ElementContext, ElementId, Entity, EntityId, Flatten, FocusHandle, FocusableView, IntoElement, ElementId, Entity, EntityId, Flatten, FocusHandle, FocusableView, IntoElement, LayoutId, Model,
LayoutId, Model, PaintIndex, Pixels, PrepaintStateIndex, Render, Style, StyleRefinement, PaintIndex, Pixels, PrepaintStateIndex, Render, Style, StyleRefinement, TextStyle, ViewContext,
TextStyle, ViewContext, VisualContext, WeakModel, VisualContext, WeakModel, WindowContext,
}; };
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use refineable::Refineable; use refineable::Refineable;
@ -93,7 +93,7 @@ impl<V: Render> Element for View<V> {
type RequestLayoutState = AnyElement; type RequestLayoutState = AnyElement;
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
cx.with_element_id(Some(ElementId::View(self.entity_id())), |cx| { cx.with_element_id(Some(ElementId::View(self.entity_id())), |cx| {
let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element()); let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.request_layout(cx); let layout_id = element.request_layout(cx);
@ -105,7 +105,7 @@ impl<V: Render> Element for View<V> {
&mut self, &mut self,
_: Bounds<Pixels>, _: Bounds<Pixels>,
element: &mut Self::RequestLayoutState, element: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
cx.set_view_id(self.entity_id()); cx.set_view_id(self.entity_id());
cx.with_element_id(Some(ElementId::View(self.entity_id())), |cx| { cx.with_element_id(Some(ElementId::View(self.entity_id())), |cx| {
@ -118,7 +118,7 @@ impl<V: Render> Element for View<V> {
_: Bounds<Pixels>, _: Bounds<Pixels>,
element: &mut Self::RequestLayoutState, element: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
cx.with_element_id(Some(ElementId::View(self.entity_id())), |cx| { cx.with_element_id(Some(ElementId::View(self.entity_id())), |cx| {
element.paint(cx) element.paint(cx)
@ -220,7 +220,7 @@ impl<V> Eq for WeakView<V> {}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct AnyView { pub struct AnyView {
model: AnyModel, model: AnyModel,
render: fn(&AnyView, &mut ElementContext) -> AnyElement, render: fn(&AnyView, &mut WindowContext) -> AnyElement,
cached_style: Option<StyleRefinement>, cached_style: Option<StyleRefinement>,
} }
@ -279,7 +279,7 @@ impl Element for AnyView {
type RequestLayoutState = Option<AnyElement>; type RequestLayoutState = Option<AnyElement>;
type PrepaintState = Option<AnyElement>; type PrepaintState = Option<AnyElement>;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
if let Some(style) = self.cached_style.as_ref() { if let Some(style) = self.cached_style.as_ref() {
let mut root_style = Style::default(); let mut root_style = Style::default();
root_style.refine(style); root_style.refine(style);
@ -298,7 +298,7 @@ impl Element for AnyView {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
element: &mut Self::RequestLayoutState, element: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<AnyElement> { ) -> Option<AnyElement> {
cx.set_view_id(self.entity_id()); cx.set_view_id(self.entity_id());
if self.cached_style.is_some() { if self.cached_style.is_some() {
@ -359,7 +359,7 @@ impl Element for AnyView {
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
element: &mut Self::PrepaintState, element: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
if self.cached_style.is_some() { if self.cached_style.is_some() {
cx.with_element_state::<AnyViewState, _>( cx.with_element_state::<AnyViewState, _>(
@ -408,7 +408,7 @@ impl IntoElement for AnyView {
/// A weak, dynamically-typed view handle that does not prevent the view from being released. /// A weak, dynamically-typed view handle that does not prevent the view from being released.
pub struct AnyWeakView { pub struct AnyWeakView {
model: AnyWeakModel, model: AnyWeakModel,
render: fn(&AnyView, &mut ElementContext) -> AnyElement, render: fn(&AnyView, &mut WindowContext) -> AnyElement,
} }
impl AnyWeakView { impl AnyWeakView {
@ -447,11 +447,11 @@ impl std::fmt::Debug for AnyWeakView {
} }
mod any_view { mod any_view {
use crate::{AnyElement, AnyView, ElementContext, IntoElement, Render}; use crate::{AnyElement, AnyView, IntoElement, Render, WindowContext};
pub(crate) fn render<V: 'static + Render>( pub(crate) fn render<V: 'static + Render>(
view: &AnyView, view: &AnyView,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> AnyElement { ) -> AnyElement {
let view = view.clone().downcast::<V>().unwrap(); let view = view.clone().downcast::<V>().unwrap();
view.update(cx, |view, cx| view.render(cx).into_any_element()) view.update(cx, |view, cx| view.render(cx).into_any_element())

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -155,7 +155,7 @@ impl FocusableView for ImageView {
impl Render for ImageView { impl Render for ImageView {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let checkered_background = |bounds: Bounds<Pixels>, _, cx: &mut ElementContext| { let checkered_background = |bounds: Bounds<Pixels>, _, cx: &mut WindowContext| {
let square_size = 32.0; let square_size = 32.0;
let start_y = bounds.origin.y.0; let start_y = bounds.origin.y.0;

View File

@ -1,11 +1,11 @@
use editor::{CursorLayout, HighlightedRange, HighlightedRangeLine}; use editor::{CursorLayout, HighlightedRange, HighlightedRangeLine};
use gpui::{ use gpui::{
div, fill, point, px, relative, AnyElement, Bounds, DispatchPhase, Element, ElementContext, div, fill, point, px, relative, AnyElement, Bounds, DispatchPhase, Element, FocusHandle, Font,
FocusHandle, Font, FontStyle, FontWeight, HighlightStyle, Hitbox, Hsla, InputHandler, FontStyle, FontWeight, HighlightStyle, Hitbox, Hsla, InputHandler, InteractiveElement,
InteractiveElement, Interactivity, IntoElement, LayoutId, Model, ModelContext, Interactivity, IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton,
ModifiersChangedEvent, MouseButton, MouseMoveEvent, Pixels, Point, ShapedLine, MouseMoveEvent, Pixels, Point, ShapedLine, StatefulInteractiveElement, StrikethroughStyle,
StatefulInteractiveElement, StrikethroughStyle, Styled, TextRun, TextStyle, UnderlineStyle, Styled, TextRun, TextStyle, UnderlineStyle, WeakView, WhiteSpace, WindowContext,
WeakView, WhiteSpace, WindowContext, WindowTextSystem, WindowTextSystem,
}; };
use itertools::Itertools; use itertools::Itertools;
use language::CursorShape; use language::CursorShape;
@ -85,7 +85,7 @@ impl LayoutCell {
origin: Point<Pixels>, origin: Point<Pixels>,
layout: &LayoutState, layout: &LayoutState,
_visible_bounds: Bounds<Pixels>, _visible_bounds: Bounds<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let pos = { let pos = {
let point = self.point; let point = self.point;
@ -124,7 +124,7 @@ impl LayoutRect {
} }
} }
fn paint(&self, origin: Point<Pixels>, layout: &LayoutState, cx: &mut ElementContext) { fn paint(&self, origin: Point<Pixels>, layout: &LayoutState, cx: &mut WindowContext) {
let position = { let position = {
let alac_point = self.point; let alac_point = self.point;
point( point(
@ -418,7 +418,7 @@ impl TerminalElement {
origin: Point<Pixels>, origin: Point<Pixels>,
mode: TermMode, mode: TermMode,
hitbox: &Hitbox, hitbox: &Hitbox,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
let focus = self.focus.clone(); let focus = self.focus.clone();
let terminal = self.terminal.clone(); let terminal = self.terminal.clone();
@ -544,7 +544,7 @@ impl Element for TerminalElement {
type RequestLayoutState = (); type RequestLayoutState = ();
type PrepaintState = LayoutState; type PrepaintState = LayoutState;
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
self.interactivity.occlude_mouse(); self.interactivity.occlude_mouse();
let layout_id = self.interactivity.request_layout(cx, |mut style, cx| { let layout_id = self.interactivity.request_layout(cx, |mut style, cx| {
style.size.width = relative(1.).into(); style.size.width = relative(1.).into();
@ -560,7 +560,7 @@ impl Element for TerminalElement {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Self::PrepaintState { ) -> Self::PrepaintState {
self.interactivity self.interactivity
.prepaint(bounds, bounds.size, cx, |_, _, hitbox, cx| { .prepaint(bounds, bounds.size, cx, |_, _, hitbox, cx| {
@ -777,7 +777,7 @@ impl Element for TerminalElement {
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
layout: &mut Self::PrepaintState, layout: &mut Self::PrepaintState,
cx: &mut ElementContext<'_>, cx: &mut WindowContext<'_>,
) { ) {
cx.paint_quad(fill(bounds, layout.background_color)); cx.paint_quad(fill(bounds, layout.background_color));
let origin = bounds.origin + Point::new(layout.gutter, px(0.)); let origin = bounds.origin + Point::new(layout.gutter, px(0.));

View File

@ -2,9 +2,9 @@ use std::{cell::RefCell, rc::Rc};
use gpui::{ use gpui::{
anchored, deferred, div, point, prelude::FluentBuilder, px, AnchorCorner, AnyElement, Bounds, anchored, deferred, div, point, prelude::FluentBuilder, px, AnchorCorner, AnyElement, Bounds,
DismissEvent, DispatchPhase, Element, ElementContext, ElementId, HitboxId, InteractiveElement, DismissEvent, DispatchPhase, Element, ElementId, HitboxId, InteractiveElement, IntoElement,
IntoElement, LayoutId, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View, LayoutId, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext,
VisualContext, WindowContext, WindowContext,
}; };
use crate::prelude::*; use crate::prelude::*;
@ -112,8 +112,8 @@ impl<M: ManagedView> PopoverMenu<M> {
fn with_element_state<R>( fn with_element_state<R>(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
f: impl FnOnce(&mut Self, &mut PopoverMenuElementState<M>, &mut ElementContext) -> R, f: impl FnOnce(&mut Self, &mut PopoverMenuElementState<M>, &mut WindowContext) -> R,
) -> R { ) -> R {
cx.with_element_state::<PopoverMenuElementState<M>, _>( cx.with_element_state::<PopoverMenuElementState<M>, _>(
Some(self.id.clone()), Some(self.id.clone()),
@ -173,7 +173,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> (gpui::LayoutId, Self::RequestLayoutState) { ) -> (gpui::LayoutId, Self::RequestLayoutState) {
self.with_element_state(cx, |this, element_state, cx| { self.with_element_state(cx, |this, element_state, cx| {
let mut menu_layout_id = None; let mut menu_layout_id = None;
@ -221,7 +221,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
&mut self, &mut self,
_bounds: Bounds<Pixels>, _bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Option<HitboxId> { ) -> Option<HitboxId> {
self.with_element_state(cx, |_this, element_state, cx| { self.with_element_state(cx, |_this, element_state, cx| {
if let Some(child) = request_layout.child_element.as_mut() { if let Some(child) = request_layout.child_element.as_mut() {
@ -245,7 +245,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
_: Bounds<gpui::Pixels>, _: Bounds<gpui::Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
child_hitbox: &mut Option<HitboxId>, child_hitbox: &mut Option<HitboxId>,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.with_element_state(cx, |_this, _element_state, cx| { self.with_element_state(cx, |_this, _element_state, cx| {
if let Some(mut child) = request_layout.child_element.take() { if let Some(mut child) = request_layout.child_element.take() {

View File

@ -2,9 +2,8 @@ use std::{cell::RefCell, rc::Rc};
use gpui::{ use gpui::{
anchored, deferred, div, AnchorCorner, AnyElement, Bounds, DismissEvent, DispatchPhase, anchored, deferred, div, AnchorCorner, AnyElement, Bounds, DismissEvent, DispatchPhase,
Element, ElementContext, ElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, Element, ElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, ManagedView,
ManagedView, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, WindowContext,
WindowContext,
}; };
pub struct RightClickMenu<M: ManagedView> { pub struct RightClickMenu<M: ManagedView> {
@ -41,8 +40,8 @@ impl<M: ManagedView> RightClickMenu<M> {
fn with_element_state<R>( fn with_element_state<R>(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
f: impl FnOnce(&mut Self, &mut MenuHandleElementState<M>, &mut ElementContext) -> R, f: impl FnOnce(&mut Self, &mut MenuHandleElementState<M>, &mut WindowContext) -> R,
) -> R { ) -> R {
cx.with_element_state::<MenuHandleElementState<M>, _>( cx.with_element_state::<MenuHandleElementState<M>, _>(
Some(self.id.clone()), Some(self.id.clone()),
@ -89,19 +88,24 @@ impl<M> Default for MenuHandleElementState<M> {
} }
} }
pub struct MenuHandleFrameState { pub struct RequestLayoutState {
child_layout_id: Option<LayoutId>, child_layout_id: Option<LayoutId>,
child_element: Option<AnyElement>, child_element: Option<AnyElement>,
menu_element: Option<AnyElement>, menu_element: Option<AnyElement>,
} }
pub struct PrepaintState {
hitbox: Hitbox,
child_bounds: Option<Bounds<Pixels>>,
}
impl<M: ManagedView> Element for RightClickMenu<M> { impl<M: ManagedView> Element for RightClickMenu<M> {
type RequestLayoutState = MenuHandleFrameState; type RequestLayoutState = RequestLayoutState;
type PrepaintState = Hitbox; type PrepaintState = PrepaintState;
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> (gpui::LayoutId, Self::RequestLayoutState) { ) -> (gpui::LayoutId, Self::RequestLayoutState) {
self.with_element_state(cx, |this, element_state, cx| { self.with_element_state(cx, |this, element_state, cx| {
let mut menu_layout_id = None; let mut menu_layout_id = None;
@ -137,7 +141,7 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
( (
layout_id, layout_id,
MenuHandleFrameState { RequestLayoutState {
child_element, child_element,
child_layout_id, child_layout_id,
menu_element, menu_element,
@ -150,8 +154,8 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> Hitbox { ) -> PrepaintState {
cx.with_element_id(Some(self.id.clone()), |cx| { cx.with_element_id(Some(self.id.clone()), |cx| {
let hitbox = cx.insert_hitbox(bounds, false); let hitbox = cx.insert_hitbox(bounds, false);
@ -163,7 +167,12 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
menu.prepaint(cx); menu.prepaint(cx);
} }
hitbox PrepaintState {
hitbox,
child_bounds: request_layout
.child_layout_id
.map(|layout_id| cx.layout_bounds(layout_id)),
}
}) })
} }
@ -171,8 +180,8 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
&mut self, &mut self,
_bounds: Bounds<gpui::Pixels>, _bounds: Bounds<gpui::Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
hitbox: &mut Self::PrepaintState, prepaint_state: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
self.with_element_state(cx, |this, element_state, cx| { self.with_element_state(cx, |this, element_state, cx| {
if let Some(mut child) = request_layout.child_element.take() { if let Some(mut child) = request_layout.child_element.take() {
@ -191,10 +200,9 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
let attach = this.attach; let attach = this.attach;
let menu = element_state.menu.clone(); let menu = element_state.menu.clone();
let position = element_state.position.clone(); let position = element_state.position.clone();
let child_layout_id = request_layout.child_layout_id; let child_bounds = prepaint_state.child_bounds;
let child_bounds = cx.layout_bounds(child_layout_id.unwrap());
let hitbox_id = hitbox.id; let hitbox_id = prepaint_state.hitbox.id;
cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| { cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
if phase == DispatchPhase::Bubble if phase == DispatchPhase::Bubble
&& event.button == MouseButton::Right && event.button == MouseButton::Right
@ -219,7 +227,7 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
.detach(); .detach();
cx.focus_view(&new_menu); cx.focus_view(&new_menu);
*menu.borrow_mut() = Some(new_menu); *menu.borrow_mut() = Some(new_menu);
*position.borrow_mut() = if child_layout_id.is_some() { *position.borrow_mut() = if let Some(child_bounds) = child_bounds {
if let Some(attach) = attach { if let Some(attach) = attach {
attach.corner(child_bounds) attach.corner(child_bounds)
} else { } else {

View File

@ -2,9 +2,9 @@
pub use gpui::prelude::*; pub use gpui::prelude::*;
pub use gpui::{ pub use gpui::{
div, px, relative, rems, AbsoluteLength, DefiniteLength, Div, Element, ElementContext, div, px, relative, rems, AbsoluteLength, DefiniteLength, Div, Element, ElementId,
ElementId, InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString, Styled, InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString, Styled, ViewContext,
ViewContext, WindowContext, WindowContext,
}; };
pub use crate::clickable::*; pub use crate::clickable::*;

View File

@ -759,7 +759,7 @@ mod element {
fn layout_handle( fn layout_handle(
axis: Axis, axis: Axis,
pane_bounds: Bounds<Pixels>, pane_bounds: Bounds<Pixels>,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> PaneAxisHandleLayout { ) -> PaneAxisHandleLayout {
let handle_bounds = Bounds { let handle_bounds = Bounds {
origin: pane_bounds.origin.apply_along(axis, |origin| { origin: pane_bounds.origin.apply_along(axis, |origin| {
@ -797,7 +797,7 @@ mod element {
fn request_layout( fn request_layout(
&mut self, &mut self,
cx: &mut ui::prelude::ElementContext, cx: &mut ui::prelude::WindowContext,
) -> (gpui::LayoutId, Self::RequestLayoutState) { ) -> (gpui::LayoutId, Self::RequestLayoutState) {
let mut style = Style::default(); let mut style = Style::default();
style.flex_grow = 1.; style.flex_grow = 1.;
@ -812,7 +812,7 @@ mod element {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
_state: &mut Self::RequestLayoutState, _state: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) -> PaneAxisLayout { ) -> PaneAxisLayout {
let dragged_handle = cx.with_element_state::<Rc<RefCell<Option<usize>>>, _>( let dragged_handle = cx.with_element_state::<Rc<RefCell<Option<usize>>>, _>(
Some(self.basis.into()), Some(self.basis.into()),
@ -900,7 +900,7 @@ mod element {
bounds: gpui::Bounds<ui::prelude::Pixels>, bounds: gpui::Bounds<ui::prelude::Pixels>,
_: &mut Self::RequestLayoutState, _: &mut Self::RequestLayoutState,
layout: &mut Self::PrepaintState, layout: &mut Self::PrepaintState,
cx: &mut ui::prelude::ElementContext, cx: &mut ui::prelude::WindowContext,
) { ) {
for child in &mut layout.children { for child in &mut layout.children {
child.element.paint(cx); child.element.paint(cx);

View File

@ -78,9 +78,9 @@ use theme::{ActiveTheme, SystemAppearance, ThemeSettings};
pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView}; pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
pub use ui; pub use ui;
use ui::{ use ui::{
div, h_flex, Context as _, Div, Element, ElementContext, FluentBuilder, div, h_flex, Context as _, Div, Element, FluentBuilder, InteractiveElement as _, IntoElement,
InteractiveElement as _, IntoElement, Label, ParentElement as _, Pixels, SharedString, Label, ParentElement as _, Pixels, SharedString, Styled as _, ViewContext, VisualContext as _,
Styled as _, ViewContext, VisualContext as _, WindowContext, WindowContext,
}; };
use util::{maybe, ResultExt}; use util::{maybe, ResultExt};
use uuid::Uuid; use uuid::Uuid;
@ -4991,7 +4991,7 @@ impl Element for DisconnectedOverlay {
type RequestLayoutState = AnyElement; type RequestLayoutState = AnyElement;
type PrepaintState = (); type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, Self::RequestLayoutState) { fn request_layout(&mut self, cx: &mut WindowContext) -> (LayoutId, Self::RequestLayoutState) {
let mut background = cx.theme().colors().elevated_surface_background; let mut background = cx.theme().colors().elevated_surface_background;
background.fade_out(0.2); background.fade_out(0.2);
let mut overlay = div() let mut overlay = div()
@ -5016,7 +5016,7 @@ impl Element for DisconnectedOverlay {
&mut self, &mut self,
bounds: Bounds<Pixels>, bounds: Bounds<Pixels>,
overlay: &mut Self::RequestLayoutState, overlay: &mut Self::RequestLayoutState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
cx.insert_hitbox(bounds, true); cx.insert_hitbox(bounds, true);
overlay.prepaint(cx); overlay.prepaint(cx);
@ -5027,7 +5027,7 @@ impl Element for DisconnectedOverlay {
_: Bounds<Pixels>, _: Bounds<Pixels>,
overlay: &mut Self::RequestLayoutState, overlay: &mut Self::RequestLayoutState,
_: &mut Self::PrepaintState, _: &mut Self::PrepaintState,
cx: &mut ElementContext, cx: &mut WindowContext,
) { ) {
overlay.paint(cx) overlay.paint(cx)
} }