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