Skip to main content

gpui_engine/
frame_session.rs

1//! The engine execution seam for a window frame.
2//!
3//! A `FrameSession` owns a frame's layout engine behind interior mutability, so
4//! the facade can drive it with `&self` without moving the engine out of the
5//! window to satisfy the borrow checker. The engine is a trait object, so the
6//! layout implementation is chosen by whoever builds the session rather than
7//! named here.
8//!
9//! The scene graph stays in the facade's double-buffered frame, and frame
10//! presentation stays in the facade because `PlatformWindow` lives above this
11//! crate.
12
13use crate::{BoxedMeasureFn, EngineLayoutStyle, LayoutEngine, LayoutId, MeasureContext};
14use gpui_types::{AvailableSpace, Bounds, Pixels, Size};
15use std::cell::RefCell;
16
17/// A window's layout engine session.
18pub struct FrameSession {
19    layout_engine: RefCell<Box<dyn LayoutEngine>>,
20}
21
22impl FrameSession {
23    /// Creates a session that drives `layout_engine`.
24    pub fn new(layout_engine: Box<dyn LayoutEngine>) -> Self {
25        Self {
26            layout_engine: RefCell::new(layout_engine),
27        }
28    }
29
30    /// Discards the layout tree and cached bounds, ready for a new frame.
31    pub fn clear(&self) {
32        self.layout_engine.borrow_mut().clear();
33    }
34
35    /// Adds a node built from `style`.
36    pub fn request_layout(
37        &self,
38        style: &EngineLayoutStyle,
39        rem_size: Pixels,
40        scale_factor: f32,
41        children: &[LayoutId],
42    ) -> LayoutId {
43        self.layout_engine
44            .borrow_mut()
45            .request_layout(style, rem_size, scale_factor, children)
46    }
47
48    /// Adds a leaf whose size is resolved by `measure` during layout.
49    pub fn request_measured_layout(
50        &self,
51        style: &EngineLayoutStyle,
52        rem_size: Pixels,
53        scale_factor: f32,
54        measure: BoxedMeasureFn,
55    ) -> LayoutId {
56        self.layout_engine.borrow_mut().request_measured_layout(
57            style,
58            rem_size,
59            scale_factor,
60            measure,
61        )
62    }
63
64    /// Treats any `auto` dimension of `id`'s style as filling `size`.
65    pub fn stretch_auto_size_to_fill(&self, id: LayoutId, size: Size<Pixels>, scale_factor: f32) {
66        self.layout_engine
67            .borrow_mut()
68            .stretch_auto_size_to_fill(id, size, scale_factor)
69    }
70
71    /// Computes the layout of `id` within `available_space`.
72    pub fn compute_layout(
73        &self,
74        id: LayoutId,
75        available_space: Size<AvailableSpace>,
76        scale_factor: f32,
77        context: &mut dyn MeasureContext,
78    ) {
79        self.layout_engine
80            .borrow_mut()
81            .compute_layout(id, available_space, scale_factor, context)
82    }
83
84    /// Returns the pixel-snapped bounds of `id` relative to the window.
85    pub fn layout_bounds(&self, id: LayoutId, scale_factor: f32) -> Bounds<Pixels> {
86        self.layout_engine
87            .borrow_mut()
88            .layout_bounds(id, scale_factor)
89    }
90}