element_cx.rs

  1use std::{
  2    any::{Any, TypeId},
  3    borrow::{Borrow, BorrowMut, Cow},
  4    mem,
  5    rc::Rc,
  6    sync::Arc,
  7};
  8
  9use anyhow::Result;
 10use derive_more::{Deref, DerefMut};
 11use media::core_video::CVImageBuffer;
 12use util::post_inc;
 13
 14use crate::{
 15    prelude::*, size, AppContext, AvailableSpace, Bounds, BoxShadow, ContentMask, Corners,
 16    DevicePixels, DispatchPhase, ElementId, ElementStateBox, EntityId, FocusHandle, FontId,
 17    GlyphId, Hsla, ImageData, InputHandler, IsZero, KeyContext, KeyEvent, LayoutId,
 18    MonochromeSprite, MouseEvent, PaintQuad, Path, Pixels, PlatformInputHandler, Point,
 19    PolychromeSprite, Quad, RenderGlyphParams, RenderImageParams, RenderSvgParams, Shadow,
 20    SharedString, Size, Style, Surface, Underline, UnderlineStyle, Window, WindowContext,
 21    SUBPIXEL_VARIANTS,
 22};
 23
 24use super::RequestedInputHandler;
 25
 26/// This context is used for assisting in the implementation of the element trait
 27#[derive(Deref, DerefMut)]
 28pub struct ElementContext<'a> {
 29    pub(crate) cx: WindowContext<'a>,
 30}
 31
 32impl<'a> WindowContext<'a> {
 33    pub fn with_element_context<R>(&mut self, f: impl FnOnce(&mut ElementContext) -> R) -> R {
 34        f(&mut ElementContext {
 35            cx: WindowContext::new(self.app, self.window),
 36        })
 37    }
 38}
 39
 40impl<'a> Borrow<AppContext> for ElementContext<'a> {
 41    fn borrow(&self) -> &AppContext {
 42        self.cx.app
 43    }
 44}
 45
 46impl<'a> BorrowMut<AppContext> for ElementContext<'a> {
 47    fn borrow_mut(&mut self) -> &mut AppContext {
 48        self.cx.borrow_mut()
 49    }
 50}
 51
 52impl<'a> Borrow<WindowContext<'a>> for ElementContext<'a> {
 53    fn borrow(&self) -> &WindowContext<'a> {
 54        &self.cx
 55    }
 56}
 57
 58impl<'a> BorrowMut<WindowContext<'a>> for ElementContext<'a> {
 59    fn borrow_mut(&mut self) -> &mut WindowContext<'a> {
 60        &mut self.cx
 61    }
 62}
 63
 64impl<'a> Borrow<Window> for ElementContext<'a> {
 65    fn borrow(&self) -> &Window {
 66        self.cx.window
 67    }
 68}
 69
 70impl<'a> BorrowMut<Window> for ElementContext<'a> {
 71    fn borrow_mut(&mut self) -> &mut Window {
 72        self.cx.borrow_mut()
 73    }
 74}
 75
 76impl<'a> Context for ElementContext<'a> {
 77    type Result<T> = <WindowContext<'a> as Context>::Result<T>;
 78
 79    fn new_model<T: 'static>(
 80        &mut self,
 81        build_model: impl FnOnce(&mut crate::ModelContext<'_, T>) -> T,
 82    ) -> Self::Result<crate::Model<T>> {
 83        self.cx.new_model(build_model)
 84    }
 85
 86    fn update_model<T, R>(
 87        &mut self,
 88        handle: &crate::Model<T>,
 89        update: impl FnOnce(&mut T, &mut crate::ModelContext<'_, T>) -> R,
 90    ) -> Self::Result<R>
 91    where
 92        T: 'static,
 93    {
 94        self.cx.update_model(handle, update)
 95    }
 96
 97    fn read_model<T, R>(
 98        &self,
 99        handle: &crate::Model<T>,
100        read: impl FnOnce(&T, &AppContext) -> R,
101    ) -> Self::Result<R>
102    where
103        T: 'static,
104    {
105        self.cx.read_model(handle, read)
106    }
107
108    fn update_window<T, F>(&mut self, window: crate::AnyWindowHandle, f: F) -> Result<T>
109    where
110        F: FnOnce(crate::AnyView, &mut WindowContext<'_>) -> T,
111    {
112        self.cx.update_window(window, f)
113    }
114
115    fn read_window<T, R>(
116        &self,
117        window: &crate::WindowHandle<T>,
118        read: impl FnOnce(crate::View<T>, &AppContext) -> R,
119    ) -> Result<R>
120    where
121        T: 'static,
122    {
123        self.cx.read_window(window, read)
124    }
125}
126
127impl<'a> VisualContext for ElementContext<'a> {
128    fn new_view<V>(
129        &mut self,
130        build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
131    ) -> Self::Result<crate::View<V>>
132    where
133        V: 'static + Render,
134    {
135        self.cx.new_view(build_view)
136    }
137
138    fn update_view<V: 'static, R>(
139        &mut self,
140        view: &crate::View<V>,
141        update: impl FnOnce(&mut V, &mut crate::ViewContext<'_, V>) -> R,
142    ) -> Self::Result<R> {
143        self.cx.update_view(view, update)
144    }
145
146    fn replace_root_view<V>(
147        &mut self,
148        build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
149    ) -> Self::Result<crate::View<V>>
150    where
151        V: 'static + Render,
152    {
153        self.cx.replace_root_view(build_view)
154    }
155
156    fn focus_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
157    where
158        V: crate::FocusableView,
159    {
160        self.cx.focus_view(view)
161    }
162
163    fn dismiss_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
164    where
165        V: crate::ManagedView,
166    {
167        self.cx.dismiss_view(view)
168    }
169}
170
171impl<'a> ElementContext<'a> {
172    /// Pushes the given element id onto the global stack and invokes the given closure
173    /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
174    /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
175    /// used to associate state with identified elements across separate frames.
176    pub fn with_element_id<R>(
177        &mut self,
178        id: Option<impl Into<ElementId>>,
179        f: impl FnOnce(&mut Self) -> R,
180    ) -> R {
181        if let Some(id) = id.map(Into::into) {
182            let window = self.window_mut();
183            window.element_id_stack.push(id);
184            let result = f(self);
185            let window: &mut Window = self.borrow_mut();
186            window.element_id_stack.pop();
187            result
188        } else {
189            f(self)
190        }
191    }
192
193    /// Invoke the given function with the given content mask after intersecting it
194    /// with the current mask.
195    pub fn with_content_mask<R>(
196        &mut self,
197        mask: Option<ContentMask<Pixels>>,
198        f: impl FnOnce(&mut Self) -> R,
199    ) -> R {
200        if let Some(mask) = mask {
201            let mask = mask.intersect(&self.content_mask());
202            self.window_mut().next_frame.content_mask_stack.push(mask);
203            let result = f(self);
204            self.window_mut().next_frame.content_mask_stack.pop();
205            result
206        } else {
207            f(self)
208        }
209    }
210
211    /// Invoke the given function with the content mask reset to that
212    /// of the window.
213    pub fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
214        let mask = ContentMask {
215            bounds: Bounds {
216                origin: Point::default(),
217                size: self.window().viewport_size,
218            },
219        };
220        let new_stacking_order_id =
221            post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
222        let new_root_z_index = post_inc(&mut self.window_mut().next_frame.next_root_z_index);
223        let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
224        self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
225        self.window_mut()
226            .next_frame
227            .z_index_stack
228            .push(new_root_z_index);
229        self.window_mut().next_frame.content_mask_stack.push(mask);
230        let result = f(self);
231        self.window_mut().next_frame.content_mask_stack.pop();
232        self.window_mut().next_frame.z_index_stack = old_stacking_order;
233        result
234    }
235
236    /// Called during painting to invoke the given closure in a new stacking context. The given
237    /// z-index is interpreted relative to the previous call to `stack`.
238    pub fn with_z_index<R>(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R {
239        let new_stacking_order_id =
240            post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
241        let old_stacking_order_id = mem::replace(
242            &mut self.window_mut().next_frame.z_index_stack.id,
243            new_stacking_order_id,
244        );
245        self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
246        self.window_mut().next_frame.z_index_stack.push(z_index);
247        let result = f(self);
248        self.window_mut().next_frame.z_index_stack.id = old_stacking_order_id;
249        self.window_mut().next_frame.z_index_stack.pop();
250        result
251    }
252
253    /// Updates the global element offset relative to the current offset. This is used to implement
254    /// scrolling.
255    pub fn with_element_offset<R>(
256        &mut self,
257        offset: Point<Pixels>,
258        f: impl FnOnce(&mut Self) -> R,
259    ) -> R {
260        if offset.is_zero() {
261            return f(self);
262        };
263
264        let abs_offset = self.element_offset() + offset;
265        self.with_absolute_element_offset(abs_offset, f)
266    }
267
268    /// Updates the global element offset based on the given offset. This is used to implement
269    /// drag handles and other manual painting of elements.
270    pub fn with_absolute_element_offset<R>(
271        &mut self,
272        offset: Point<Pixels>,
273        f: impl FnOnce(&mut Self) -> R,
274    ) -> R {
275        self.window_mut()
276            .next_frame
277            .element_offset_stack
278            .push(offset);
279        let result = f(self);
280        self.window_mut().next_frame.element_offset_stack.pop();
281        result
282    }
283
284    /// Obtain the current element offset.
285    pub fn element_offset(&self) -> Point<Pixels> {
286        self.window()
287            .next_frame
288            .element_offset_stack
289            .last()
290            .copied()
291            .unwrap_or_default()
292    }
293
294    /// Obtain the current content mask.
295    pub fn content_mask(&self) -> ContentMask<Pixels> {
296        self.window()
297            .next_frame
298            .content_mask_stack
299            .last()
300            .cloned()
301            .unwrap_or_else(|| ContentMask {
302                bounds: Bounds {
303                    origin: Point::default(),
304                    size: self.window().viewport_size,
305                },
306            })
307    }
308
309    /// The size of an em for the base font of the application. Adjusting this value allows the
310    /// UI to scale, just like zooming a web page.
311    pub fn rem_size(&self) -> Pixels {
312        self.window().rem_size
313    }
314
315    /// Updates or initializes state for an element with the given id that lives across multiple
316    /// frames. If an element with this ID existed in the rendered frame, its state will be passed
317    /// to the given closure. The state returned by the closure will be stored so it can be referenced
318    /// when drawing the next frame.
319    pub fn with_element_state<S, R>(
320        &mut self,
321        id: ElementId,
322        f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
323    ) -> R
324    where
325        S: 'static,
326    {
327        self.with_element_id(Some(id), |cx| {
328                let global_id = cx.window().element_id_stack.clone();
329
330                if let Some(any) = cx
331                    .window_mut()
332                    .next_frame
333                    .element_states
334                    .remove(&global_id)
335                    .or_else(|| {
336                        cx.window_mut()
337                            .rendered_frame
338                            .element_states
339                            .remove(&global_id)
340                    })
341                {
342                    let ElementStateBox {
343                        inner,
344                        parent_view_id,
345                        #[cfg(debug_assertions)]
346                        type_name
347                    } = any;
348                    // Using the extra inner option to avoid needing to reallocate a new box.
349                    let mut state_box = inner
350                        .downcast::<Option<S>>()
351                        .map_err(|_| {
352                            #[cfg(debug_assertions)]
353                            {
354                                anyhow::anyhow!(
355                                    "invalid element state type for id, requested_type {:?}, actual type: {:?}",
356                                    std::any::type_name::<S>(),
357                                    type_name
358                                )
359                            }
360
361                            #[cfg(not(debug_assertions))]
362                            {
363                                anyhow::anyhow!(
364                                    "invalid element state type for id, requested_type {:?}",
365                                    std::any::type_name::<S>(),
366                                )
367                            }
368                        })
369                        .unwrap();
370
371                    // Actual: Option<AnyElement> <- View
372                    // Requested: () <- AnyElement
373                    let state = state_box
374                        .take()
375                        .expect("element state is already on the stack");
376                    let (result, state) = f(Some(state), cx);
377                    state_box.replace(state);
378                    cx.window_mut()
379                        .next_frame
380                        .element_states
381                        .insert(global_id, ElementStateBox {
382                            inner: state_box,
383                            parent_view_id,
384                            #[cfg(debug_assertions)]
385                            type_name
386                        });
387                    result
388                } else {
389                    let (result, state) = f(None, cx);
390                    let parent_view_id = cx.parent_view_id();
391                    cx.window_mut()
392                        .next_frame
393                        .element_states
394                        .insert(global_id,
395                            ElementStateBox {
396                                inner: Box::new(Some(state)),
397                                parent_view_id,
398                                #[cfg(debug_assertions)]
399                                type_name: std::any::type_name::<S>()
400                            }
401
402                        );
403                    result
404                }
405            })
406    }
407    /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
408    pub fn paint_shadows(
409        &mut self,
410        bounds: Bounds<Pixels>,
411        corner_radii: Corners<Pixels>,
412        shadows: &[BoxShadow],
413    ) {
414        let scale_factor = self.scale_factor();
415        let content_mask = self.content_mask();
416        let view_id = self.parent_view_id();
417        let window = &mut *self.window;
418        for shadow in shadows {
419            let mut shadow_bounds = bounds;
420            shadow_bounds.origin += shadow.offset;
421            shadow_bounds.dilate(shadow.spread_radius);
422            window.next_frame.scene.insert(
423                &window.next_frame.z_index_stack,
424                Shadow {
425                    view_id: view_id.into(),
426                    layer_id: 0,
427                    order: 0,
428                    bounds: shadow_bounds.scale(scale_factor),
429                    content_mask: content_mask.scale(scale_factor),
430                    corner_radii: corner_radii.scale(scale_factor),
431                    color: shadow.color,
432                    blur_radius: shadow.blur_radius.scale(scale_factor),
433                },
434            );
435        }
436    }
437
438    /// Paint one or more quads into the scene for the next frame at the current stacking context.
439    /// Quads are colored rectangular regions with an optional background, border, and corner radius.
440    /// see [`fill`], [`outline`], and [`quad`] to construct this type.
441    pub fn paint_quad(&mut self, quad: PaintQuad) {
442        let scale_factor = self.scale_factor();
443        let content_mask = self.content_mask();
444        let view_id = self.parent_view_id();
445
446        let window = &mut *self.window;
447        window.next_frame.scene.insert(
448            &window.next_frame.z_index_stack,
449            Quad {
450                view_id: view_id.into(),
451                layer_id: 0,
452                order: 0,
453                bounds: quad.bounds.scale(scale_factor),
454                content_mask: content_mask.scale(scale_factor),
455                background: quad.background,
456                border_color: quad.border_color,
457                corner_radii: quad.corner_radii.scale(scale_factor),
458                border_widths: quad.border_widths.scale(scale_factor),
459            },
460        );
461    }
462
463    /// Paint the given `Path` into the scene for the next frame at the current z-index.
464    pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
465        let scale_factor = self.scale_factor();
466        let content_mask = self.content_mask();
467        let view_id = self.parent_view_id();
468
469        path.content_mask = content_mask;
470        path.color = color.into();
471        path.view_id = view_id.into();
472        let window = &mut *self.window;
473        window
474            .next_frame
475            .scene
476            .insert(&window.next_frame.z_index_stack, path.scale(scale_factor));
477    }
478
479    /// Paint an underline into the scene for the next frame at the current z-index.
480    pub fn paint_underline(
481        &mut self,
482        origin: Point<Pixels>,
483        width: Pixels,
484        style: &UnderlineStyle,
485    ) {
486        let scale_factor = self.scale_factor();
487        let height = if style.wavy {
488            style.thickness * 3.
489        } else {
490            style.thickness
491        };
492        let bounds = Bounds {
493            origin,
494            size: size(width, height),
495        };
496        let content_mask = self.content_mask();
497        let view_id = self.parent_view_id();
498
499        let window = &mut *self.window;
500        window.next_frame.scene.insert(
501            &window.next_frame.z_index_stack,
502            Underline {
503                view_id: view_id.into(),
504                layer_id: 0,
505                order: 0,
506                bounds: bounds.scale(scale_factor),
507                content_mask: content_mask.scale(scale_factor),
508                thickness: style.thickness.scale(scale_factor),
509                color: style.color.unwrap_or_default(),
510                wavy: style.wavy,
511            },
512        );
513    }
514
515    /// Paint a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
516    /// The y component of the origin is the baseline of the glyph.
517    pub fn paint_glyph(
518        &mut self,
519        origin: Point<Pixels>,
520        font_id: FontId,
521        glyph_id: GlyphId,
522        font_size: Pixels,
523        color: Hsla,
524    ) -> Result<()> {
525        let scale_factor = self.scale_factor();
526        let glyph_origin = origin.scale(scale_factor);
527        let subpixel_variant = Point {
528            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
529            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
530        };
531        let params = RenderGlyphParams {
532            font_id,
533            glyph_id,
534            font_size,
535            subpixel_variant,
536            scale_factor,
537            is_emoji: false,
538        };
539
540        let raster_bounds = self.text_system().raster_bounds(&params)?;
541        if !raster_bounds.is_zero() {
542            let tile =
543                self.window
544                    .sprite_atlas
545                    .get_or_insert_with(&params.clone().into(), &mut || {
546                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
547                        Ok((size, Cow::Owned(bytes)))
548                    })?;
549            let bounds = Bounds {
550                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
551                size: tile.bounds.size.map(Into::into),
552            };
553            let content_mask = self.content_mask().scale(scale_factor);
554            let view_id = self.parent_view_id();
555            let window = &mut *self.window;
556            window.next_frame.scene.insert(
557                &window.next_frame.z_index_stack,
558                MonochromeSprite {
559                    view_id: view_id.into(),
560                    layer_id: 0,
561                    order: 0,
562                    bounds,
563                    content_mask,
564                    color,
565                    tile,
566                },
567            );
568        }
569        Ok(())
570    }
571
572    /// Paint an emoji glyph into the scene for the next frame at the current z-index.
573    /// The y component of the origin is the baseline of the glyph.
574    pub fn paint_emoji(
575        &mut self,
576        origin: Point<Pixels>,
577        font_id: FontId,
578        glyph_id: GlyphId,
579        font_size: Pixels,
580    ) -> Result<()> {
581        let scale_factor = self.scale_factor();
582        let glyph_origin = origin.scale(scale_factor);
583        let params = RenderGlyphParams {
584            font_id,
585            glyph_id,
586            font_size,
587            // We don't render emojis with subpixel variants.
588            subpixel_variant: Default::default(),
589            scale_factor,
590            is_emoji: true,
591        };
592
593        let raster_bounds = self.text_system().raster_bounds(&params)?;
594        if !raster_bounds.is_zero() {
595            let tile =
596                self.window
597                    .sprite_atlas
598                    .get_or_insert_with(&params.clone().into(), &mut || {
599                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
600                        Ok((size, Cow::Owned(bytes)))
601                    })?;
602            let bounds = Bounds {
603                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
604                size: tile.bounds.size.map(Into::into),
605            };
606            let content_mask = self.content_mask().scale(scale_factor);
607            let view_id = self.parent_view_id();
608            let window = &mut *self.window;
609
610            window.next_frame.scene.insert(
611                &window.next_frame.z_index_stack,
612                PolychromeSprite {
613                    view_id: view_id.into(),
614                    layer_id: 0,
615                    order: 0,
616                    bounds,
617                    corner_radii: Default::default(),
618                    content_mask,
619                    tile,
620                    grayscale: false,
621                },
622            );
623        }
624        Ok(())
625    }
626
627    /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
628    pub fn paint_svg(
629        &mut self,
630        bounds: Bounds<Pixels>,
631        path: SharedString,
632        color: Hsla,
633    ) -> Result<()> {
634        let scale_factor = self.scale_factor();
635        let bounds = bounds.scale(scale_factor);
636        // Render the SVG at twice the size to get a higher quality result.
637        let params = RenderSvgParams {
638            path,
639            size: bounds
640                .size
641                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
642        };
643
644        let tile =
645            self.window
646                .sprite_atlas
647                .get_or_insert_with(&params.clone().into(), &mut || {
648                    let bytes = self.svg_renderer.render(&params)?;
649                    Ok((params.size, Cow::Owned(bytes)))
650                })?;
651        let content_mask = self.content_mask().scale(scale_factor);
652        let view_id = self.parent_view_id();
653
654        let window = &mut *self.window;
655        window.next_frame.scene.insert(
656            &window.next_frame.z_index_stack,
657            MonochromeSprite {
658                view_id: view_id.into(),
659                layer_id: 0,
660                order: 0,
661                bounds,
662                content_mask,
663                color,
664                tile,
665            },
666        );
667
668        Ok(())
669    }
670
671    /// Paint an image into the scene for the next frame at the current z-index.
672    pub fn paint_image(
673        &mut self,
674        bounds: Bounds<Pixels>,
675        corner_radii: Corners<Pixels>,
676        data: Arc<ImageData>,
677        grayscale: bool,
678    ) -> Result<()> {
679        let scale_factor = self.scale_factor();
680        let bounds = bounds.scale(scale_factor);
681        let params = RenderImageParams { image_id: data.id };
682
683        let tile = self
684            .window
685            .sprite_atlas
686            .get_or_insert_with(&params.clone().into(), &mut || {
687                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
688            })?;
689        let content_mask = self.content_mask().scale(scale_factor);
690        let corner_radii = corner_radii.scale(scale_factor);
691        let view_id = self.parent_view_id();
692
693        let window = &mut *self.window;
694        window.next_frame.scene.insert(
695            &window.next_frame.z_index_stack,
696            PolychromeSprite {
697                view_id: view_id.into(),
698                layer_id: 0,
699                order: 0,
700                bounds,
701                content_mask,
702                corner_radii,
703                tile,
704                grayscale,
705            },
706        );
707        Ok(())
708    }
709
710    /// Paint a surface into the scene for the next frame at the current z-index.
711    pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
712        let scale_factor = self.scale_factor();
713        let bounds = bounds.scale(scale_factor);
714        let content_mask = self.content_mask().scale(scale_factor);
715        let view_id = self.parent_view_id();
716        let window = &mut *self.window;
717        window.next_frame.scene.insert(
718            &window.next_frame.z_index_stack,
719            Surface {
720                view_id: view_id.into(),
721                layer_id: 0,
722                order: 0,
723                bounds,
724                content_mask,
725                image_buffer,
726            },
727        );
728    }
729
730    #[must_use]
731    /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
732    /// layout is being requested, along with the layout ids of any children. This method is called during
733    /// calls to the `Element::layout` trait method and enables any element to participate in layout.
734    pub fn request_layout(
735        &mut self,
736        style: &Style,
737        children: impl IntoIterator<Item = LayoutId>,
738    ) -> LayoutId {
739        self.app.layout_id_buffer.clear();
740        self.app.layout_id_buffer.extend(children);
741        let rem_size = self.rem_size();
742
743        self.cx
744            .window
745            .layout_engine
746            .as_mut()
747            .unwrap()
748            .request_layout(style, rem_size, &self.cx.app.layout_id_buffer)
749    }
750
751    /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
752    /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
753    /// determine the element's size. One place this is used internally is when measuring text.
754    ///
755    /// The given closure is invoked at layout time with the known dimensions and available space and
756    /// returns a `Size`.
757    pub fn request_measured_layout<
758        F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
759            + 'static,
760    >(
761        &mut self,
762        style: Style,
763        measure: F,
764    ) -> LayoutId {
765        let rem_size = self.rem_size();
766        self.window
767            .layout_engine
768            .as_mut()
769            .unwrap()
770            .request_measured_layout(style, rem_size, measure)
771    }
772
773    /// Compute the layout for the given id within the given available space.
774    /// This method is called for its side effect, typically by the framework prior to painting.
775    /// After calling it, you can request the bounds of the given layout node id or any descendant.
776    pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
777        let mut layout_engine = self.window.layout_engine.take().unwrap();
778        layout_engine.compute_layout(layout_id, available_space, self);
779        self.window.layout_engine = Some(layout_engine);
780    }
781
782    /// Obtain the bounds computed for the given LayoutId relative to the window. This method should not
783    /// be invoked until the paint phase begins, and will usually be invoked by GPUI itself automatically
784    /// in order to pass your element its `Bounds` automatically.
785    pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
786        let mut bounds = self
787            .window
788            .layout_engine
789            .as_mut()
790            .unwrap()
791            .layout_bounds(layout_id)
792            .map(Into::into);
793        bounds.origin += self.element_offset();
794        bounds
795    }
796
797    pub(crate) fn layout_style(&self, layout_id: LayoutId) -> Option<&Style> {
798        self.window
799            .layout_engine
800            .as_ref()
801            .unwrap()
802            .requested_style(layout_id)
803    }
804
805    /// Called during painting to track which z-index is on top at each pixel position
806    pub fn add_opaque_layer(&mut self, bounds: Bounds<Pixels>) {
807        let stacking_order = self.window.next_frame.z_index_stack.clone();
808        let view_id = self.parent_view_id();
809        let depth_map = &mut self.window.next_frame.depth_map;
810        match depth_map.binary_search_by(|(level, _, _)| stacking_order.cmp(level)) {
811            Ok(i) | Err(i) => depth_map.insert(i, (stacking_order, view_id, bounds)),
812        }
813    }
814
815    /// Invoke the given function with the given focus handle present on the key dispatch stack.
816    /// If you want an element to participate in key dispatch, use this method to push its key context and focus handle into the stack during paint.
817    pub fn with_key_dispatch<R>(
818        &mut self,
819        context: Option<KeyContext>,
820        focus_handle: Option<FocusHandle>,
821        f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
822    ) -> R {
823        let window = &mut self.window;
824        let focus_id = focus_handle.as_ref().map(|handle| handle.id);
825        window
826            .next_frame
827            .dispatch_tree
828            .push_node(context.clone(), focus_id, None);
829
830        let result = f(focus_handle, self);
831
832        self.window.next_frame.dispatch_tree.pop_node();
833
834        result
835    }
836
837    /// Invoke the given function with the given view id present on the view stack.
838    /// This is a fairly low-level method used to layout views.
839    pub fn with_view_id<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
840        let text_system = self.text_system().clone();
841        text_system.with_view(view_id, || {
842            if self.window.next_frame.view_stack.last() == Some(&view_id) {
843                return f(self);
844            } else {
845                self.window.next_frame.view_stack.push(view_id);
846                let result = f(self);
847                self.window.next_frame.view_stack.pop();
848                result
849            }
850        })
851    }
852
853    /// Invoke the given function with the given view id present on the view stack.
854    /// This is a fairly low-level method used to paint views.
855    pub fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
856        let text_system = self.text_system().clone();
857        text_system.with_view(view_id, || {
858            if self.window.next_frame.view_stack.last() == Some(&view_id) {
859                return f(self);
860            } else {
861                self.window.next_frame.view_stack.push(view_id);
862                self.window
863                    .next_frame
864                    .dispatch_tree
865                    .push_node(None, None, Some(view_id));
866                let result = f(self);
867                self.window.next_frame.dispatch_tree.pop_node();
868                self.window.next_frame.view_stack.pop();
869                result
870            }
871        })
872    }
873
874    /// Sets an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
875    /// platform to receive textual input with proper integration with concerns such
876    /// as IME interactions. This handler will be active for the upcoming frame until the following frame is
877    /// rendered.
878    ///
879    /// [element_input_handler]: crate::ElementInputHandler
880    pub fn handle_input(&mut self, focus_handle: &FocusHandle, input_handler: impl InputHandler) {
881        if focus_handle.is_focused(self) {
882            let view_id = self.parent_view_id();
883            self.window.next_frame.requested_input_handler = Some(RequestedInputHandler {
884                view_id,
885                handler: Some(PlatformInputHandler::new(
886                    self.to_async(),
887                    Box::new(input_handler),
888                )),
889            })
890        }
891    }
892
893    /// Register a mouse event listener on the window for the next frame. The type of event
894    /// is determined by the first parameter of the given listener. When the next frame is rendered
895    /// the listener will be cleared.
896    pub fn on_mouse_event<Event: MouseEvent>(
897        &mut self,
898        mut handler: impl FnMut(&Event, DispatchPhase, &mut ElementContext) + 'static,
899    ) {
900        let view_id = self.parent_view_id();
901        let order = self.window.next_frame.z_index_stack.clone();
902        self.window
903            .next_frame
904            .mouse_listeners
905            .entry(TypeId::of::<Event>())
906            .or_default()
907            .push((
908                order,
909                view_id,
910                Box::new(
911                    move |event: &dyn Any, phase: DispatchPhase, cx: &mut ElementContext<'_>| {
912                        handler(event.downcast_ref().unwrap(), phase, cx)
913                    },
914                ),
915            ))
916    }
917
918    /// Register a key event listener on the window for the next frame. The type of event
919    /// is determined by the first parameter of the given listener. When the next frame is rendered
920    /// the listener will be cleared.
921    ///
922    /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
923    /// a specific need to register a global listener.
924    pub fn on_key_event<Event: KeyEvent>(
925        &mut self,
926        listener: impl Fn(&Event, DispatchPhase, &mut ElementContext) + 'static,
927    ) {
928        self.window.next_frame.dispatch_tree.on_key_event(Rc::new(
929            move |event: &dyn Any, phase, cx: &mut ElementContext<'_>| {
930                if let Some(event) = event.downcast_ref::<Event>() {
931                    listener(event, phase, cx)
932                }
933            },
934        ));
935    }
936}