Skip to main content

gpui/elements/
platform_view.rs

1use crate::{
2    App, Bounds, Element, ElementId, GlobalElementId, InspectorElementId, IntoElement, LayoutId,
3    Pixels, PlatformViewHandle, Style, StyleRefinement, Styled, Window,
4};
5use refineable::Refineable;
6
7/// An element that gives a natively hosted view a place in GPUI's layout.
8///
9/// See [`platform_view`].
10pub struct PlatformView {
11    handle: PlatformViewHandle,
12    style: StyleRefinement,
13}
14
15/// Hosts a native platform view — an `NSView` on macOS or a child `HWND` on
16/// Windows — inside the window, at the bounds this element is laid out at.
17///
18/// The element itself paints nothing. Size it the way you would size any other
19/// element; GPUI owns the native view's frame from then on and repositions it
20/// after every frame it is painted in. A frame that does not paint the element
21/// hides and detaches the view, so unmounting is just not rendering it.
22///
23/// # Stacking
24///
25/// The hosted view is ordered above GPUI's root scene. Content drawn on that
26/// same base surface does not composite over the native view. When the window's
27/// scene overlay is enabled, deferred and window-level overlay content is drawn
28/// on a separate surface above hosted views.
29///
30/// # Platforms
31///
32/// macOS and Windows host native views. Elsewhere the element still lays out,
33/// reserves space, and does not host a view.
34pub fn platform_view(handle: PlatformViewHandle) -> PlatformView {
35    PlatformView {
36        handle,
37        style: StyleRefinement::default(),
38    }
39}
40
41impl Element for PlatformView {
42    type RequestLayoutState = ();
43    type PrepaintState = ();
44
45    fn id(&self) -> Option<ElementId> {
46        None
47    }
48
49    fn source_location(&self) -> Option<&'static core::panic::Location<'static>> {
50        None
51    }
52
53    fn request_layout(
54        &mut self,
55        _global_id: Option<&GlobalElementId>,
56        _inspector_id: Option<&InspectorElementId>,
57        window: &mut Window,
58        cx: &mut App,
59    ) -> (LayoutId, Self::RequestLayoutState) {
60        let mut style = Style::default();
61        style.refine(&self.style);
62        let layout_id = window.request_layout(style, [], cx);
63        (layout_id, ())
64    }
65
66    fn prepaint(
67        &mut self,
68        _global_id: Option<&GlobalElementId>,
69        _inspector_id: Option<&InspectorElementId>,
70        _bounds: Bounds<Pixels>,
71        _request_layout: &mut Self::RequestLayoutState,
72        _window: &mut Window,
73        _cx: &mut App,
74    ) -> Self::PrepaintState {
75    }
76
77    fn paint(
78        &mut self,
79        _global_id: Option<&GlobalElementId>,
80        _inspector_id: Option<&InspectorElementId>,
81        bounds: Bounds<Pixels>,
82        _request_layout: &mut Self::RequestLayoutState,
83        _prepaint: &mut Self::PrepaintState,
84        window: &mut Window,
85        _cx: &mut App,
86    ) {
87        window.paint_platform_view(bounds, self.handle.clone());
88    }
89}
90
91impl IntoElement for PlatformView {
92    type Element = Self;
93
94    fn into_element(self) -> Self::Element {
95        self
96    }
97}
98
99impl Styled for PlatformView {
100    fn style(&mut self) -> &mut StyleRefinement {
101        &mut self.style
102    }
103}