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