element_cx.rs

   1//! The element context is the main interface for interacting with the frame during a paint.
   2//!
   3//! Elements are hierarchical and with a few exceptions the context accumulates state in a stack
   4//! as it processes all of the elements in the frame. The methods that interact with this stack
   5//! are generally marked with `with_*`, and take a callback to denote the region of code that
   6//! should be executed with that state.
   7//!
   8//! The other main interface is the `paint_*` family of methods, which push basic drawing commands
   9//! to the GPU. Everything in a GPUI app is drawn with these methods.
  10//!
  11//! There are also several internal methods that GPUI uses, such as [`ElementContext::with_element_state`]
  12//! to call the paint and layout methods on elements. These have been included as they're often useful
  13//! for taking manual control of the layouting or painting of specialized elements.
  14
  15use std::{
  16    any::{Any, TypeId},
  17    borrow::{Borrow, BorrowMut, Cow},
  18    mem,
  19    rc::Rc,
  20    sync::Arc,
  21};
  22
  23use anyhow::Result;
  24use collections::{FxHashMap, FxHashSet};
  25use derive_more::{Deref, DerefMut};
  26use media::core_video::CVImageBuffer;
  27use smallvec::SmallVec;
  28use util::post_inc;
  29
  30use crate::{
  31    prelude::*, size, AnyTooltip, AppContext, AvailableSpace, Bounds, BoxShadow, ContentMask,
  32    Corners, CursorStyle, DevicePixels, DispatchPhase, DispatchTree, ElementId, ElementStateBox,
  33    EntityId, FocusHandle, FocusId, FontId, GlobalElementId, GlyphId, Hsla, ImageData,
  34    InputHandler, IsZero, KeyContext, KeyEvent, KeymatchMode, LayoutId, MonochromeSprite,
  35    MouseEvent, PaintQuad, Path, Pixels, PlatformInputHandler, Point, PolychromeSprite, Quad,
  36    RenderGlyphParams, RenderImageParams, RenderSvgParams, Scene, Shadow, SharedString, Size,
  37    StackingContext, StackingOrder, Style, Surface, TextStyleRefinement, Underline, UnderlineStyle,
  38    Window, WindowContext, SUBPIXEL_VARIANTS,
  39};
  40
  41type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut ElementContext) + 'static>;
  42
  43pub(crate) struct RequestedInputHandler {
  44    pub(crate) view_id: EntityId,
  45    pub(crate) handler: Option<PlatformInputHandler>,
  46}
  47
  48pub(crate) struct TooltipRequest {
  49    pub(crate) view_id: EntityId,
  50    pub(crate) tooltip: AnyTooltip,
  51}
  52
  53pub(crate) struct Frame {
  54    pub(crate) focus: Option<FocusId>,
  55    pub(crate) window_active: bool,
  56    pub(crate) element_states: FxHashMap<GlobalElementId, ElementStateBox>,
  57    pub(crate) mouse_listeners: FxHashMap<TypeId, Vec<(StackingOrder, EntityId, AnyMouseListener)>>,
  58    pub(crate) dispatch_tree: DispatchTree,
  59    pub(crate) scene: Scene,
  60    pub(crate) depth_map: Vec<(StackingOrder, EntityId, Bounds<Pixels>)>,
  61    pub(crate) z_index_stack: StackingOrder,
  62    pub(crate) next_stacking_order_ids: Vec<u16>,
  63    pub(crate) next_root_z_index: u16,
  64    pub(crate) content_mask_stack: Vec<ContentMask<Pixels>>,
  65    pub(crate) element_offset_stack: Vec<Point<Pixels>>,
  66    pub(crate) requested_input_handler: Option<RequestedInputHandler>,
  67    pub(crate) tooltip_request: Option<TooltipRequest>,
  68    pub(crate) cursor_styles: FxHashMap<EntityId, CursorStyle>,
  69    pub(crate) requested_cursor_style: Option<CursorStyle>,
  70    pub(crate) view_stack: Vec<EntityId>,
  71    pub(crate) reused_views: FxHashSet<EntityId>,
  72
  73    #[cfg(any(test, feature = "test-support"))]
  74    pub(crate) debug_bounds: collections::FxHashMap<String, Bounds<Pixels>>,
  75}
  76
  77impl Frame {
  78    pub(crate) fn new(dispatch_tree: DispatchTree) -> Self {
  79        Frame {
  80            focus: None,
  81            window_active: false,
  82            element_states: FxHashMap::default(),
  83            mouse_listeners: FxHashMap::default(),
  84            dispatch_tree,
  85            scene: Scene::default(),
  86            depth_map: Vec::new(),
  87            z_index_stack: StackingOrder::default(),
  88            next_stacking_order_ids: vec![0],
  89            next_root_z_index: 0,
  90            content_mask_stack: Vec::new(),
  91            element_offset_stack: Vec::new(),
  92            requested_input_handler: None,
  93            tooltip_request: None,
  94            cursor_styles: FxHashMap::default(),
  95            requested_cursor_style: None,
  96            view_stack: Vec::new(),
  97            reused_views: FxHashSet::default(),
  98
  99            #[cfg(any(test, feature = "test-support"))]
 100            debug_bounds: FxHashMap::default(),
 101        }
 102    }
 103
 104    pub(crate) fn clear(&mut self) {
 105        self.element_states.clear();
 106        self.mouse_listeners.values_mut().for_each(Vec::clear);
 107        self.dispatch_tree.clear();
 108        self.depth_map.clear();
 109        self.next_stacking_order_ids = vec![0];
 110        self.next_root_z_index = 0;
 111        self.reused_views.clear();
 112        self.scene.clear();
 113        self.requested_input_handler.take();
 114        self.tooltip_request.take();
 115        self.cursor_styles.clear();
 116        self.requested_cursor_style.take();
 117        debug_assert_eq!(self.view_stack.len(), 0);
 118    }
 119
 120    pub(crate) fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
 121        self.focus
 122            .map(|focus_id| self.dispatch_tree.focus_path(focus_id))
 123            .unwrap_or_default()
 124    }
 125
 126    pub(crate) fn finish(&mut self, prev_frame: &mut Self) {
 127        // Reuse mouse listeners that didn't change since the last frame.
 128        for (type_id, listeners) in &mut prev_frame.mouse_listeners {
 129            let next_listeners = self.mouse_listeners.entry(*type_id).or_default();
 130            for (order, view_id, listener) in listeners.drain(..) {
 131                if self.reused_views.contains(&view_id) {
 132                    next_listeners.push((order, view_id, listener));
 133                }
 134            }
 135        }
 136
 137        // Reuse entries in the depth map that didn't change since the last frame.
 138        for (order, view_id, bounds) in prev_frame.depth_map.drain(..) {
 139            if self.reused_views.contains(&view_id) {
 140                match self
 141                    .depth_map
 142                    .binary_search_by(|(level, _, _)| order.cmp(level))
 143                {
 144                    Ok(i) | Err(i) => self.depth_map.insert(i, (order, view_id, bounds)),
 145                }
 146            }
 147        }
 148
 149        // Retain element states for views that didn't change since the last frame.
 150        for (element_id, state) in prev_frame.element_states.drain() {
 151            if self.reused_views.contains(&state.parent_view_id) {
 152                self.element_states.entry(element_id).or_insert(state);
 153            }
 154        }
 155
 156        // Reuse geometry that didn't change since the last frame.
 157        self.scene
 158            .reuse_views(&self.reused_views, &mut prev_frame.scene);
 159        self.scene.finish();
 160    }
 161}
 162
 163/// This context is used for assisting in the implementation of the element trait
 164#[derive(Deref, DerefMut)]
 165pub struct ElementContext<'a> {
 166    pub(crate) cx: WindowContext<'a>,
 167}
 168
 169impl<'a> WindowContext<'a> {
 170    /// Convert this window context into an ElementContext in this callback.
 171    /// If you need to use this method, you're probably intermixing the imperative
 172    /// and declarative APIs, which is not recommended.
 173    pub fn with_element_context<R>(&mut self, f: impl FnOnce(&mut ElementContext) -> R) -> R {
 174        f(&mut ElementContext {
 175            cx: WindowContext::new(self.app, self.window),
 176        })
 177    }
 178}
 179
 180impl<'a> Borrow<AppContext> for ElementContext<'a> {
 181    fn borrow(&self) -> &AppContext {
 182        self.cx.app
 183    }
 184}
 185
 186impl<'a> BorrowMut<AppContext> for ElementContext<'a> {
 187    fn borrow_mut(&mut self) -> &mut AppContext {
 188        self.cx.borrow_mut()
 189    }
 190}
 191
 192impl<'a> Borrow<WindowContext<'a>> for ElementContext<'a> {
 193    fn borrow(&self) -> &WindowContext<'a> {
 194        &self.cx
 195    }
 196}
 197
 198impl<'a> BorrowMut<WindowContext<'a>> for ElementContext<'a> {
 199    fn borrow_mut(&mut self) -> &mut WindowContext<'a> {
 200        &mut self.cx
 201    }
 202}
 203
 204impl<'a> Borrow<Window> for ElementContext<'a> {
 205    fn borrow(&self) -> &Window {
 206        self.cx.window
 207    }
 208}
 209
 210impl<'a> BorrowMut<Window> for ElementContext<'a> {
 211    fn borrow_mut(&mut self) -> &mut Window {
 212        self.cx.borrow_mut()
 213    }
 214}
 215
 216impl<'a> Context for ElementContext<'a> {
 217    type Result<T> = <WindowContext<'a> as Context>::Result<T>;
 218
 219    fn new_model<T: 'static>(
 220        &mut self,
 221        build_model: impl FnOnce(&mut crate::ModelContext<'_, T>) -> T,
 222    ) -> Self::Result<crate::Model<T>> {
 223        self.cx.new_model(build_model)
 224    }
 225
 226    fn update_model<T, R>(
 227        &mut self,
 228        handle: &crate::Model<T>,
 229        update: impl FnOnce(&mut T, &mut crate::ModelContext<'_, T>) -> R,
 230    ) -> Self::Result<R>
 231    where
 232        T: 'static,
 233    {
 234        self.cx.update_model(handle, update)
 235    }
 236
 237    fn read_model<T, R>(
 238        &self,
 239        handle: &crate::Model<T>,
 240        read: impl FnOnce(&T, &AppContext) -> R,
 241    ) -> Self::Result<R>
 242    where
 243        T: 'static,
 244    {
 245        self.cx.read_model(handle, read)
 246    }
 247
 248    fn update_window<T, F>(&mut self, window: crate::AnyWindowHandle, f: F) -> Result<T>
 249    where
 250        F: FnOnce(crate::AnyView, &mut WindowContext<'_>) -> T,
 251    {
 252        self.cx.update_window(window, f)
 253    }
 254
 255    fn read_window<T, R>(
 256        &self,
 257        window: &crate::WindowHandle<T>,
 258        read: impl FnOnce(crate::View<T>, &AppContext) -> R,
 259    ) -> Result<R>
 260    where
 261        T: 'static,
 262    {
 263        self.cx.read_window(window, read)
 264    }
 265}
 266
 267impl<'a> VisualContext for ElementContext<'a> {
 268    fn new_view<V>(
 269        &mut self,
 270        build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
 271    ) -> Self::Result<crate::View<V>>
 272    where
 273        V: 'static + Render,
 274    {
 275        self.cx.new_view(build_view)
 276    }
 277
 278    fn update_view<V: 'static, R>(
 279        &mut self,
 280        view: &crate::View<V>,
 281        update: impl FnOnce(&mut V, &mut crate::ViewContext<'_, V>) -> R,
 282    ) -> Self::Result<R> {
 283        self.cx.update_view(view, update)
 284    }
 285
 286    fn replace_root_view<V>(
 287        &mut self,
 288        build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
 289    ) -> Self::Result<crate::View<V>>
 290    where
 291        V: 'static + Render,
 292    {
 293        self.cx.replace_root_view(build_view)
 294    }
 295
 296    fn focus_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
 297    where
 298        V: crate::FocusableView,
 299    {
 300        self.cx.focus_view(view)
 301    }
 302
 303    fn dismiss_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
 304    where
 305        V: crate::ManagedView,
 306    {
 307        self.cx.dismiss_view(view)
 308    }
 309}
 310
 311impl<'a> ElementContext<'a> {
 312    pub(crate) fn reuse_view(&mut self, next_stacking_order_id: u16) {
 313        let view_id = self.parent_view_id();
 314        let grafted_view_ids = self
 315            .cx
 316            .window
 317            .next_frame
 318            .dispatch_tree
 319            .reuse_view(view_id, &mut self.cx.window.rendered_frame.dispatch_tree);
 320        for view_id in grafted_view_ids {
 321            assert!(self.window.next_frame.reused_views.insert(view_id));
 322
 323            // Reuse the previous input handler requested during painting of the reused view.
 324            if self
 325                .window
 326                .rendered_frame
 327                .requested_input_handler
 328                .as_ref()
 329                .map_or(false, |requested| requested.view_id == view_id)
 330            {
 331                self.window.next_frame.requested_input_handler =
 332                    self.window.rendered_frame.requested_input_handler.take();
 333            }
 334
 335            // Reuse the tooltip previously requested during painting of the reused view.
 336            if self
 337                .window
 338                .rendered_frame
 339                .tooltip_request
 340                .as_ref()
 341                .map_or(false, |requested| requested.view_id == view_id)
 342            {
 343                self.window.next_frame.tooltip_request =
 344                    self.window.rendered_frame.tooltip_request.take();
 345            }
 346
 347            // Reuse the cursor styles previously requested during painting of the reused view.
 348            if let Some(style) = self.window.rendered_frame.cursor_styles.remove(&view_id) {
 349                self.window.next_frame.cursor_styles.insert(view_id, style);
 350                self.window.next_frame.requested_cursor_style = Some(style);
 351            }
 352        }
 353
 354        debug_assert!(
 355            next_stacking_order_id
 356                >= self
 357                    .window
 358                    .next_frame
 359                    .next_stacking_order_ids
 360                    .last()
 361                    .copied()
 362                    .unwrap()
 363        );
 364        *self
 365            .window
 366            .next_frame
 367            .next_stacking_order_ids
 368            .last_mut()
 369            .unwrap() = next_stacking_order_id;
 370    }
 371
 372    /// Push a text style onto the stack, and call a function with that style active.
 373    /// Use [`AppContext::text_style`] to get the current, combined text style.
 374    pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
 375    where
 376        F: FnOnce(&mut Self) -> R,
 377    {
 378        if let Some(style) = style {
 379            self.push_text_style(style);
 380            let result = f(self);
 381            self.pop_text_style();
 382            result
 383        } else {
 384            f(self)
 385        }
 386    }
 387
 388    /// Updates the cursor style at the platform level.
 389    pub fn set_cursor_style(&mut self, style: CursorStyle) {
 390        let view_id = self.parent_view_id();
 391        self.window.next_frame.cursor_styles.insert(view_id, style);
 392        self.window.next_frame.requested_cursor_style = Some(style);
 393    }
 394
 395    /// Sets a tooltip to be rendered for the upcoming frame
 396    pub fn set_tooltip(&mut self, tooltip: AnyTooltip) {
 397        let view_id = self.parent_view_id();
 398        self.window.next_frame.tooltip_request = Some(TooltipRequest { view_id, tooltip });
 399    }
 400
 401    /// Pushes the given element id onto the global stack and invokes the given closure
 402    /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
 403    /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
 404    /// used to associate state with identified elements across separate frames.
 405    pub fn with_element_id<R>(
 406        &mut self,
 407        id: Option<impl Into<ElementId>>,
 408        f: impl FnOnce(&mut Self) -> R,
 409    ) -> R {
 410        if let Some(id) = id.map(Into::into) {
 411            let window = self.window_mut();
 412            window.element_id_stack.push(id);
 413            let result = f(self);
 414            let window: &mut Window = self.borrow_mut();
 415            window.element_id_stack.pop();
 416            result
 417        } else {
 418            f(self)
 419        }
 420    }
 421
 422    /// Invoke the given function with the given content mask after intersecting it
 423    /// with the current mask.
 424    pub fn with_content_mask<R>(
 425        &mut self,
 426        mask: Option<ContentMask<Pixels>>,
 427        f: impl FnOnce(&mut Self) -> R,
 428    ) -> R {
 429        if let Some(mask) = mask {
 430            let mask = mask.intersect(&self.content_mask());
 431            self.window_mut().next_frame.content_mask_stack.push(mask);
 432            let result = f(self);
 433            self.window_mut().next_frame.content_mask_stack.pop();
 434            result
 435        } else {
 436            f(self)
 437        }
 438    }
 439
 440    /// Invoke the given function with the content mask reset to that
 441    /// of the window.
 442    pub fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
 443        let mask = ContentMask {
 444            bounds: Bounds {
 445                origin: Point::default(),
 446                size: self.window().viewport_size,
 447            },
 448        };
 449
 450        let new_root_z_index = post_inc(&mut self.window_mut().next_frame.next_root_z_index);
 451        let new_stacking_order_id = post_inc(
 452            self.window_mut()
 453                .next_frame
 454                .next_stacking_order_ids
 455                .last_mut()
 456                .unwrap(),
 457        );
 458        let new_context = StackingContext {
 459            z_index: new_root_z_index,
 460            id: new_stacking_order_id,
 461        };
 462
 463        let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
 464
 465        self.window_mut().next_frame.z_index_stack.push(new_context);
 466        self.window_mut().next_frame.content_mask_stack.push(mask);
 467        let result = f(self);
 468        self.window_mut().next_frame.content_mask_stack.pop();
 469        self.window_mut().next_frame.z_index_stack = old_stacking_order;
 470
 471        result
 472    }
 473
 474    /// Called during painting to invoke the given closure in a new stacking context. The given
 475    /// z-index is interpreted relative to the previous call to `stack`.
 476    pub fn with_z_index<R>(&mut self, z_index: u16, f: impl FnOnce(&mut Self) -> R) -> R {
 477        let new_stacking_order_id = post_inc(
 478            self.window_mut()
 479                .next_frame
 480                .next_stacking_order_ids
 481                .last_mut()
 482                .unwrap(),
 483        );
 484        self.window_mut().next_frame.next_stacking_order_ids.push(0);
 485        let new_context = StackingContext {
 486            z_index,
 487            id: new_stacking_order_id,
 488        };
 489
 490        self.window_mut().next_frame.z_index_stack.push(new_context);
 491        let result = f(self);
 492        self.window_mut().next_frame.z_index_stack.pop();
 493
 494        self.window_mut().next_frame.next_stacking_order_ids.pop();
 495
 496        result
 497    }
 498
 499    /// Updates the global element offset relative to the current offset. This is used to implement
 500    /// scrolling.
 501    pub fn with_element_offset<R>(
 502        &mut self,
 503        offset: Point<Pixels>,
 504        f: impl FnOnce(&mut Self) -> R,
 505    ) -> R {
 506        if offset.is_zero() {
 507            return f(self);
 508        };
 509
 510        let abs_offset = self.element_offset() + offset;
 511        self.with_absolute_element_offset(abs_offset, f)
 512    }
 513
 514    /// Updates the global element offset based on the given offset. This is used to implement
 515    /// drag handles and other manual painting of elements.
 516    pub fn with_absolute_element_offset<R>(
 517        &mut self,
 518        offset: Point<Pixels>,
 519        f: impl FnOnce(&mut Self) -> R,
 520    ) -> R {
 521        self.window_mut()
 522            .next_frame
 523            .element_offset_stack
 524            .push(offset);
 525        let result = f(self);
 526        self.window_mut().next_frame.element_offset_stack.pop();
 527        result
 528    }
 529
 530    /// Obtain the current element offset.
 531    pub fn element_offset(&self) -> Point<Pixels> {
 532        self.window()
 533            .next_frame
 534            .element_offset_stack
 535            .last()
 536            .copied()
 537            .unwrap_or_default()
 538    }
 539
 540    /// Obtain the current content mask.
 541    pub fn content_mask(&self) -> ContentMask<Pixels> {
 542        self.window()
 543            .next_frame
 544            .content_mask_stack
 545            .last()
 546            .cloned()
 547            .unwrap_or_else(|| ContentMask {
 548                bounds: Bounds {
 549                    origin: Point::default(),
 550                    size: self.window().viewport_size,
 551                },
 552            })
 553    }
 554
 555    /// The size of an em for the base font of the application. Adjusting this value allows the
 556    /// UI to scale, just like zooming a web page.
 557    pub fn rem_size(&self) -> Pixels {
 558        self.window().rem_size
 559    }
 560
 561    /// Updates or initializes state for an element with the given id that lives across multiple
 562    /// frames. If an element with this ID existed in the rendered frame, its state will be passed
 563    /// to the given closure. The state returned by the closure will be stored so it can be referenced
 564    /// when drawing the next frame.
 565    pub fn with_element_state<S, R>(
 566        &mut self,
 567        id: ElementId,
 568        f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
 569    ) -> R
 570    where
 571        S: 'static,
 572    {
 573        self.with_element_id(Some(id), |cx| {
 574                let global_id = cx.window().element_id_stack.clone();
 575
 576                if let Some(any) = cx
 577                    .window_mut()
 578                    .next_frame
 579                    .element_states
 580                    .remove(&global_id)
 581                    .or_else(|| {
 582                        cx.window_mut()
 583                            .rendered_frame
 584                            .element_states
 585                            .remove(&global_id)
 586                    })
 587                {
 588                    let ElementStateBox {
 589                        inner,
 590                        parent_view_id,
 591                        #[cfg(debug_assertions)]
 592                        type_name
 593                    } = any;
 594                    // Using the extra inner option to avoid needing to reallocate a new box.
 595                    let mut state_box = inner
 596                        .downcast::<Option<S>>()
 597                        .map_err(|_| {
 598                            #[cfg(debug_assertions)]
 599                            {
 600                                anyhow::anyhow!(
 601                                    "invalid element state type for id, requested_type {:?}, actual type: {:?}",
 602                                    std::any::type_name::<S>(),
 603                                    type_name
 604                                )
 605                            }
 606
 607                            #[cfg(not(debug_assertions))]
 608                            {
 609                                anyhow::anyhow!(
 610                                    "invalid element state type for id, requested_type {:?}",
 611                                    std::any::type_name::<S>(),
 612                                )
 613                            }
 614                        })
 615                        .unwrap();
 616
 617                    // Actual: Option<AnyElement> <- View
 618                    // Requested: () <- AnyElement
 619                    let state = state_box
 620                        .take()
 621                        .expect("element state is already on the stack");
 622                    let (result, state) = f(Some(state), cx);
 623                    state_box.replace(state);
 624                    cx.window_mut()
 625                        .next_frame
 626                        .element_states
 627                        .insert(global_id, ElementStateBox {
 628                            inner: state_box,
 629                            parent_view_id,
 630                            #[cfg(debug_assertions)]
 631                            type_name
 632                        });
 633                    result
 634                } else {
 635                    let (result, state) = f(None, cx);
 636                    let parent_view_id = cx.parent_view_id();
 637                    cx.window_mut()
 638                        .next_frame
 639                        .element_states
 640                        .insert(global_id,
 641                            ElementStateBox {
 642                                inner: Box::new(Some(state)),
 643                                parent_view_id,
 644                                #[cfg(debug_assertions)]
 645                                type_name: std::any::type_name::<S>()
 646                            }
 647
 648                        );
 649                    result
 650                }
 651            })
 652    }
 653    /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
 654    pub fn paint_shadows(
 655        &mut self,
 656        bounds: Bounds<Pixels>,
 657        corner_radii: Corners<Pixels>,
 658        shadows: &[BoxShadow],
 659    ) {
 660        let scale_factor = self.scale_factor();
 661        let content_mask = self.content_mask();
 662        let view_id = self.parent_view_id();
 663        let window = &mut *self.window;
 664        for shadow in shadows {
 665            let mut shadow_bounds = bounds;
 666            shadow_bounds.origin += shadow.offset;
 667            shadow_bounds.dilate(shadow.spread_radius);
 668            window.next_frame.scene.insert(
 669                &window.next_frame.z_index_stack,
 670                Shadow {
 671                    view_id: view_id.into(),
 672                    layer_id: 0,
 673                    order: 0,
 674                    bounds: shadow_bounds.scale(scale_factor),
 675                    content_mask: content_mask.scale(scale_factor),
 676                    corner_radii: corner_radii.scale(scale_factor),
 677                    color: shadow.color,
 678                    blur_radius: shadow.blur_radius.scale(scale_factor),
 679                },
 680            );
 681        }
 682    }
 683
 684    /// Paint one or more quads into the scene for the next frame at the current stacking context.
 685    /// Quads are colored rectangular regions with an optional background, border, and corner radius.
 686    /// see [`fill`](crate::fill), [`outline`](crate::outline), and [`quad`](crate::quad) to construct this type.
 687    pub fn paint_quad(&mut self, quad: PaintQuad) {
 688        let scale_factor = self.scale_factor();
 689        let content_mask = self.content_mask();
 690        let view_id = self.parent_view_id();
 691
 692        let window = &mut *self.window;
 693        window.next_frame.scene.insert(
 694            &window.next_frame.z_index_stack,
 695            Quad {
 696                view_id: view_id.into(),
 697                layer_id: 0,
 698                order: 0,
 699                bounds: quad.bounds.scale(scale_factor),
 700                content_mask: content_mask.scale(scale_factor),
 701                background: quad.background,
 702                border_color: quad.border_color,
 703                corner_radii: quad.corner_radii.scale(scale_factor),
 704                border_widths: quad.border_widths.scale(scale_factor),
 705            },
 706        );
 707    }
 708
 709    /// Paint the given `Path` into the scene for the next frame at the current z-index.
 710    pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
 711        let scale_factor = self.scale_factor();
 712        let content_mask = self.content_mask();
 713        let view_id = self.parent_view_id();
 714
 715        path.content_mask = content_mask;
 716        path.color = color.into();
 717        path.view_id = view_id.into();
 718        let window = &mut *self.window;
 719        window
 720            .next_frame
 721            .scene
 722            .insert(&window.next_frame.z_index_stack, path.scale(scale_factor));
 723    }
 724
 725    /// Paint an underline into the scene for the next frame at the current z-index.
 726    pub fn paint_underline(
 727        &mut self,
 728        origin: Point<Pixels>,
 729        width: Pixels,
 730        style: &UnderlineStyle,
 731    ) {
 732        let scale_factor = self.scale_factor();
 733        let height = if style.wavy {
 734            style.thickness * 3.
 735        } else {
 736            style.thickness
 737        };
 738        let bounds = Bounds {
 739            origin,
 740            size: size(width, height),
 741        };
 742        let content_mask = self.content_mask();
 743        let view_id = self.parent_view_id();
 744
 745        let window = &mut *self.window;
 746        window.next_frame.scene.insert(
 747            &window.next_frame.z_index_stack,
 748            Underline {
 749                view_id: view_id.into(),
 750                layer_id: 0,
 751                order: 0,
 752                bounds: bounds.scale(scale_factor),
 753                content_mask: content_mask.scale(scale_factor),
 754                thickness: style.thickness.scale(scale_factor),
 755                color: style.color.unwrap_or_default(),
 756                wavy: style.wavy,
 757            },
 758        );
 759    }
 760
 761    /// Paints a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
 762    ///
 763    /// The y component of the origin is the baseline of the glyph.
 764    /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
 765    /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
 766    /// This method is only useful if you need to paint a single glyph that has already been shaped.
 767    pub fn paint_glyph(
 768        &mut self,
 769        origin: Point<Pixels>,
 770        font_id: FontId,
 771        glyph_id: GlyphId,
 772        font_size: Pixels,
 773        color: Hsla,
 774    ) -> Result<()> {
 775        let scale_factor = self.scale_factor();
 776        let glyph_origin = origin.scale(scale_factor);
 777        let subpixel_variant = Point {
 778            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 779            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 780        };
 781        let params = RenderGlyphParams {
 782            font_id,
 783            glyph_id,
 784            font_size,
 785            subpixel_variant,
 786            scale_factor,
 787            is_emoji: false,
 788        };
 789
 790        let raster_bounds = self.text_system().raster_bounds(&params)?;
 791        if !raster_bounds.is_zero() {
 792            let tile =
 793                self.window
 794                    .sprite_atlas
 795                    .get_or_insert_with(&params.clone().into(), &mut || {
 796                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 797                        Ok((size, Cow::Owned(bytes)))
 798                    })?;
 799            let bounds = Bounds {
 800                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 801                size: tile.bounds.size.map(Into::into),
 802            };
 803            let content_mask = self.content_mask().scale(scale_factor);
 804            let view_id = self.parent_view_id();
 805            let window = &mut *self.window;
 806            window.next_frame.scene.insert(
 807                &window.next_frame.z_index_stack,
 808                MonochromeSprite {
 809                    view_id: view_id.into(),
 810                    layer_id: 0,
 811                    order: 0,
 812                    bounds,
 813                    content_mask,
 814                    color,
 815                    tile,
 816                },
 817            );
 818        }
 819        Ok(())
 820    }
 821
 822    /// Paints an emoji glyph into the scene for the next frame at the current z-index.
 823    ///
 824    /// The y component of the origin is the baseline of the glyph.
 825    /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
 826    /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
 827    /// This method is only useful if you need to paint a single emoji that has already been shaped.
 828    pub fn paint_emoji(
 829        &mut self,
 830        origin: Point<Pixels>,
 831        font_id: FontId,
 832        glyph_id: GlyphId,
 833        font_size: Pixels,
 834    ) -> Result<()> {
 835        let scale_factor = self.scale_factor();
 836        let glyph_origin = origin.scale(scale_factor);
 837        let params = RenderGlyphParams {
 838            font_id,
 839            glyph_id,
 840            font_size,
 841            // We don't render emojis with subpixel variants.
 842            subpixel_variant: Default::default(),
 843            scale_factor,
 844            is_emoji: true,
 845        };
 846
 847        let raster_bounds = self.text_system().raster_bounds(&params)?;
 848        if !raster_bounds.is_zero() {
 849            let tile =
 850                self.window
 851                    .sprite_atlas
 852                    .get_or_insert_with(&params.clone().into(), &mut || {
 853                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 854                        Ok((size, Cow::Owned(bytes)))
 855                    })?;
 856            let bounds = Bounds {
 857                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 858                size: tile.bounds.size.map(Into::into),
 859            };
 860            let content_mask = self.content_mask().scale(scale_factor);
 861            let view_id = self.parent_view_id();
 862            let window = &mut *self.window;
 863
 864            window.next_frame.scene.insert(
 865                &window.next_frame.z_index_stack,
 866                PolychromeSprite {
 867                    view_id: view_id.into(),
 868                    layer_id: 0,
 869                    order: 0,
 870                    bounds,
 871                    corner_radii: Default::default(),
 872                    content_mask,
 873                    tile,
 874                    grayscale: false,
 875                },
 876            );
 877        }
 878        Ok(())
 879    }
 880
 881    /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
 882    pub fn paint_svg(
 883        &mut self,
 884        bounds: Bounds<Pixels>,
 885        path: SharedString,
 886        color: Hsla,
 887    ) -> Result<()> {
 888        let scale_factor = self.scale_factor();
 889        let bounds = bounds.scale(scale_factor);
 890        // Render the SVG at twice the size to get a higher quality result.
 891        let params = RenderSvgParams {
 892            path,
 893            size: bounds
 894                .size
 895                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
 896        };
 897
 898        let tile =
 899            self.window
 900                .sprite_atlas
 901                .get_or_insert_with(&params.clone().into(), &mut || {
 902                    let bytes = self.svg_renderer.render(&params)?;
 903                    Ok((params.size, Cow::Owned(bytes)))
 904                })?;
 905        let content_mask = self.content_mask().scale(scale_factor);
 906        let view_id = self.parent_view_id();
 907
 908        let window = &mut *self.window;
 909        window.next_frame.scene.insert(
 910            &window.next_frame.z_index_stack,
 911            MonochromeSprite {
 912                view_id: view_id.into(),
 913                layer_id: 0,
 914                order: 0,
 915                bounds,
 916                content_mask,
 917                color,
 918                tile,
 919            },
 920        );
 921
 922        Ok(())
 923    }
 924
 925    /// Paint an image into the scene for the next frame at the current z-index.
 926    pub fn paint_image(
 927        &mut self,
 928        bounds: Bounds<Pixels>,
 929        corner_radii: Corners<Pixels>,
 930        data: Arc<ImageData>,
 931        grayscale: bool,
 932    ) -> Result<()> {
 933        let scale_factor = self.scale_factor();
 934        let bounds = bounds.scale(scale_factor);
 935        let params = RenderImageParams { image_id: data.id };
 936
 937        let tile = self
 938            .window
 939            .sprite_atlas
 940            .get_or_insert_with(&params.clone().into(), &mut || {
 941                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
 942            })?;
 943        let content_mask = self.content_mask().scale(scale_factor);
 944        let corner_radii = corner_radii.scale(scale_factor);
 945        let view_id = self.parent_view_id();
 946
 947        let window = &mut *self.window;
 948        window.next_frame.scene.insert(
 949            &window.next_frame.z_index_stack,
 950            PolychromeSprite {
 951                view_id: view_id.into(),
 952                layer_id: 0,
 953                order: 0,
 954                bounds,
 955                content_mask,
 956                corner_radii,
 957                tile,
 958                grayscale,
 959            },
 960        );
 961        Ok(())
 962    }
 963
 964    /// Paint a surface into the scene for the next frame at the current z-index.
 965    pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
 966        let scale_factor = self.scale_factor();
 967        let bounds = bounds.scale(scale_factor);
 968        let content_mask = self.content_mask().scale(scale_factor);
 969        let view_id = self.parent_view_id();
 970        let window = &mut *self.window;
 971        window.next_frame.scene.insert(
 972            &window.next_frame.z_index_stack,
 973            Surface {
 974                view_id: view_id.into(),
 975                layer_id: 0,
 976                order: 0,
 977                bounds,
 978                content_mask,
 979                image_buffer,
 980            },
 981        );
 982    }
 983
 984    #[must_use]
 985    /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
 986    /// layout is being requested, along with the layout ids of any children. This method is called during
 987    /// calls to the `Element::layout` trait method and enables any element to participate in layout.
 988    pub fn request_layout(
 989        &mut self,
 990        style: &Style,
 991        children: impl IntoIterator<Item = LayoutId>,
 992    ) -> LayoutId {
 993        self.app.layout_id_buffer.clear();
 994        self.app.layout_id_buffer.extend(children);
 995        let rem_size = self.rem_size();
 996
 997        self.cx
 998            .window
 999            .layout_engine
1000            .as_mut()
1001            .unwrap()
1002            .request_layout(style, rem_size, &self.cx.app.layout_id_buffer)
1003    }
1004
1005    /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
1006    /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
1007    /// determine the element's size. One place this is used internally is when measuring text.
1008    ///
1009    /// The given closure is invoked at layout time with the known dimensions and available space and
1010    /// returns a `Size`.
1011    pub fn request_measured_layout<
1012        F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
1013            + 'static,
1014    >(
1015        &mut self,
1016        style: Style,
1017        measure: F,
1018    ) -> LayoutId {
1019        let rem_size = self.rem_size();
1020        self.window
1021            .layout_engine
1022            .as_mut()
1023            .unwrap()
1024            .request_measured_layout(style, rem_size, measure)
1025    }
1026
1027    /// Compute the layout for the given id within the given available space.
1028    /// This method is called for its side effect, typically by the framework prior to painting.
1029    /// After calling it, you can request the bounds of the given layout node id or any descendant.
1030    pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
1031        let mut layout_engine = self.window.layout_engine.take().unwrap();
1032        layout_engine.compute_layout(layout_id, available_space, self);
1033        self.window.layout_engine = Some(layout_engine);
1034    }
1035
1036    /// Obtain the bounds computed for the given LayoutId relative to the window. This method will usually be invoked by
1037    /// GPUI itself automatically in order to pass your element its `Bounds` automatically.
1038    pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
1039        let mut bounds = self
1040            .window
1041            .layout_engine
1042            .as_mut()
1043            .unwrap()
1044            .layout_bounds(layout_id)
1045            .map(Into::into);
1046        bounds.origin += self.element_offset();
1047        bounds
1048    }
1049
1050    pub(crate) fn layout_style(&self, layout_id: LayoutId) -> Option<&Style> {
1051        self.window
1052            .layout_engine
1053            .as_ref()
1054            .unwrap()
1055            .requested_style(layout_id)
1056    }
1057
1058    /// Called during painting to track which z-index is on top at each pixel position
1059    pub fn add_opaque_layer(&mut self, bounds: Bounds<Pixels>) {
1060        let stacking_order = self.window.next_frame.z_index_stack.clone();
1061        let view_id = self.parent_view_id();
1062        let depth_map = &mut self.window.next_frame.depth_map;
1063        match depth_map.binary_search_by(|(level, _, _)| stacking_order.cmp(level)) {
1064            Ok(i) | Err(i) => depth_map.insert(i, (stacking_order, view_id, bounds)),
1065        }
1066    }
1067
1068    /// Invoke the given function with the given focus handle present on the key dispatch stack.
1069    /// 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.
1070    pub fn with_key_dispatch<R>(
1071        &mut self,
1072        context: Option<KeyContext>,
1073        focus_handle: Option<FocusHandle>,
1074        f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
1075    ) -> R {
1076        let window = &mut self.window;
1077        let focus_id = focus_handle.as_ref().map(|handle| handle.id);
1078        window
1079            .next_frame
1080            .dispatch_tree
1081            .push_node(context.clone(), focus_id, None);
1082
1083        let result = f(focus_handle, self);
1084
1085        self.window.next_frame.dispatch_tree.pop_node();
1086
1087        result
1088    }
1089
1090    /// Invoke the given function with the given view id present on the view stack.
1091    /// This is a fairly low-level method used to layout views.
1092    pub fn with_view_id<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
1093        let text_system = self.text_system().clone();
1094        text_system.with_view(view_id, || {
1095            if self.window.next_frame.view_stack.last() == Some(&view_id) {
1096                f(self)
1097            } else {
1098                self.window.next_frame.view_stack.push(view_id);
1099                let result = f(self);
1100                self.window.next_frame.view_stack.pop();
1101                result
1102            }
1103        })
1104    }
1105
1106    /// Invoke the given function with the given view id present on the view stack.
1107    /// This is a fairly low-level method used to paint views.
1108    pub fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
1109        let text_system = self.text_system().clone();
1110        text_system.with_view(view_id, || {
1111            if self.window.next_frame.view_stack.last() == Some(&view_id) {
1112                f(self)
1113            } else {
1114                self.window.next_frame.view_stack.push(view_id);
1115                self.window
1116                    .next_frame
1117                    .dispatch_tree
1118                    .push_node(None, None, Some(view_id));
1119                let result = f(self);
1120                self.window.next_frame.dispatch_tree.pop_node();
1121                self.window.next_frame.view_stack.pop();
1122                result
1123            }
1124        })
1125    }
1126
1127    /// Sets an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
1128    /// platform to receive textual input with proper integration with concerns such
1129    /// as IME interactions. This handler will be active for the upcoming frame until the following frame is
1130    /// rendered.
1131    ///
1132    /// [element_input_handler]: crate::ElementInputHandler
1133    pub fn handle_input(&mut self, focus_handle: &FocusHandle, input_handler: impl InputHandler) {
1134        if focus_handle.is_focused(self) {
1135            let view_id = self.parent_view_id();
1136            self.window.next_frame.requested_input_handler = Some(RequestedInputHandler {
1137                view_id,
1138                handler: Some(PlatformInputHandler::new(
1139                    self.to_async(),
1140                    Box::new(input_handler),
1141                )),
1142            })
1143        }
1144    }
1145
1146    /// keymatch mode immediate instructs GPUI to prefer shorter action bindings.
1147    /// In the case that you have a keybinding of `"cmd-k": "terminal::Clear"` and
1148    /// `"cmd-k left": "workspace::MoveLeft"`, GPUI will by default wait for 1s after
1149    /// you type cmd-k to see if you're going to type left.
1150    /// This is problematic in the terminal
1151    pub fn keymatch_mode_immediate(&mut self) {
1152        self.window.next_frame.dispatch_tree.keymatch_mode = KeymatchMode::Immediate;
1153    }
1154
1155    /// Register a mouse event listener on the window for the next frame. The type of event
1156    /// is determined by the first parameter of the given listener. When the next frame is rendered
1157    /// the listener will be cleared.
1158    pub fn on_mouse_event<Event: MouseEvent>(
1159        &mut self,
1160        mut handler: impl FnMut(&Event, DispatchPhase, &mut ElementContext) + 'static,
1161    ) {
1162        let view_id = self.parent_view_id();
1163        let order = self.window.next_frame.z_index_stack.clone();
1164        self.window
1165            .next_frame
1166            .mouse_listeners
1167            .entry(TypeId::of::<Event>())
1168            .or_default()
1169            .push((
1170                order,
1171                view_id,
1172                Box::new(
1173                    move |event: &dyn Any, phase: DispatchPhase, cx: &mut ElementContext<'_>| {
1174                        handler(event.downcast_ref().unwrap(), phase, cx)
1175                    },
1176                ),
1177            ))
1178    }
1179
1180    /// Register a key event listener on the window for the next frame. The type of event
1181    /// is determined by the first parameter of the given listener. When the next frame is rendered
1182    /// the listener will be cleared.
1183    ///
1184    /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
1185    /// a specific need to register a global listener.
1186    pub fn on_key_event<Event: KeyEvent>(
1187        &mut self,
1188        listener: impl Fn(&Event, DispatchPhase, &mut ElementContext) + 'static,
1189    ) {
1190        self.window.next_frame.dispatch_tree.on_key_event(Rc::new(
1191            move |event: &dyn Any, phase, cx: &mut ElementContext<'_>| {
1192                if let Some(event) = event.downcast_ref::<Event>() {
1193                    listener(event, phase, cx)
1194                }
1195            },
1196        ));
1197    }
1198}