Create a SceneBuilder and sort stacking contexts when calling build

This commit is contained in:
Antonio Scandurra 2022-10-25 12:16:09 +02:00
parent c1f7ac0d8c
commit 6a4f3aaa56
4 changed files with 57 additions and 35 deletions

View file

@ -31,7 +31,7 @@ use gpui::{
text_layout::{self, Line, RunStyle, TextLayoutCache}, text_layout::{self, Line, RunStyle, TextLayoutCache},
AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, LayoutContext, AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, LayoutContext,
Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, MutableAppContext, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, MutableAppContext,
PaintContext, Quad, Scene, SizeConstraint, ViewContext, WeakViewHandle, PaintContext, Quad, SceneBuilder, SizeConstraint, ViewContext, WeakViewHandle,
}; };
use json::json; use json::json;
use language::{Bias, CursorShape, DiagnosticSeverity, OffsetUtf16, Point, Selection}; use language::{Bias, CursorShape, DiagnosticSeverity, OffsetUtf16, Point, Selection};
@ -2189,7 +2189,7 @@ pub struct HighlightedRangeLine {
} }
impl HighlightedRange { 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 { 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(self.start_y, &self.lines[0..1], bounds, scene);
self.paint_lines( self.paint_lines(
@ -2208,7 +2208,7 @@ impl HighlightedRange {
start_y: f32, start_y: f32,
lines: &[HighlightedRangeLine], lines: &[HighlightedRangeLine],
bounds: RectF, bounds: RectF,
scene: &mut Scene, scene: &mut SceneBuilder,
) { ) {
if lines.is_empty() { if lines.is_empty() {
return; return;
@ -2375,7 +2375,7 @@ mod tests {
let mut element = EditorElement::new(editor.downgrade(), editor.read(cx).style(cx)); 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 presenter = cx.build_presenter(window_id, 30., Default::default());
let mut layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx); let mut layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx);
let (size, mut state) = element.layout( let (size, mut state) = element.layout(

View file

@ -16,7 +16,7 @@ pub mod fonts;
pub mod geometry; pub mod geometry;
mod presenter; mod presenter;
pub mod scene; 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 mod text_layout;
pub use text_layout::TextLayoutCache; pub use text_layout::TextLayoutCache;
mod util; mod util;

View file

@ -8,13 +8,14 @@ use crate::{
platform::{CursorStyle, Event}, platform::{CursorStyle, Event},
scene::{ scene::{
CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover,
MouseMove, MouseScrollWheel, MouseUp, MouseUpOut, MouseMove, MouseScrollWheel, MouseUp, MouseUpOut, Scene,
}, },
text_layout::TextLayoutCache, text_layout::TextLayoutCache,
Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, Appearance, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, Appearance,
AssetCache, ElementBox, Entity, FontSystem, ModelHandle, MouseButton, MouseMovedEvent, AssetCache, ElementBox, Entity, FontSystem, ModelHandle, MouseButton, MouseMovedEvent,
MouseRegion, MouseRegionId, ParentId, ReadModel, ReadView, RenderContext, RenderParams, Scene, MouseRegion, MouseRegionId, ParentId, ReadModel, ReadView, RenderContext, RenderParams,
UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle, SceneBuilder, UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle,
WeakViewHandle,
}; };
use collections::{HashMap, HashSet}; use collections::{HashMap, HashSet};
use pathfinder_geometry::vector::{vec2f, Vector2F}; use pathfinder_geometry::vector::{vec2f, Vector2F};
@ -135,17 +136,18 @@ impl Presenter {
refreshing: bool, refreshing: bool,
cx: &mut MutableAppContext, cx: &mut MutableAppContext,
) -> Scene { ) -> 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) { if let Some(root_view_id) = cx.root_view_id(self.window_id) {
self.layout(window_size, refreshing, cx); 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( paint_cx.paint(
root_view_id, root_view_id,
Vector2F::zero(), Vector2F::zero(),
RectF::new(Vector2F::zero(), window_size), RectF::new(Vector2F::zero(), window_size),
); );
self.text_layout_cache.finish_frame(); self.text_layout_cache.finish_frame();
let scene = scene_builder.build();
self.cursor_regions = scene.cursor_regions(); self.cursor_regions = scene.cursor_regions();
self.mouse_regions = scene.mouse_regions(); self.mouse_regions = scene.mouse_regions();
@ -154,11 +156,12 @@ impl Presenter {
self.dispatch_event(event, true, cx); self.dispatch_event(event, true, cx);
} }
} }
scene
} else { } else {
log::error!("could not find root_view_id for window {}", self.window_id); 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) { fn layout(&mut self, window_size: Vector2F, refreshing: bool, cx: &mut MutableAppContext) {
@ -196,7 +199,7 @@ impl Presenter {
pub fn build_paint_context<'a>( pub fn build_paint_context<'a>(
&'a mut self, &'a mut self,
scene: &'a mut Scene, scene: &'a mut SceneBuilder,
window_size: Vector2F, window_size: Vector2F,
cx: &'a mut MutableAppContext, cx: &'a mut MutableAppContext,
) -> PaintContext { ) -> PaintContext {
@ -689,7 +692,7 @@ pub struct PaintContext<'a> {
rendered_views: &'a mut HashMap<usize, ElementBox>, rendered_views: &'a mut HashMap<usize, ElementBox>,
view_stack: Vec<usize>, view_stack: Vec<usize>,
pub window_size: Vector2F, pub window_size: Vector2F,
pub scene: &'a mut Scene, pub scene: &'a mut SceneBuilder,
pub font_cache: &'a FontCache, pub font_cache: &'a FontCache,
pub text_layout_cache: &'a TextLayoutCache, pub text_layout_cache: &'a TextLayoutCache,
pub app: &'a AppContext, pub app: &'a AppContext,

View file

@ -18,7 +18,7 @@ use crate::{
pub use mouse_event::*; pub use mouse_event::*;
pub use mouse_region::*; pub use mouse_region::*;
pub struct Scene { pub struct SceneBuilder {
scale_factor: f32, scale_factor: f32,
stacking_contexts: Vec<StackingContext>, stacking_contexts: Vec<StackingContext>,
active_stacking_context_stack: Vec<usize>, active_stacking_context_stack: Vec<usize>,
@ -176,18 +176,12 @@ pub struct Image {
pub data: Arc<ImageData>, pub data: Arc<ImageData>,
} }
impl Scene { pub struct Scene {
pub fn new(scale_factor: f32) -> Self { scale_factor: f32,
let stacking_context = StackingContext::new(0, None); stacking_contexts: Vec<StackingContext>,
Scene { }
scale_factor,
stacking_contexts: vec![stacking_context],
active_stacking_context_stack: vec![0],
#[cfg(debug_assertions)]
mouse_region_ids: Default::default(),
}
}
impl Scene {
pub fn scale_factor(&self) -> f32 { pub fn scale_factor(&self) -> f32 {
self.scale_factor self.scale_factor
} }
@ -204,16 +198,41 @@ impl Scene {
} }
pub fn mouse_regions(&self) -> Vec<(MouseRegion, usize)> { pub fn mouse_regions(&self) -> Vec<(MouseRegion, usize)> {
let mut regions = Vec::new(); self.stacking_contexts
for stacking_context in self.stacking_contexts.iter() { .iter()
for layer in &stacking_context.layers { .flat_map(|context| {
for mouse_region in &layer.mouse_regions { context
regions.push((mouse_region.clone(), stacking_context.depth)); .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<RectF>) { pub fn push_stacking_context(&mut self, clip_bounds: Option<RectF>) {