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    cmp, mem,
  19    ops::Range,
  20    rc::Rc,
  21    sync::Arc,
  22};
  23
  24use anyhow::Result;
  25use collections::FxHashMap;
  26use derive_more::{Deref, DerefMut};
  27use futures::{future::Shared, FutureExt};
  28#[cfg(target_os = "macos")]
  29use media::core_video::CVImageBuffer;
  30use smallvec::SmallVec;
  31use util::post_inc;
  32
  33use crate::{
  34    hash, point, prelude::*, px, size, AnyElement, AnyTooltip, AppContext, Asset, AvailableSpace,
  35    Bounds, BoxShadow, ContentMask, Corners, CursorStyle, DevicePixels, DispatchNodeId,
  36    DispatchPhase, DispatchTree, DrawPhase, ElementId, ElementStateBox, EntityId, FocusHandle,
  37    FocusId, FontId, GlobalElementId, GlyphId, Hsla, ImageData, InputHandler, IsZero, KeyContext,
  38    KeyEvent, LayoutId, LineLayoutIndex, ModifiersChangedEvent, MonochromeSprite, MouseEvent,
  39    PaintQuad, Path, Pixels, PlatformInputHandler, Point, PolychromeSprite, Quad,
  40    RenderGlyphParams, RenderImageParams, RenderSvgParams, Scene, Shadow, SharedString, Size,
  41    StrikethroughStyle, Style, Task, TextStyleRefinement, TransformationMatrix, Underline,
  42    UnderlineStyle, Window, WindowContext, SUBPIXEL_VARIANTS,
  43};
  44
  45pub(crate) type AnyMouseListener =
  46    Box<dyn FnMut(&dyn Any, DispatchPhase, &mut ElementContext) + 'static>;
  47
  48#[derive(Clone)]
  49pub(crate) struct CursorStyleRequest {
  50    pub(crate) hitbox_id: HitboxId,
  51    pub(crate) style: CursorStyle,
  52}
  53
  54/// An identifier for a [Hitbox].
  55#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
  56pub struct HitboxId(usize);
  57
  58impl HitboxId {
  59    /// Checks if the hitbox with this id is currently hovered.
  60    pub fn is_hovered(&self, cx: &WindowContext) -> bool {
  61        cx.window.mouse_hit_test.0.contains(self)
  62    }
  63}
  64
  65/// A rectangular region that potentially blocks hitboxes inserted prior.
  66/// See [ElementContext::insert_hitbox] for more details.
  67#[derive(Clone, Debug, Deref)]
  68pub struct Hitbox {
  69    /// A unique identifier for the hitbox
  70    pub id: HitboxId,
  71    /// The bounds of the hitbox
  72    #[deref]
  73    pub bounds: Bounds<Pixels>,
  74    /// Whether the hitbox occludes other hitboxes inserted prior.
  75    pub opaque: bool,
  76}
  77
  78impl Hitbox {
  79    /// Checks if the hitbox is currently hovered.
  80    pub fn is_hovered(&self, cx: &WindowContext) -> bool {
  81        self.id.is_hovered(cx)
  82    }
  83}
  84
  85#[derive(Default, Eq, PartialEq)]
  86pub(crate) struct HitTest(SmallVec<[HitboxId; 8]>);
  87
  88/// An identifier for a tooltip.
  89#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
  90pub struct TooltipId(usize);
  91
  92impl TooltipId {
  93    /// Checks if the tooltip is currently hovered.
  94    pub fn is_hovered(&self, cx: &WindowContext) -> bool {
  95        cx.window
  96            .tooltip_bounds
  97            .as_ref()
  98            .map_or(false, |tooltip_bounds| {
  99                tooltip_bounds.id == *self && tooltip_bounds.bounds.contains(&cx.mouse_position())
 100            })
 101    }
 102}
 103
 104pub(crate) struct TooltipBounds {
 105    id: TooltipId,
 106    bounds: Bounds<Pixels>,
 107}
 108
 109#[derive(Clone)]
 110pub(crate) struct TooltipRequest {
 111    id: TooltipId,
 112    tooltip: AnyTooltip,
 113}
 114
 115pub(crate) struct DeferredDraw {
 116    priority: usize,
 117    parent_node: DispatchNodeId,
 118    element_id_stack: GlobalElementId,
 119    text_style_stack: Vec<TextStyleRefinement>,
 120    element: Option<AnyElement>,
 121    absolute_offset: Point<Pixels>,
 122    layout_range: Range<AfterLayoutIndex>,
 123    paint_range: Range<PaintIndex>,
 124}
 125
 126pub(crate) struct Frame {
 127    pub(crate) focus: Option<FocusId>,
 128    pub(crate) window_active: bool,
 129    pub(crate) element_states: FxHashMap<(GlobalElementId, TypeId), ElementStateBox>,
 130    accessed_element_states: Vec<(GlobalElementId, TypeId)>,
 131    pub(crate) mouse_listeners: Vec<Option<AnyMouseListener>>,
 132    pub(crate) dispatch_tree: DispatchTree,
 133    pub(crate) scene: Scene,
 134    pub(crate) hitboxes: Vec<Hitbox>,
 135    pub(crate) deferred_draws: Vec<DeferredDraw>,
 136    pub(crate) content_mask_stack: Vec<ContentMask<Pixels>>,
 137    pub(crate) element_offset_stack: Vec<Point<Pixels>>,
 138    pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,
 139    pub(crate) tooltip_requests: Vec<Option<TooltipRequest>>,
 140    pub(crate) cursor_styles: Vec<CursorStyleRequest>,
 141    #[cfg(any(test, feature = "test-support"))]
 142    pub(crate) debug_bounds: FxHashMap<String, Bounds<Pixels>>,
 143}
 144
 145#[derive(Clone, Default)]
 146pub(crate) struct AfterLayoutIndex {
 147    hitboxes_index: usize,
 148    tooltips_index: usize,
 149    deferred_draws_index: usize,
 150    dispatch_tree_index: usize,
 151    accessed_element_states_index: usize,
 152    line_layout_index: LineLayoutIndex,
 153}
 154
 155#[derive(Clone, Default)]
 156pub(crate) struct PaintIndex {
 157    scene_index: usize,
 158    mouse_listeners_index: usize,
 159    input_handlers_index: usize,
 160    cursor_styles_index: usize,
 161    accessed_element_states_index: usize,
 162    line_layout_index: LineLayoutIndex,
 163}
 164
 165impl Frame {
 166    pub(crate) fn new(dispatch_tree: DispatchTree) -> Self {
 167        Frame {
 168            focus: None,
 169            window_active: false,
 170            element_states: FxHashMap::default(),
 171            accessed_element_states: Vec::new(),
 172            mouse_listeners: Vec::new(),
 173            dispatch_tree,
 174            scene: Scene::default(),
 175            hitboxes: Vec::new(),
 176            deferred_draws: Vec::new(),
 177            content_mask_stack: Vec::new(),
 178            element_offset_stack: Vec::new(),
 179            input_handlers: Vec::new(),
 180            tooltip_requests: Vec::new(),
 181            cursor_styles: Vec::new(),
 182
 183            #[cfg(any(test, feature = "test-support"))]
 184            debug_bounds: FxHashMap::default(),
 185        }
 186    }
 187
 188    pub(crate) fn clear(&mut self) {
 189        self.element_states.clear();
 190        self.accessed_element_states.clear();
 191        self.mouse_listeners.clear();
 192        self.dispatch_tree.clear();
 193        self.scene.clear();
 194        self.input_handlers.clear();
 195        self.tooltip_requests.clear();
 196        self.cursor_styles.clear();
 197        self.hitboxes.clear();
 198        self.deferred_draws.clear();
 199    }
 200
 201    pub(crate) fn hit_test(&self, position: Point<Pixels>) -> HitTest {
 202        let mut hit_test = HitTest::default();
 203        for hitbox in self.hitboxes.iter().rev() {
 204            if hitbox.bounds.contains(&position) {
 205                hit_test.0.push(hitbox.id);
 206                if hitbox.opaque {
 207                    break;
 208                }
 209            }
 210        }
 211        hit_test
 212    }
 213
 214    pub(crate) fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
 215        self.focus
 216            .map(|focus_id| self.dispatch_tree.focus_path(focus_id))
 217            .unwrap_or_default()
 218    }
 219
 220    pub(crate) fn finish(&mut self, prev_frame: &mut Self) {
 221        for element_state_key in &self.accessed_element_states {
 222            if let Some(element_state) = prev_frame.element_states.remove(element_state_key) {
 223                self.element_states
 224                    .insert(element_state_key.clone(), element_state);
 225            }
 226        }
 227
 228        self.scene.finish();
 229    }
 230}
 231
 232/// This context is used for assisting in the implementation of the element trait
 233#[derive(Deref, DerefMut)]
 234pub struct ElementContext<'a> {
 235    pub(crate) cx: WindowContext<'a>,
 236}
 237
 238impl<'a> WindowContext<'a> {
 239    /// Convert this window context into an ElementContext in this callback.
 240    /// If you need to use this method, you're probably intermixing the imperative
 241    /// and declarative APIs, which is not recommended.
 242    pub fn with_element_context<R>(&mut self, f: impl FnOnce(&mut ElementContext) -> R) -> R {
 243        f(&mut ElementContext {
 244            cx: WindowContext::new(self.app, self.window),
 245        })
 246    }
 247}
 248
 249impl<'a> Borrow<AppContext> for ElementContext<'a> {
 250    fn borrow(&self) -> &AppContext {
 251        self.cx.app
 252    }
 253}
 254
 255impl<'a> BorrowMut<AppContext> for ElementContext<'a> {
 256    fn borrow_mut(&mut self) -> &mut AppContext {
 257        self.cx.borrow_mut()
 258    }
 259}
 260
 261impl<'a> Borrow<WindowContext<'a>> for ElementContext<'a> {
 262    fn borrow(&self) -> &WindowContext<'a> {
 263        &self.cx
 264    }
 265}
 266
 267impl<'a> BorrowMut<WindowContext<'a>> for ElementContext<'a> {
 268    fn borrow_mut(&mut self) -> &mut WindowContext<'a> {
 269        &mut self.cx
 270    }
 271}
 272
 273impl<'a> Borrow<Window> for ElementContext<'a> {
 274    fn borrow(&self) -> &Window {
 275        self.cx.window
 276    }
 277}
 278
 279impl<'a> BorrowMut<Window> for ElementContext<'a> {
 280    fn borrow_mut(&mut self) -> &mut Window {
 281        self.cx.borrow_mut()
 282    }
 283}
 284
 285impl<'a> Context for ElementContext<'a> {
 286    type Result<T> = <WindowContext<'a> as Context>::Result<T>;
 287
 288    fn new_model<T: 'static>(
 289        &mut self,
 290        build_model: impl FnOnce(&mut crate::ModelContext<'_, T>) -> T,
 291    ) -> Self::Result<crate::Model<T>> {
 292        self.cx.new_model(build_model)
 293    }
 294
 295    fn reserve_model<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> {
 296        self.cx.reserve_model()
 297    }
 298
 299    fn insert_model<T: 'static>(
 300        &mut self,
 301        reservation: crate::Reservation<T>,
 302        build_model: impl FnOnce(&mut crate::ModelContext<'_, T>) -> T,
 303    ) -> Self::Result<crate::Model<T>> {
 304        self.cx.insert_model(reservation, build_model)
 305    }
 306
 307    fn update_model<T, R>(
 308        &mut self,
 309        handle: &crate::Model<T>,
 310        update: impl FnOnce(&mut T, &mut crate::ModelContext<'_, T>) -> R,
 311    ) -> Self::Result<R>
 312    where
 313        T: 'static,
 314    {
 315        self.cx.update_model(handle, update)
 316    }
 317
 318    fn read_model<T, R>(
 319        &self,
 320        handle: &crate::Model<T>,
 321        read: impl FnOnce(&T, &AppContext) -> R,
 322    ) -> Self::Result<R>
 323    where
 324        T: 'static,
 325    {
 326        self.cx.read_model(handle, read)
 327    }
 328
 329    fn update_window<T, F>(&mut self, window: crate::AnyWindowHandle, f: F) -> Result<T>
 330    where
 331        F: FnOnce(crate::AnyView, &mut WindowContext<'_>) -> T,
 332    {
 333        self.cx.update_window(window, f)
 334    }
 335
 336    fn read_window<T, R>(
 337        &self,
 338        window: &crate::WindowHandle<T>,
 339        read: impl FnOnce(crate::View<T>, &AppContext) -> R,
 340    ) -> Result<R>
 341    where
 342        T: 'static,
 343    {
 344        self.cx.read_window(window, read)
 345    }
 346}
 347
 348impl<'a> VisualContext for ElementContext<'a> {
 349    fn new_view<V>(
 350        &mut self,
 351        build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
 352    ) -> Self::Result<crate::View<V>>
 353    where
 354        V: 'static + Render,
 355    {
 356        self.cx.new_view(build_view)
 357    }
 358
 359    fn update_view<V: 'static, R>(
 360        &mut self,
 361        view: &crate::View<V>,
 362        update: impl FnOnce(&mut V, &mut crate::ViewContext<'_, V>) -> R,
 363    ) -> Self::Result<R> {
 364        self.cx.update_view(view, update)
 365    }
 366
 367    fn replace_root_view<V>(
 368        &mut self,
 369        build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
 370    ) -> Self::Result<crate::View<V>>
 371    where
 372        V: 'static + Render,
 373    {
 374        self.cx.replace_root_view(build_view)
 375    }
 376
 377    fn focus_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
 378    where
 379        V: crate::FocusableView,
 380    {
 381        self.cx.focus_view(view)
 382    }
 383
 384    fn dismiss_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
 385    where
 386        V: crate::ManagedView,
 387    {
 388        self.cx.dismiss_view(view)
 389    }
 390}
 391
 392impl<'a> ElementContext<'a> {
 393    pub(crate) fn draw_roots(&mut self) {
 394        self.window.draw_phase = DrawPhase::Layout;
 395        self.window.tooltip_bounds.take();
 396
 397        // Layout all root elements.
 398        let mut root_element = self.window.root_view.as_ref().unwrap().clone().into_any();
 399        root_element.layout(Point::default(), self.window.viewport_size.into(), self);
 400
 401        let mut sorted_deferred_draws =
 402            (0..self.window.next_frame.deferred_draws.len()).collect::<SmallVec<[_; 8]>>();
 403        sorted_deferred_draws.sort_by_key(|ix| self.window.next_frame.deferred_draws[*ix].priority);
 404        self.layout_deferred_draws(&sorted_deferred_draws);
 405
 406        let mut prompt_element = None;
 407        let mut active_drag_element = None;
 408        let mut tooltip_element = None;
 409        if let Some(prompt) = self.window.prompt.take() {
 410            let mut element = prompt.view.any_view().into_any();
 411            element.layout(Point::default(), self.window.viewport_size.into(), self);
 412            prompt_element = Some(element);
 413            self.window.prompt = Some(prompt);
 414        } else if let Some(active_drag) = self.app.active_drag.take() {
 415            let mut element = active_drag.view.clone().into_any();
 416            let offset = self.mouse_position() - active_drag.cursor_offset;
 417            element.layout(offset, AvailableSpace::min_size(), self);
 418            active_drag_element = Some(element);
 419            self.app.active_drag = Some(active_drag);
 420        } else {
 421            tooltip_element = self.layout_tooltip();
 422        }
 423
 424        self.window.mouse_hit_test = self.window.next_frame.hit_test(self.window.mouse_position);
 425
 426        // Now actually paint the elements.
 427        self.window.draw_phase = DrawPhase::Paint;
 428        root_element.paint(self);
 429
 430        self.paint_deferred_draws(&sorted_deferred_draws);
 431
 432        if let Some(mut prompt_element) = prompt_element {
 433            prompt_element.paint(self)
 434        } else if let Some(mut drag_element) = active_drag_element {
 435            drag_element.paint(self);
 436        } else if let Some(mut tooltip_element) = tooltip_element {
 437            tooltip_element.paint(self);
 438        }
 439    }
 440
 441    fn layout_tooltip(&mut self) -> Option<AnyElement> {
 442        let tooltip_request = self.window.next_frame.tooltip_requests.last().cloned()?;
 443        let tooltip_request = tooltip_request.unwrap();
 444        let mut element = tooltip_request.tooltip.view.clone().into_any();
 445        let mouse_position = tooltip_request.tooltip.mouse_position;
 446        let tooltip_size = element.measure(AvailableSpace::min_size(), self);
 447
 448        let mut tooltip_bounds = Bounds::new(mouse_position + point(px(1.), px(1.)), tooltip_size);
 449        let window_bounds = Bounds {
 450            origin: Point::default(),
 451            size: self.viewport_size(),
 452        };
 453
 454        if tooltip_bounds.right() > window_bounds.right() {
 455            let new_x = mouse_position.x - tooltip_bounds.size.width - px(1.);
 456            if new_x >= Pixels::ZERO {
 457                tooltip_bounds.origin.x = new_x;
 458            } else {
 459                tooltip_bounds.origin.x = cmp::max(
 460                    Pixels::ZERO,
 461                    tooltip_bounds.origin.x - tooltip_bounds.right() - window_bounds.right(),
 462                );
 463            }
 464        }
 465
 466        if tooltip_bounds.bottom() > window_bounds.bottom() {
 467            let new_y = mouse_position.y - tooltip_bounds.size.height - px(1.);
 468            if new_y >= Pixels::ZERO {
 469                tooltip_bounds.origin.y = new_y;
 470            } else {
 471                tooltip_bounds.origin.y = cmp::max(
 472                    Pixels::ZERO,
 473                    tooltip_bounds.origin.y - tooltip_bounds.bottom() - window_bounds.bottom(),
 474                );
 475            }
 476        }
 477
 478        self.with_absolute_element_offset(tooltip_bounds.origin, |cx| element.after_layout(cx));
 479
 480        self.window.tooltip_bounds = Some(TooltipBounds {
 481            id: tooltip_request.id,
 482            bounds: tooltip_bounds,
 483        });
 484        Some(element)
 485    }
 486
 487    fn layout_deferred_draws(&mut self, deferred_draw_indices: &[usize]) {
 488        assert_eq!(self.window.element_id_stack.len(), 0);
 489
 490        let mut deferred_draws = mem::take(&mut self.window.next_frame.deferred_draws);
 491        for deferred_draw_ix in deferred_draw_indices {
 492            let deferred_draw = &mut deferred_draws[*deferred_draw_ix];
 493            self.window.element_id_stack = deferred_draw.element_id_stack.clone();
 494            self.window.text_style_stack = deferred_draw.text_style_stack.clone();
 495            self.window
 496                .next_frame
 497                .dispatch_tree
 498                .set_active_node(deferred_draw.parent_node);
 499
 500            let layout_start = self.after_layout_index();
 501            if let Some(element) = deferred_draw.element.as_mut() {
 502                self.with_absolute_element_offset(deferred_draw.absolute_offset, |cx| {
 503                    element.after_layout(cx)
 504                });
 505            } else {
 506                self.reuse_after_layout(deferred_draw.layout_range.clone());
 507            }
 508            let layout_end = self.after_layout_index();
 509            deferred_draw.layout_range = layout_start..layout_end;
 510        }
 511        assert_eq!(
 512            self.window.next_frame.deferred_draws.len(),
 513            0,
 514            "cannot call defer_draw during deferred drawing"
 515        );
 516        self.window.next_frame.deferred_draws = deferred_draws;
 517        self.window.element_id_stack.clear();
 518        self.window.text_style_stack.clear();
 519    }
 520
 521    fn paint_deferred_draws(&mut self, deferred_draw_indices: &[usize]) {
 522        assert_eq!(self.window.element_id_stack.len(), 0);
 523
 524        let mut deferred_draws = mem::take(&mut self.window.next_frame.deferred_draws);
 525        for deferred_draw_ix in deferred_draw_indices {
 526            let mut deferred_draw = &mut deferred_draws[*deferred_draw_ix];
 527            self.window.element_id_stack = deferred_draw.element_id_stack.clone();
 528            self.window
 529                .next_frame
 530                .dispatch_tree
 531                .set_active_node(deferred_draw.parent_node);
 532
 533            let paint_start = self.paint_index();
 534            if let Some(element) = deferred_draw.element.as_mut() {
 535                element.paint(self);
 536            } else {
 537                self.reuse_paint(deferred_draw.paint_range.clone());
 538            }
 539            let paint_end = self.paint_index();
 540            deferred_draw.paint_range = paint_start..paint_end;
 541        }
 542        self.window.next_frame.deferred_draws = deferred_draws;
 543        self.window.element_id_stack.clear();
 544    }
 545
 546    pub(crate) fn after_layout_index(&self) -> AfterLayoutIndex {
 547        AfterLayoutIndex {
 548            hitboxes_index: self.window.next_frame.hitboxes.len(),
 549            tooltips_index: self.window.next_frame.tooltip_requests.len(),
 550            deferred_draws_index: self.window.next_frame.deferred_draws.len(),
 551            dispatch_tree_index: self.window.next_frame.dispatch_tree.len(),
 552            accessed_element_states_index: self.window.next_frame.accessed_element_states.len(),
 553            line_layout_index: self.window.text_system.layout_index(),
 554        }
 555    }
 556
 557    pub(crate) fn reuse_after_layout(&mut self, range: Range<AfterLayoutIndex>) {
 558        let window = &mut self.window;
 559        window.next_frame.hitboxes.extend(
 560            window.rendered_frame.hitboxes[range.start.hitboxes_index..range.end.hitboxes_index]
 561                .iter()
 562                .cloned(),
 563        );
 564        window.next_frame.tooltip_requests.extend(
 565            window.rendered_frame.tooltip_requests
 566                [range.start.tooltips_index..range.end.tooltips_index]
 567                .iter_mut()
 568                .map(|request| request.take()),
 569        );
 570        window.next_frame.accessed_element_states.extend(
 571            window.rendered_frame.accessed_element_states[range.start.accessed_element_states_index
 572                ..range.end.accessed_element_states_index]
 573                .iter()
 574                .cloned(),
 575        );
 576        window
 577            .text_system
 578            .reuse_layouts(range.start.line_layout_index..range.end.line_layout_index);
 579
 580        let reused_subtree = window.next_frame.dispatch_tree.reuse_subtree(
 581            range.start.dispatch_tree_index..range.end.dispatch_tree_index,
 582            &mut window.rendered_frame.dispatch_tree,
 583        );
 584        window.next_frame.deferred_draws.extend(
 585            window.rendered_frame.deferred_draws
 586                [range.start.deferred_draws_index..range.end.deferred_draws_index]
 587                .iter()
 588                .map(|deferred_draw| DeferredDraw {
 589                    parent_node: reused_subtree.refresh_node_id(deferred_draw.parent_node),
 590                    element_id_stack: deferred_draw.element_id_stack.clone(),
 591                    text_style_stack: deferred_draw.text_style_stack.clone(),
 592                    priority: deferred_draw.priority,
 593                    element: None,
 594                    absolute_offset: deferred_draw.absolute_offset,
 595                    layout_range: deferred_draw.layout_range.clone(),
 596                    paint_range: deferred_draw.paint_range.clone(),
 597                }),
 598        );
 599    }
 600
 601    pub(crate) fn paint_index(&self) -> PaintIndex {
 602        PaintIndex {
 603            scene_index: self.window.next_frame.scene.len(),
 604            mouse_listeners_index: self.window.next_frame.mouse_listeners.len(),
 605            input_handlers_index: self.window.next_frame.input_handlers.len(),
 606            cursor_styles_index: self.window.next_frame.cursor_styles.len(),
 607            accessed_element_states_index: self.window.next_frame.accessed_element_states.len(),
 608            line_layout_index: self.window.text_system.layout_index(),
 609        }
 610    }
 611
 612    pub(crate) fn reuse_paint(&mut self, range: Range<PaintIndex>) {
 613        let window = &mut self.cx.window;
 614
 615        window.next_frame.cursor_styles.extend(
 616            window.rendered_frame.cursor_styles
 617                [range.start.cursor_styles_index..range.end.cursor_styles_index]
 618                .iter()
 619                .cloned(),
 620        );
 621        window.next_frame.input_handlers.extend(
 622            window.rendered_frame.input_handlers
 623                [range.start.input_handlers_index..range.end.input_handlers_index]
 624                .iter_mut()
 625                .map(|handler| handler.take()),
 626        );
 627        window.next_frame.mouse_listeners.extend(
 628            window.rendered_frame.mouse_listeners
 629                [range.start.mouse_listeners_index..range.end.mouse_listeners_index]
 630                .iter_mut()
 631                .map(|listener| listener.take()),
 632        );
 633        window.next_frame.accessed_element_states.extend(
 634            window.rendered_frame.accessed_element_states[range.start.accessed_element_states_index
 635                ..range.end.accessed_element_states_index]
 636                .iter()
 637                .cloned(),
 638        );
 639        window
 640            .text_system
 641            .reuse_layouts(range.start.line_layout_index..range.end.line_layout_index);
 642        window.next_frame.scene.replay(
 643            range.start.scene_index..range.end.scene_index,
 644            &window.rendered_frame.scene,
 645        );
 646    }
 647
 648    /// Push a text style onto the stack, and call a function with that style active.
 649    /// Use [`AppContext::text_style`] to get the current, combined text style.
 650    pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
 651    where
 652        F: FnOnce(&mut Self) -> R,
 653    {
 654        if let Some(style) = style {
 655            self.window.text_style_stack.push(style);
 656            let result = f(self);
 657            self.window.text_style_stack.pop();
 658            result
 659        } else {
 660            f(self)
 661        }
 662    }
 663
 664    /// Updates the cursor style at the platform level.
 665    pub fn set_cursor_style(&mut self, style: CursorStyle, hitbox: &Hitbox) {
 666        self.window
 667            .next_frame
 668            .cursor_styles
 669            .push(CursorStyleRequest {
 670                hitbox_id: hitbox.id,
 671                style,
 672            });
 673    }
 674
 675    /// Sets a tooltip to be rendered for the upcoming frame
 676    pub fn set_tooltip(&mut self, tooltip: AnyTooltip) -> TooltipId {
 677        let id = TooltipId(post_inc(&mut self.window.next_tooltip_id.0));
 678        self.window
 679            .next_frame
 680            .tooltip_requests
 681            .push(Some(TooltipRequest { id, tooltip }));
 682        id
 683    }
 684
 685    /// Pushes the given element id onto the global stack and invokes the given closure
 686    /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
 687    /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
 688    /// used to associate state with identified elements across separate frames.
 689    pub fn with_element_id<R>(
 690        &mut self,
 691        id: Option<impl Into<ElementId>>,
 692        f: impl FnOnce(&mut Self) -> R,
 693    ) -> R {
 694        if let Some(id) = id.map(Into::into) {
 695            let window = self.window_mut();
 696            window.element_id_stack.push(id);
 697            let result = f(self);
 698            let window: &mut Window = self.borrow_mut();
 699            window.element_id_stack.pop();
 700            result
 701        } else {
 702            f(self)
 703        }
 704    }
 705
 706    /// Invoke the given function with the given content mask after intersecting it
 707    /// with the current mask.
 708    pub fn with_content_mask<R>(
 709        &mut self,
 710        mask: Option<ContentMask<Pixels>>,
 711        f: impl FnOnce(&mut Self) -> R,
 712    ) -> R {
 713        if let Some(mask) = mask {
 714            let mask = mask.intersect(&self.content_mask());
 715            self.window_mut().next_frame.content_mask_stack.push(mask);
 716            let result = f(self);
 717            self.window_mut().next_frame.content_mask_stack.pop();
 718            result
 719        } else {
 720            f(self)
 721        }
 722    }
 723
 724    /// Updates the global element offset relative to the current offset. This is used to implement
 725    /// scrolling.
 726    pub fn with_element_offset<R>(
 727        &mut self,
 728        offset: Point<Pixels>,
 729        f: impl FnOnce(&mut Self) -> R,
 730    ) -> R {
 731        if offset.is_zero() {
 732            return f(self);
 733        };
 734
 735        let abs_offset = self.element_offset() + offset;
 736        self.with_absolute_element_offset(abs_offset, f)
 737    }
 738
 739    /// Updates the global element offset based on the given offset. This is used to implement
 740    /// drag handles and other manual painting of elements.
 741    pub fn with_absolute_element_offset<R>(
 742        &mut self,
 743        offset: Point<Pixels>,
 744        f: impl FnOnce(&mut Self) -> R,
 745    ) -> R {
 746        self.window_mut()
 747            .next_frame
 748            .element_offset_stack
 749            .push(offset);
 750        let result = f(self);
 751        self.window_mut().next_frame.element_offset_stack.pop();
 752        result
 753    }
 754
 755    /// Remove an asset from GPUI's cache
 756    pub fn remove_cached_asset<A: Asset + 'static>(
 757        &mut self,
 758        source: &A::Source,
 759    ) -> Option<A::Output> {
 760        self.asset_cache.remove::<A>(source)
 761    }
 762
 763    /// Asynchronously load an asset, if the asset hasn't finished loading this will return None.
 764    /// Your view will be re-drawn once the asset has finished loading.
 765    ///
 766    /// Note that the multiple calls to this method will only result in one `Asset::load` call.
 767    /// The results of that call will be cached, and returned on subsequent uses of this API.
 768    ///
 769    /// Use [Self::remove_cached_asset] to reload your asset.
 770    pub fn use_cached_asset<A: Asset + 'static>(
 771        &mut self,
 772        source: &A::Source,
 773    ) -> Option<A::Output> {
 774        self.asset_cache.get::<A>(source).or_else(|| {
 775            if let Some(asset) = self.use_asset::<A>(source) {
 776                self.asset_cache
 777                    .insert::<A>(source.to_owned(), asset.clone());
 778                Some(asset)
 779            } else {
 780                None
 781            }
 782        })
 783    }
 784
 785    /// Asynchronously load an asset, if the asset hasn't finished loading this will return None.
 786    /// Your view will be re-drawn once the asset has finished loading.
 787    ///
 788    /// Note that the multiple calls to this method will only result in one `Asset::load` call at a
 789    /// time.
 790    ///
 791    /// This asset will not be cached by default, see [Self::use_cached_asset]
 792    pub fn use_asset<A: Asset + 'static>(&mut self, source: &A::Source) -> Option<A::Output> {
 793        let asset_id = (TypeId::of::<A>(), hash(source));
 794        let mut is_first = false;
 795        let task = self
 796            .loading_assets
 797            .remove(&asset_id)
 798            .map(|boxed_task| *boxed_task.downcast::<Shared<Task<A::Output>>>().unwrap())
 799            .unwrap_or_else(|| {
 800                is_first = true;
 801                let future = A::load(source.clone(), self);
 802                let task = self.background_executor().spawn(future).shared();
 803                task
 804            });
 805
 806        task.clone().now_or_never().or_else(|| {
 807            if is_first {
 808                let parent_id = self.parent_view_id();
 809                self.spawn({
 810                    let task = task.clone();
 811                    |mut cx| async move {
 812                        task.await;
 813
 814                        cx.on_next_frame(move |cx| {
 815                            if let Some(parent_id) = parent_id {
 816                                cx.notify(parent_id)
 817                            } else {
 818                                cx.refresh()
 819                            }
 820                        });
 821                    }
 822                })
 823                .detach();
 824            }
 825
 826            self.loading_assets.insert(asset_id, Box::new(task));
 827
 828            None
 829        })
 830    }
 831
 832    /// Obtain the current element offset.
 833    pub fn element_offset(&self) -> Point<Pixels> {
 834        self.window()
 835            .next_frame
 836            .element_offset_stack
 837            .last()
 838            .copied()
 839            .unwrap_or_default()
 840    }
 841
 842    /// Obtain the current content mask.
 843    pub fn content_mask(&self) -> ContentMask<Pixels> {
 844        self.window()
 845            .next_frame
 846            .content_mask_stack
 847            .last()
 848            .cloned()
 849            .unwrap_or_else(|| ContentMask {
 850                bounds: Bounds {
 851                    origin: Point::default(),
 852                    size: self.window().viewport_size,
 853                },
 854            })
 855    }
 856
 857    /// The size of an em for the base font of the application. Adjusting this value allows the
 858    /// UI to scale, just like zooming a web page.
 859    pub fn rem_size(&self) -> Pixels {
 860        self.window().rem_size
 861    }
 862
 863    /// Updates or initializes state for an element with the given id that lives across multiple
 864    /// frames. If an element with this ID existed in the rendered frame, its state will be passed
 865    /// to the given closure. The state returned by the closure will be stored so it can be referenced
 866    /// when drawing the next frame.
 867    pub fn with_element_state<S, R>(
 868        &mut self,
 869        element_id: Option<ElementId>,
 870        f: impl FnOnce(Option<Option<S>>, &mut Self) -> (R, Option<S>),
 871    ) -> R
 872    where
 873        S: 'static,
 874    {
 875        let id_is_none = element_id.is_none();
 876        self.with_element_id(element_id, |cx| {
 877            if id_is_none {
 878                let (result, state) = f(None, cx);
 879                debug_assert!(state.is_none(), "you must not return an element state when passing None for the element id");
 880                result
 881            } else {
 882                let global_id = cx.window().element_id_stack.clone();
 883                let key = (global_id, TypeId::of::<S>());
 884                cx.window.next_frame.accessed_element_states.push(key.clone());
 885
 886                if let Some(any) = cx
 887                    .window_mut()
 888                    .next_frame
 889                    .element_states
 890                    .remove(&key)
 891                    .or_else(|| {
 892                        cx.window_mut()
 893                            .rendered_frame
 894                            .element_states
 895                            .remove(&key)
 896                    })
 897                {
 898                    let ElementStateBox {
 899                        inner,
 900                        #[cfg(debug_assertions)]
 901                        type_name
 902                    } = any;
 903                    // Using the extra inner option to avoid needing to reallocate a new box.
 904                    let mut state_box = inner
 905                        .downcast::<Option<S>>()
 906                        .map_err(|_| {
 907                            #[cfg(debug_assertions)]
 908                            {
 909                                anyhow::anyhow!(
 910                                    "invalid element state type for id, requested_type {:?}, actual type: {:?}",
 911                                    std::any::type_name::<S>(),
 912                                    type_name
 913                                )
 914                            }
 915
 916                            #[cfg(not(debug_assertions))]
 917                            {
 918                                anyhow::anyhow!(
 919                                    "invalid element state type for id, requested_type {:?}",
 920                                    std::any::type_name::<S>(),
 921                                )
 922                            }
 923                        })
 924                        .unwrap();
 925
 926                    // Actual: Option<AnyElement> <- View
 927                    // Requested: () <- AnyElement
 928                    let state = state_box
 929                        .take()
 930                        .expect("reentrant call to with_element_state for the same state type and element id");
 931                    let (result, state) = f(Some(Some(state)), cx);
 932                    state_box.replace(state.expect("you must return "));
 933                    cx.window_mut()
 934                        .next_frame
 935                        .element_states
 936                        .insert(key, ElementStateBox {
 937                            inner: state_box,
 938                            #[cfg(debug_assertions)]
 939                            type_name
 940                        });
 941                    result
 942                } else {
 943                    let (result, state) = f(Some(None), cx);
 944                    cx.window_mut()
 945                        .next_frame
 946                        .element_states
 947                        .insert(key,
 948                            ElementStateBox {
 949                                inner: Box::new(Some(state.expect("you must return Some<State> when you pass some element id"))),
 950                                #[cfg(debug_assertions)]
 951                                type_name: std::any::type_name::<S>()
 952                            }
 953
 954                        );
 955                    result
 956                }
 957            }
 958        })
 959    }
 960
 961    /// Defers the drawing of the given element, scheduling it to be painted on top of the currently-drawn tree
 962    /// at a later time. The `priority` parameter determines the drawing order relative to other deferred elements,
 963    /// with higher values being drawn on top.
 964    pub fn defer_draw(
 965        &mut self,
 966        element: AnyElement,
 967        absolute_offset: Point<Pixels>,
 968        priority: usize,
 969    ) {
 970        let window = &mut self.cx.window;
 971        assert_eq!(
 972            window.draw_phase,
 973            DrawPhase::Layout,
 974            "defer_draw can only be called during before_layout or after_layout"
 975        );
 976        let parent_node = window.next_frame.dispatch_tree.active_node_id().unwrap();
 977        window.next_frame.deferred_draws.push(DeferredDraw {
 978            parent_node,
 979            element_id_stack: window.element_id_stack.clone(),
 980            text_style_stack: window.text_style_stack.clone(),
 981            priority,
 982            element: Some(element),
 983            absolute_offset,
 984            layout_range: AfterLayoutIndex::default()..AfterLayoutIndex::default(),
 985            paint_range: PaintIndex::default()..PaintIndex::default(),
 986        });
 987    }
 988
 989    /// Creates a new painting layer for the specified bounds. A "layer" is a batch
 990    /// of geometry that are non-overlapping and have the same draw order. This is typically used
 991    /// for performance reasons.
 992    pub fn paint_layer<R>(&mut self, bounds: Bounds<Pixels>, f: impl FnOnce(&mut Self) -> R) -> R {
 993        let scale_factor = self.scale_factor();
 994        let content_mask = self.content_mask();
 995        let clipped_bounds = bounds.intersect(&content_mask.bounds);
 996        if !clipped_bounds.is_empty() {
 997            self.window
 998                .next_frame
 999                .scene
1000                .push_layer(clipped_bounds.scale(scale_factor));
1001        }
1002
1003        let result = f(self);
1004
1005        if !clipped_bounds.is_empty() {
1006            self.window.next_frame.scene.pop_layer();
1007        }
1008
1009        result
1010    }
1011
1012    /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
1013    pub fn paint_shadows(
1014        &mut self,
1015        bounds: Bounds<Pixels>,
1016        corner_radii: Corners<Pixels>,
1017        shadows: &[BoxShadow],
1018    ) {
1019        let scale_factor = self.scale_factor();
1020        let content_mask = self.content_mask();
1021        for shadow in shadows {
1022            let mut shadow_bounds = bounds;
1023            shadow_bounds.origin += shadow.offset;
1024            shadow_bounds.dilate(shadow.spread_radius);
1025            self.window.next_frame.scene.insert_primitive(Shadow {
1026                order: 0,
1027                blur_radius: shadow.blur_radius.scale(scale_factor),
1028                bounds: shadow_bounds.scale(scale_factor),
1029                content_mask: content_mask.scale(scale_factor),
1030                corner_radii: corner_radii.scale(scale_factor),
1031                color: shadow.color,
1032            });
1033        }
1034    }
1035
1036    /// Paint one or more quads into the scene for the next frame at the current stacking context.
1037    /// Quads are colored rectangular regions with an optional background, border, and corner radius.
1038    /// see [`fill`](crate::fill), [`outline`](crate::outline), and [`quad`](crate::quad) to construct this type.
1039    pub fn paint_quad(&mut self, quad: PaintQuad) {
1040        let scale_factor = self.scale_factor();
1041        let content_mask = self.content_mask();
1042        self.window.next_frame.scene.insert_primitive(Quad {
1043            order: 0,
1044            pad: 0,
1045            bounds: quad.bounds.scale(scale_factor),
1046            content_mask: content_mask.scale(scale_factor),
1047            background: quad.background,
1048            border_color: quad.border_color,
1049            corner_radii: quad.corner_radii.scale(scale_factor),
1050            border_widths: quad.border_widths.scale(scale_factor),
1051        });
1052    }
1053
1054    /// Paint the given `Path` into the scene for the next frame at the current z-index.
1055    pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
1056        let scale_factor = self.scale_factor();
1057        let content_mask = self.content_mask();
1058        path.content_mask = content_mask;
1059        path.color = color.into();
1060        self.window
1061            .next_frame
1062            .scene
1063            .insert_primitive(path.scale(scale_factor));
1064    }
1065
1066    /// Paint an underline into the scene for the next frame at the current z-index.
1067    pub fn paint_underline(
1068        &mut self,
1069        origin: Point<Pixels>,
1070        width: Pixels,
1071        style: &UnderlineStyle,
1072    ) {
1073        let scale_factor = self.scale_factor();
1074        let height = if style.wavy {
1075            style.thickness * 3.
1076        } else {
1077            style.thickness
1078        };
1079        let bounds = Bounds {
1080            origin,
1081            size: size(width, height),
1082        };
1083        let content_mask = self.content_mask();
1084
1085        self.window.next_frame.scene.insert_primitive(Underline {
1086            order: 0,
1087            pad: 0,
1088            bounds: bounds.scale(scale_factor),
1089            content_mask: content_mask.scale(scale_factor),
1090            color: style.color.unwrap_or_default(),
1091            thickness: style.thickness.scale(scale_factor),
1092            wavy: style.wavy,
1093        });
1094    }
1095
1096    /// Paint a strikethrough into the scene for the next frame at the current z-index.
1097    pub fn paint_strikethrough(
1098        &mut self,
1099        origin: Point<Pixels>,
1100        width: Pixels,
1101        style: &StrikethroughStyle,
1102    ) {
1103        let scale_factor = self.scale_factor();
1104        let height = style.thickness;
1105        let bounds = Bounds {
1106            origin,
1107            size: size(width, height),
1108        };
1109        let content_mask = self.content_mask();
1110
1111        self.window.next_frame.scene.insert_primitive(Underline {
1112            order: 0,
1113            pad: 0,
1114            bounds: bounds.scale(scale_factor),
1115            content_mask: content_mask.scale(scale_factor),
1116            thickness: style.thickness.scale(scale_factor),
1117            color: style.color.unwrap_or_default(),
1118            wavy: false,
1119        });
1120    }
1121
1122    /// Paints a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
1123    ///
1124    /// The y component of the origin is the baseline of the glyph.
1125    /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
1126    /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
1127    /// This method is only useful if you need to paint a single glyph that has already been shaped.
1128    pub fn paint_glyph(
1129        &mut self,
1130        origin: Point<Pixels>,
1131        font_id: FontId,
1132        glyph_id: GlyphId,
1133        font_size: Pixels,
1134        color: Hsla,
1135    ) -> Result<()> {
1136        let scale_factor = self.scale_factor();
1137        let glyph_origin = origin.scale(scale_factor);
1138        let subpixel_variant = Point {
1139            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
1140            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
1141        };
1142        let params = RenderGlyphParams {
1143            font_id,
1144            glyph_id,
1145            font_size,
1146            subpixel_variant,
1147            scale_factor,
1148            is_emoji: false,
1149        };
1150
1151        let raster_bounds = self.text_system().raster_bounds(&params)?;
1152        if !raster_bounds.is_zero() {
1153            let tile =
1154                self.window
1155                    .sprite_atlas
1156                    .get_or_insert_with(&params.clone().into(), &mut || {
1157                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
1158                        Ok((size, Cow::Owned(bytes)))
1159                    })?;
1160            let bounds = Bounds {
1161                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
1162                size: tile.bounds.size.map(Into::into),
1163            };
1164            let content_mask = self.content_mask().scale(scale_factor);
1165            self.window
1166                .next_frame
1167                .scene
1168                .insert_primitive(MonochromeSprite {
1169                    order: 0,
1170                    pad: 0,
1171                    bounds,
1172                    content_mask,
1173                    color,
1174                    tile,
1175                    transformation: TransformationMatrix::unit(),
1176                });
1177        }
1178        Ok(())
1179    }
1180
1181    /// Paints an emoji glyph into the scene for the next frame at the current z-index.
1182    ///
1183    /// The y component of the origin is the baseline of the glyph.
1184    /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
1185    /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
1186    /// This method is only useful if you need to paint a single emoji that has already been shaped.
1187    pub fn paint_emoji(
1188        &mut self,
1189        origin: Point<Pixels>,
1190        font_id: FontId,
1191        glyph_id: GlyphId,
1192        font_size: Pixels,
1193    ) -> Result<()> {
1194        let scale_factor = self.scale_factor();
1195        let glyph_origin = origin.scale(scale_factor);
1196        let params = RenderGlyphParams {
1197            font_id,
1198            glyph_id,
1199            font_size,
1200            // We don't render emojis with subpixel variants.
1201            subpixel_variant: Default::default(),
1202            scale_factor,
1203            is_emoji: true,
1204        };
1205
1206        let raster_bounds = self.text_system().raster_bounds(&params)?;
1207        if !raster_bounds.is_zero() {
1208            let tile =
1209                self.window
1210                    .sprite_atlas
1211                    .get_or_insert_with(&params.clone().into(), &mut || {
1212                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
1213                        Ok((size, Cow::Owned(bytes)))
1214                    })?;
1215            let bounds = Bounds {
1216                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
1217                size: tile.bounds.size.map(Into::into),
1218            };
1219            let content_mask = self.content_mask().scale(scale_factor);
1220
1221            self.window
1222                .next_frame
1223                .scene
1224                .insert_primitive(PolychromeSprite {
1225                    order: 0,
1226                    grayscale: false,
1227                    bounds,
1228                    corner_radii: Default::default(),
1229                    content_mask,
1230                    tile,
1231                });
1232        }
1233        Ok(())
1234    }
1235
1236    /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
1237    pub fn paint_svg(
1238        &mut self,
1239        bounds: Bounds<Pixels>,
1240        path: SharedString,
1241        transformation: TransformationMatrix,
1242        color: Hsla,
1243    ) -> Result<()> {
1244        let scale_factor = self.scale_factor();
1245        let bounds = bounds.scale(scale_factor);
1246        // Render the SVG at twice the size to get a higher quality result.
1247        let params = RenderSvgParams {
1248            path,
1249            size: bounds
1250                .size
1251                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
1252        };
1253
1254        let tile =
1255            self.window
1256                .sprite_atlas
1257                .get_or_insert_with(&params.clone().into(), &mut || {
1258                    let bytes = self.svg_renderer.render(&params)?;
1259                    Ok((params.size, Cow::Owned(bytes)))
1260                })?;
1261        let content_mask = self.content_mask().scale(scale_factor);
1262
1263        self.window
1264            .next_frame
1265            .scene
1266            .insert_primitive(MonochromeSprite {
1267                order: 0,
1268                pad: 0,
1269                bounds,
1270                content_mask,
1271                color,
1272                tile,
1273                transformation,
1274            });
1275
1276        Ok(())
1277    }
1278
1279    /// Paint an image into the scene for the next frame at the current z-index.
1280    pub fn paint_image(
1281        &mut self,
1282        bounds: Bounds<Pixels>,
1283        corner_radii: Corners<Pixels>,
1284        data: Arc<ImageData>,
1285        grayscale: bool,
1286    ) -> Result<()> {
1287        let scale_factor = self.scale_factor();
1288        let bounds = bounds.scale(scale_factor);
1289        let params = RenderImageParams { image_id: data.id };
1290
1291        let tile = self
1292            .window
1293            .sprite_atlas
1294            .get_or_insert_with(&params.clone().into(), &mut || {
1295                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
1296            })?;
1297        let content_mask = self.content_mask().scale(scale_factor);
1298        let corner_radii = corner_radii.scale(scale_factor);
1299
1300        self.window
1301            .next_frame
1302            .scene
1303            .insert_primitive(PolychromeSprite {
1304                order: 0,
1305                grayscale,
1306                bounds,
1307                content_mask,
1308                corner_radii,
1309                tile,
1310            });
1311        Ok(())
1312    }
1313
1314    /// Paint a surface into the scene for the next frame at the current z-index.
1315    #[cfg(target_os = "macos")]
1316    pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
1317        let scale_factor = self.scale_factor();
1318        let bounds = bounds.scale(scale_factor);
1319        let content_mask = self.content_mask().scale(scale_factor);
1320        self.window
1321            .next_frame
1322            .scene
1323            .insert_primitive(crate::Surface {
1324                order: 0,
1325                bounds,
1326                content_mask,
1327                image_buffer,
1328            });
1329    }
1330
1331    #[must_use]
1332    /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
1333    /// layout is being requested, along with the layout ids of any children. This method is called during
1334    /// calls to the `Element::layout` trait method and enables any element to participate in layout.
1335    pub fn request_layout(
1336        &mut self,
1337        style: &Style,
1338        children: impl IntoIterator<Item = LayoutId>,
1339    ) -> LayoutId {
1340        self.app.layout_id_buffer.clear();
1341        self.app.layout_id_buffer.extend(children);
1342        let rem_size = self.rem_size();
1343
1344        self.cx
1345            .window
1346            .layout_engine
1347            .as_mut()
1348            .unwrap()
1349            .before_layout(style, rem_size, &self.cx.app.layout_id_buffer)
1350    }
1351
1352    /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
1353    /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
1354    /// determine the element's size. One place this is used internally is when measuring text.
1355    ///
1356    /// The given closure is invoked at layout time with the known dimensions and available space and
1357    /// returns a `Size`.
1358    pub fn request_measured_layout<
1359        F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
1360            + 'static,
1361    >(
1362        &mut self,
1363        style: Style,
1364        measure: F,
1365    ) -> LayoutId {
1366        let rem_size = self.rem_size();
1367        self.window
1368            .layout_engine
1369            .as_mut()
1370            .unwrap()
1371            .request_measured_layout(style, rem_size, measure)
1372    }
1373
1374    /// Compute the layout for the given id within the given available space.
1375    /// This method is called for its side effect, typically by the framework prior to painting.
1376    /// After calling it, you can request the bounds of the given layout node id or any descendant.
1377    pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
1378        let mut layout_engine = self.window.layout_engine.take().unwrap();
1379        layout_engine.compute_layout(layout_id, available_space, self);
1380        self.window.layout_engine = Some(layout_engine);
1381    }
1382
1383    /// Obtain the bounds computed for the given LayoutId relative to the window. This method will usually be invoked by
1384    /// GPUI itself automatically in order to pass your element its `Bounds` automatically.
1385    pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
1386        let mut bounds = self
1387            .window
1388            .layout_engine
1389            .as_mut()
1390            .unwrap()
1391            .layout_bounds(layout_id)
1392            .map(Into::into);
1393        bounds.origin += self.element_offset();
1394        bounds
1395    }
1396
1397    /// This method should be called during `after_layout`. You can use
1398    /// the returned [Hitbox] during `paint` or in an event handler
1399    /// to determine whether the inserted hitbox was the topmost.
1400    pub fn insert_hitbox(&mut self, bounds: Bounds<Pixels>, opaque: bool) -> Hitbox {
1401        let content_mask = self.content_mask();
1402        let window = &mut self.window;
1403        let id = window.next_hitbox_id;
1404        window.next_hitbox_id.0 += 1;
1405        let hitbox = Hitbox {
1406            id,
1407            bounds: bounds.intersect(&content_mask.bounds),
1408            opaque,
1409        };
1410        window.next_frame.hitboxes.push(hitbox.clone());
1411        hitbox
1412    }
1413
1414    /// Sets the key context for the current element. This context will be used to translate
1415    /// keybindings into actions.
1416    pub fn set_key_context(&mut self, context: KeyContext) {
1417        self.window
1418            .next_frame
1419            .dispatch_tree
1420            .set_key_context(context);
1421    }
1422
1423    /// Sets the focus handle for the current element. This handle will be used to manage focus state
1424    /// and keyboard event dispatch for the element.
1425    pub fn set_focus_handle(&mut self, focus_handle: &FocusHandle) {
1426        self.window
1427            .next_frame
1428            .dispatch_tree
1429            .set_focus_id(focus_handle.id);
1430    }
1431
1432    /// Sets the view id for the current element, which will be used to manage view caching.
1433    pub fn set_view_id(&mut self, view_id: EntityId) {
1434        self.window.next_frame.dispatch_tree.set_view_id(view_id);
1435    }
1436
1437    /// Get the last view id for the current element
1438    pub fn parent_view_id(&mut self) -> Option<EntityId> {
1439        self.window.next_frame.dispatch_tree.parent_view_id()
1440    }
1441
1442    /// Sets an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
1443    /// platform to receive textual input with proper integration with concerns such
1444    /// as IME interactions. This handler will be active for the upcoming frame until the following frame is
1445    /// rendered.
1446    ///
1447    /// [element_input_handler]: crate::ElementInputHandler
1448    pub fn handle_input(&mut self, focus_handle: &FocusHandle, input_handler: impl InputHandler) {
1449        if focus_handle.is_focused(self) {
1450            let cx = self.to_async();
1451            self.window
1452                .next_frame
1453                .input_handlers
1454                .push(Some(PlatformInputHandler::new(cx, Box::new(input_handler))));
1455        }
1456    }
1457
1458    /// Register a mouse event listener on the window for the next frame. The type of event
1459    /// is determined by the first parameter of the given listener. When the next frame is rendered
1460    /// the listener will be cleared.
1461    pub fn on_mouse_event<Event: MouseEvent>(
1462        &mut self,
1463        mut handler: impl FnMut(&Event, DispatchPhase, &mut ElementContext) + 'static,
1464    ) {
1465        self.window.next_frame.mouse_listeners.push(Some(Box::new(
1466            move |event: &dyn Any, phase: DispatchPhase, cx: &mut ElementContext<'_>| {
1467                if let Some(event) = event.downcast_ref() {
1468                    handler(event, phase, cx)
1469                }
1470            },
1471        )));
1472    }
1473
1474    /// Register a key event listener on the window for the next frame. The type of event
1475    /// is determined by the first parameter of the given listener. When the next frame is rendered
1476    /// the listener will be cleared.
1477    ///
1478    /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
1479    /// a specific need to register a global listener.
1480    pub fn on_key_event<Event: KeyEvent>(
1481        &mut self,
1482        listener: impl Fn(&Event, DispatchPhase, &mut ElementContext) + 'static,
1483    ) {
1484        self.window.next_frame.dispatch_tree.on_key_event(Rc::new(
1485            move |event: &dyn Any, phase, cx: &mut ElementContext<'_>| {
1486                if let Some(event) = event.downcast_ref::<Event>() {
1487                    listener(event, phase, cx)
1488                }
1489            },
1490        ));
1491    }
1492
1493    /// Register a modifiers changed event listener on the window for the next frame.
1494    ///
1495    /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
1496    /// a specific need to register a global listener.
1497    pub fn on_modifiers_changed(
1498        &mut self,
1499        listener: impl Fn(&ModifiersChangedEvent, &mut ElementContext) + 'static,
1500    ) {
1501        self.window
1502            .next_frame
1503            .dispatch_tree
1504            .on_modifiers_changed(Rc::new(
1505                move |event: &ModifiersChangedEvent, cx: &mut ElementContext<'_>| {
1506                    listener(event, cx)
1507                },
1508            ));
1509    }
1510}