element_cx.rs

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