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