diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 9bb1c2735f..424351ebfc 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -31,7 +31,7 @@ use gpui::{ text_layout::{self, Line, RunStyle, TextLayoutCache}, AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, LayoutContext, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, MutableAppContext, - PaintContext, Quad, Scene, SizeConstraint, ViewContext, WeakViewHandle, + PaintContext, Quad, SceneBuilder, SizeConstraint, ViewContext, WeakViewHandle, }; use json::json; use language::{Bias, CursorShape, DiagnosticSeverity, OffsetUtf16, Point, Selection}; @@ -2189,7 +2189,7 @@ pub struct HighlightedRangeLine { } impl HighlightedRange { - pub fn paint(&self, bounds: RectF, scene: &mut Scene) { + pub fn paint(&self, bounds: RectF, scene: &mut SceneBuilder) { 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, scene); self.paint_lines( @@ -2208,7 +2208,7 @@ impl HighlightedRange { start_y: f32, lines: &[HighlightedRangeLine], bounds: RectF, - scene: &mut Scene, + scene: &mut SceneBuilder, ) { if lines.is_empty() { return; @@ -2375,7 +2375,7 @@ mod tests { let mut element = EditorElement::new(editor.downgrade(), editor.read(cx).style(cx)); - let mut scene = Scene::new(1.0); + let mut scene = SceneBuilder::new(1.0); let mut presenter = cx.build_presenter(window_id, 30., Default::default()); let mut layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx); let (size, mut state) = element.layout( diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 4cca93edc8..d8b446ac17 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -16,7 +16,7 @@ pub mod fonts; pub mod geometry; mod presenter; pub mod scene; -pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene}; +pub use scene::{Border, CursorRegion, MouseRegion, MouseRegionId, Quad, Scene, SceneBuilder}; pub mod text_layout; pub use text_layout::TextLayoutCache; mod util; diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 71803a4cf0..b0a8d37301 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -8,13 +8,14 @@ use crate::{ platform::{CursorStyle, Event}, scene::{ CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, - MouseMove, MouseScrollWheel, MouseUp, MouseUpOut, + MouseMove, MouseScrollWheel, MouseUp, MouseUpOut, Scene, }, text_layout::TextLayoutCache, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, Appearance, AssetCache, ElementBox, Entity, FontSystem, ModelHandle, MouseButton, MouseMovedEvent, - MouseRegion, MouseRegionId, ParentId, ReadModel, ReadView, RenderContext, RenderParams, Scene, - UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle, + MouseRegion, MouseRegionId, ParentId, ReadModel, ReadView, RenderContext, RenderParams, + SceneBuilder, UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, + WeakViewHandle, }; use collections::{HashMap, HashSet}; use pathfinder_geometry::vector::{vec2f, Vector2F}; @@ -135,17 +136,18 @@ impl Presenter { refreshing: bool, cx: &mut MutableAppContext, ) -> Scene { - let mut scene = Scene::new(scale_factor); + let mut scene_builder = SceneBuilder::new(scale_factor); if let Some(root_view_id) = cx.root_view_id(self.window_id) { self.layout(window_size, refreshing, cx); - let mut paint_cx = self.build_paint_context(&mut scene, window_size, cx); + let mut paint_cx = self.build_paint_context(&mut scene_builder, window_size, cx); paint_cx.paint( root_view_id, Vector2F::zero(), RectF::new(Vector2F::zero(), window_size), ); self.text_layout_cache.finish_frame(); + let scene = scene_builder.build(); self.cursor_regions = scene.cursor_regions(); self.mouse_regions = scene.mouse_regions(); @@ -154,11 +156,12 @@ impl Presenter { self.dispatch_event(event, true, cx); } } + + scene } else { log::error!("could not find root_view_id for window {}", self.window_id); + scene_builder.build() } - - scene } fn layout(&mut self, window_size: Vector2F, refreshing: bool, cx: &mut MutableAppContext) { @@ -196,7 +199,7 @@ impl Presenter { pub fn build_paint_context<'a>( &'a mut self, - scene: &'a mut Scene, + scene: &'a mut SceneBuilder, window_size: Vector2F, cx: &'a mut MutableAppContext, ) -> PaintContext { @@ -689,7 +692,7 @@ pub struct PaintContext<'a> { rendered_views: &'a mut HashMap, view_stack: Vec, pub window_size: Vector2F, - pub scene: &'a mut Scene, + pub scene: &'a mut SceneBuilder, pub font_cache: &'a FontCache, pub text_layout_cache: &'a TextLayoutCache, pub app: &'a AppContext, diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index 99b38a1852..9dd9e6bf21 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -18,7 +18,7 @@ use crate::{ pub use mouse_event::*; pub use mouse_region::*; -pub struct Scene { +pub struct SceneBuilder { scale_factor: f32, stacking_contexts: Vec, active_stacking_context_stack: Vec, @@ -176,18 +176,12 @@ pub struct Image { pub data: Arc, } -impl Scene { - pub fn new(scale_factor: f32) -> Self { - let stacking_context = StackingContext::new(0, None); - Scene { - scale_factor, - stacking_contexts: vec![stacking_context], - active_stacking_context_stack: vec![0], - #[cfg(debug_assertions)] - mouse_region_ids: Default::default(), - } - } +pub struct Scene { + scale_factor: f32, + stacking_contexts: Vec, +} +impl Scene { pub fn scale_factor(&self) -> f32 { self.scale_factor } @@ -204,16 +198,41 @@ impl Scene { } pub fn mouse_regions(&self) -> Vec<(MouseRegion, usize)> { - let mut regions = Vec::new(); - for stacking_context in self.stacking_contexts.iter() { - for layer in &stacking_context.layers { - for mouse_region in &layer.mouse_regions { - regions.push((mouse_region.clone(), stacking_context.depth)); - } - } + self.stacking_contexts + .iter() + .flat_map(|context| { + context + .layers + .iter() + .flat_map(|layer| &layer.mouse_regions) + .map(|region| (region.clone(), context.depth)) + }) + .collect() + } +} + +impl SceneBuilder { + pub fn new(scale_factor: f32) -> Self { + let stacking_context = StackingContext::new(0, None); + SceneBuilder { + scale_factor, + stacking_contexts: vec![stacking_context], + active_stacking_context_stack: vec![0], + #[cfg(debug_assertions)] + mouse_region_ids: Default::default(), } - regions.sort_by_key(|(_, depth)| *depth); - regions + } + + pub fn build(mut self) -> Scene { + self.stacking_contexts.sort_by_key(|context| context.depth); + Scene { + scale_factor: self.scale_factor, + stacking_contexts: self.stacking_contexts, + } + } + + pub fn scale_factor(&self) -> f32 { + self.scale_factor } pub fn push_stacking_context(&mut self, clip_bounds: Option) {