window.rs

   1use crate::{
   2    image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext,
   3    AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId,
   4    Edges, Effect, Element, EntityId, Event, FontId, GlyphId, Handle, Hsla, ImageData, IsZero,
   5    LayoutId, MainThread, MainThreadOnly, MonochromeSprite, Path, Pixels, PlatformAtlas,
   6    PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderSvgParams,
   7    ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, TaffyLayoutEngine, Task,
   8    Underline, UnderlineStyle, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
   9};
  10use anyhow::Result;
  11use collections::HashMap;
  12use derive_more::{Deref, DerefMut};
  13use smallvec::SmallVec;
  14use std::{
  15    any::{Any, TypeId},
  16    borrow::Cow,
  17    fmt::Debug,
  18    future::Future,
  19    marker::PhantomData,
  20    mem,
  21    sync::Arc,
  22};
  23use util::ResultExt;
  24
  25#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default)]
  26pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
  27
  28#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
  29pub enum DispatchPhase {
  30    /// After the capture phase comes the bubble phase, in which event handlers are
  31    /// invoked front to back. This is the phase you'll usually want to use for event handlers.
  32    #[default]
  33    Bubble,
  34    /// During the initial capture phase, event handlers are invoked back to front. This phase
  35    /// is used for special purposes such as clearing the "pressed" state for click events. If
  36    /// you stop event propagation during this phase, you need to know what you're doing. Handlers
  37    /// outside of the immediate region may rely on detecting non-local events during this phase.
  38    Capture,
  39}
  40
  41type MouseEventHandler =
  42    Arc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
  43
  44pub struct Window {
  45    handle: AnyWindowHandle,
  46    platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
  47    pub(crate) display_id: DisplayId, // todo!("make private again?")
  48    sprite_atlas: Arc<dyn PlatformAtlas>,
  49    rem_size: Pixels,
  50    content_size: Size<Pixels>,
  51    layout_engine: TaffyLayoutEngine,
  52    pub(crate) root_view: Option<AnyView<()>>,
  53    current_stacking_order: StackingOrder,
  54    content_mask_stack: Vec<ContentMask<Pixels>>,
  55    mouse_event_handlers: HashMap<TypeId, Vec<(StackingOrder, MouseEventHandler)>>,
  56    propagate_event: bool,
  57    mouse_position: Point<Pixels>,
  58    scale_factor: f32,
  59    pub(crate) scene_builder: SceneBuilder,
  60    pub(crate) dirty: bool,
  61}
  62
  63impl Window {
  64    pub fn new(
  65        handle: AnyWindowHandle,
  66        options: WindowOptions,
  67        cx: &mut MainThread<AppContext>,
  68    ) -> Self {
  69        let platform_window = cx.platform().open_window(handle, options);
  70        let display_id = platform_window.display().id();
  71        let sprite_atlas = platform_window.sprite_atlas();
  72        let mouse_position = platform_window.mouse_position();
  73        let content_size = platform_window.content_size();
  74        let scale_factor = platform_window.scale_factor();
  75        platform_window.on_resize(Box::new({
  76            let cx = cx.to_async();
  77            move |content_size, scale_factor| {
  78                cx.update_window(handle, |cx| {
  79                    cx.window.scale_factor = scale_factor;
  80                    cx.window.scene_builder = SceneBuilder::new();
  81                    cx.window.content_size = content_size;
  82                    cx.window.display_id = cx
  83                        .window
  84                        .platform_window
  85                        .borrow_on_main_thread()
  86                        .display()
  87                        .id();
  88                    cx.window.dirty = true;
  89                })
  90                .log_err();
  91            }
  92        }));
  93
  94        platform_window.on_event({
  95            let cx = cx.to_async();
  96            Box::new(move |event| {
  97                cx.update_window(handle, |cx| cx.dispatch_event(event))
  98                    .log_err()
  99                    .unwrap_or(true)
 100            })
 101        });
 102
 103        let platform_window = MainThreadOnly::new(Arc::new(platform_window), cx.executor.clone());
 104
 105        Window {
 106            handle,
 107            platform_window,
 108            display_id,
 109            sprite_atlas,
 110            rem_size: px(16.),
 111            content_size,
 112            layout_engine: TaffyLayoutEngine::new(),
 113            root_view: None,
 114            current_stacking_order: StackingOrder(SmallVec::new()),
 115            content_mask_stack: Vec::new(),
 116            mouse_event_handlers: HashMap::default(),
 117            propagate_event: true,
 118            mouse_position,
 119            scale_factor,
 120            scene_builder: SceneBuilder::new(),
 121            dirty: true,
 122        }
 123    }
 124}
 125
 126#[derive(Clone, Debug, Default, PartialEq, Eq)]
 127#[repr(C)]
 128pub struct ContentMask<P: Clone + Debug> {
 129    pub bounds: Bounds<P>,
 130}
 131
 132impl ContentMask<Pixels> {
 133    pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
 134        ContentMask {
 135            bounds: self.bounds.scale(factor),
 136        }
 137    }
 138
 139    pub fn intersect(&self, other: &Self) -> Self {
 140        let bounds = self.bounds.intersect(&other.bounds);
 141        ContentMask { bounds }
 142    }
 143}
 144
 145pub struct WindowContext<'a, 'w> {
 146    app: Reference<'a, AppContext>,
 147    window: Reference<'w, Window>,
 148}
 149
 150impl<'a, 'w> WindowContext<'a, 'w> {
 151    pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self {
 152        Self {
 153            app: Reference::Mutable(app),
 154            window: Reference::Mutable(window),
 155        }
 156    }
 157
 158    pub fn notify(&mut self) {
 159        self.window.dirty = true;
 160    }
 161
 162    pub fn run_on_main<R>(
 163        &mut self,
 164        f: impl FnOnce(&mut MainThread<WindowContext<'_, '_>>) -> R + Send + 'static,
 165    ) -> Task<Result<R>>
 166    where
 167        R: Send + 'static,
 168    {
 169        if self.executor.is_main_thread() {
 170            Task::ready(Ok(f(unsafe {
 171                mem::transmute::<&mut Self, &mut MainThread<Self>>(self)
 172            })))
 173        } else {
 174            let id = self.window.handle.id;
 175            self.app.run_on_main(move |cx| cx.update_window(id, f))
 176        }
 177    }
 178
 179    pub fn to_async(&self) -> AsyncWindowContext {
 180        AsyncWindowContext::new(self.app.to_async(), self.window.handle)
 181    }
 182
 183    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
 184        let f = Box::new(f);
 185        let display_id = self.window.display_id;
 186        let async_cx = self.to_async();
 187        let app_cx = self.app_mut();
 188        match app_cx.next_frame_callbacks.entry(display_id) {
 189            collections::hash_map::Entry::Occupied(mut entry) => {
 190                if entry.get().is_empty() {
 191                    app_cx.display_linker.start(display_id);
 192                }
 193                entry.get_mut().push(f);
 194            }
 195            collections::hash_map::Entry::Vacant(entry) => {
 196                app_cx.display_linker.set_output_callback(
 197                    display_id,
 198                    Box::new(move |_current_time, _output_time| {
 199                        let _ = async_cx.update(|cx| {
 200                            let callbacks = cx
 201                                .next_frame_callbacks
 202                                .get_mut(&display_id)
 203                                .unwrap()
 204                                .drain(..)
 205                                .collect::<Vec<_>>();
 206                            for callback in callbacks {
 207                                callback(cx);
 208                            }
 209
 210                            if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
 211                                cx.display_linker.stop(display_id);
 212                            }
 213                        });
 214                    }),
 215                );
 216                app_cx.display_linker.start(display_id);
 217                entry.insert(vec![f]);
 218            }
 219        }
 220    }
 221
 222    pub fn spawn<Fut, R>(
 223        &mut self,
 224        f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static,
 225    ) -> Task<R>
 226    where
 227        R: Send + 'static,
 228        Fut: Future<Output = R> + Send + 'static,
 229    {
 230        let window = self.window.handle;
 231        self.app.spawn(move |app| {
 232            let cx = AsyncWindowContext::new(app, window);
 233            let future = f(window, cx);
 234            async move { future.await }
 235        })
 236    }
 237
 238    pub fn request_layout(
 239        &mut self,
 240        style: Style,
 241        children: impl IntoIterator<Item = LayoutId>,
 242    ) -> Result<LayoutId> {
 243        self.app.layout_id_buffer.clear();
 244        self.app.layout_id_buffer.extend(children.into_iter());
 245        let rem_size = self.rem_size();
 246
 247        self.window
 248            .layout_engine
 249            .request_layout(style, rem_size, &self.app.layout_id_buffer)
 250    }
 251
 252    pub fn request_measured_layout<
 253        F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync + 'static,
 254    >(
 255        &mut self,
 256        style: Style,
 257        rem_size: Pixels,
 258        measure: F,
 259    ) -> Result<LayoutId> {
 260        self.window
 261            .layout_engine
 262            .request_measured_layout(style, rem_size, measure)
 263    }
 264
 265    pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Result<Bounds<Pixels>> {
 266        Ok(self
 267            .window
 268            .layout_engine
 269            .layout_bounds(layout_id)
 270            .map(Into::into)?)
 271    }
 272
 273    pub fn scale_factor(&self) -> f32 {
 274        self.window.scale_factor
 275    }
 276
 277    pub fn rem_size(&self) -> Pixels {
 278        self.window.rem_size
 279    }
 280
 281    pub fn stop_propagation(&mut self) {
 282        self.window.propagate_event = false;
 283    }
 284
 285    pub fn on_mouse_event<Event: 'static>(
 286        &mut self,
 287        handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + Sync + 'static,
 288    ) {
 289        let order = self.window.current_stacking_order.clone();
 290        self.window
 291            .mouse_event_handlers
 292            .entry(TypeId::of::<Event>())
 293            .or_default()
 294            .push((
 295                order,
 296                Arc::new(move |event: &dyn Any, phase, cx| {
 297                    handler(event.downcast_ref().unwrap(), phase, cx)
 298                }),
 299            ))
 300    }
 301
 302    pub fn mouse_position(&self) -> Point<Pixels> {
 303        self.window.mouse_position
 304    }
 305
 306    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
 307        self.window.current_stacking_order.push(order);
 308        let result = f(self);
 309        self.window.current_stacking_order.pop();
 310        result
 311    }
 312
 313    pub fn paint_shadows(
 314        &mut self,
 315        bounds: Bounds<Pixels>,
 316        corner_radii: Corners<Pixels>,
 317        shadows: &[BoxShadow],
 318    ) {
 319        let scale_factor = self.scale_factor();
 320        let content_mask = self.content_mask();
 321        let window = &mut *self.window;
 322        for shadow in shadows {
 323            let mut shadow_bounds = bounds;
 324            shadow_bounds.origin += shadow.offset;
 325            shadow_bounds.dilate(shadow.spread_radius);
 326            window.scene_builder.insert(
 327                &window.current_stacking_order,
 328                Shadow {
 329                    order: 0,
 330                    bounds: shadow_bounds.scale(scale_factor),
 331                    content_mask: content_mask.scale(scale_factor),
 332                    corner_radii: corner_radii.scale(scale_factor),
 333                    color: shadow.color,
 334                    blur_radius: shadow.blur_radius.scale(scale_factor),
 335                },
 336            );
 337        }
 338    }
 339
 340    pub fn paint_quad(
 341        &mut self,
 342        bounds: Bounds<Pixels>,
 343        corner_radii: Corners<Pixels>,
 344        background: impl Into<Hsla>,
 345        border_widths: Edges<Pixels>,
 346        border_color: impl Into<Hsla>,
 347    ) {
 348        let scale_factor = self.scale_factor();
 349        let content_mask = self.content_mask();
 350
 351        let window = &mut *self.window;
 352        window.scene_builder.insert(
 353            &window.current_stacking_order,
 354            Quad {
 355                order: 0,
 356                bounds: bounds.scale(scale_factor),
 357                content_mask: content_mask.scale(scale_factor),
 358                background: background.into(),
 359                border_color: border_color.into(),
 360                corner_radii: corner_radii.scale(scale_factor),
 361                border_widths: border_widths.scale(scale_factor),
 362            },
 363        );
 364    }
 365
 366    pub fn paint_path(&mut self, mut path: Path<Pixels>) {
 367        let scale_factor = self.scale_factor();
 368        let content_mask = self.content_mask();
 369        for vertex in &mut path.vertices {
 370            vertex.content_mask = content_mask.clone();
 371        }
 372        let window = &mut *self.window;
 373        window
 374            .scene_builder
 375            .insert(&window.current_stacking_order, path.scale(scale_factor));
 376    }
 377
 378    pub fn paint_underline(
 379        &mut self,
 380        origin: Point<Pixels>,
 381        width: Pixels,
 382        style: &UnderlineStyle,
 383    ) -> Result<()> {
 384        let scale_factor = self.scale_factor();
 385        let height = if style.wavy {
 386            style.thickness * 3.
 387        } else {
 388            style.thickness
 389        };
 390        let bounds = Bounds {
 391            origin,
 392            size: size(width, height),
 393        };
 394        let content_mask = self.content_mask();
 395        let window = &mut *self.window;
 396        window.scene_builder.insert(
 397            &window.current_stacking_order,
 398            Underline {
 399                order: 0,
 400                bounds: bounds.scale(scale_factor),
 401                content_mask: content_mask.scale(scale_factor),
 402                thickness: style.thickness.scale(scale_factor),
 403                color: style.color.unwrap_or_default(),
 404                wavy: style.wavy,
 405            },
 406        );
 407        Ok(())
 408    }
 409
 410    pub fn paint_glyph(
 411        &mut self,
 412        origin: Point<Pixels>,
 413        font_id: FontId,
 414        glyph_id: GlyphId,
 415        font_size: Pixels,
 416        color: Hsla,
 417    ) -> Result<()> {
 418        let scale_factor = self.scale_factor();
 419        let glyph_origin = origin.scale(scale_factor);
 420        let subpixel_variant = Point {
 421            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 422            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 423        };
 424        let params = RenderGlyphParams {
 425            font_id,
 426            glyph_id,
 427            font_size,
 428            subpixel_variant,
 429            scale_factor,
 430            is_emoji: false,
 431        };
 432
 433        let raster_bounds = self.text_system().raster_bounds(&params)?;
 434        if !raster_bounds.is_zero() {
 435            let tile =
 436                self.window
 437                    .sprite_atlas
 438                    .get_or_insert_with(&params.clone().into(), &mut || {
 439                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 440                        Ok((size, Cow::Owned(bytes)))
 441                    })?;
 442            let bounds = Bounds {
 443                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 444                size: tile.bounds.size.map(Into::into),
 445            };
 446            let content_mask = self.content_mask().scale(scale_factor);
 447            let window = &mut *self.window;
 448            window.scene_builder.insert(
 449                &window.current_stacking_order,
 450                MonochromeSprite {
 451                    order: 0,
 452                    bounds,
 453                    content_mask,
 454                    color,
 455                    tile,
 456                },
 457            );
 458        }
 459        Ok(())
 460    }
 461
 462    pub fn paint_emoji(
 463        &mut self,
 464        origin: Point<Pixels>,
 465        font_id: FontId,
 466        glyph_id: GlyphId,
 467        font_size: Pixels,
 468    ) -> Result<()> {
 469        let scale_factor = self.scale_factor();
 470        let glyph_origin = origin.scale(scale_factor);
 471        let params = RenderGlyphParams {
 472            font_id,
 473            glyph_id,
 474            font_size,
 475            // We don't render emojis with subpixel variants.
 476            subpixel_variant: Default::default(),
 477            scale_factor,
 478            is_emoji: true,
 479        };
 480
 481        let raster_bounds = self.text_system().raster_bounds(&params)?;
 482        if !raster_bounds.is_zero() {
 483            let tile =
 484                self.window
 485                    .sprite_atlas
 486                    .get_or_insert_with(&params.clone().into(), &mut || {
 487                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 488                        Ok((size, Cow::Owned(bytes)))
 489                    })?;
 490            let bounds = Bounds {
 491                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 492                size: tile.bounds.size.map(Into::into),
 493            };
 494            let content_mask = self.content_mask().scale(scale_factor);
 495            let window = &mut *self.window;
 496
 497            window.scene_builder.insert(
 498                &window.current_stacking_order,
 499                PolychromeSprite {
 500                    order: 0,
 501                    bounds,
 502                    corner_radii: Default::default(),
 503                    content_mask,
 504                    tile,
 505                    grayscale: false,
 506                },
 507            );
 508        }
 509        Ok(())
 510    }
 511
 512    pub fn paint_svg(
 513        &mut self,
 514        bounds: Bounds<Pixels>,
 515        path: SharedString,
 516        color: Hsla,
 517    ) -> Result<()> {
 518        let scale_factor = self.scale_factor();
 519        let bounds = bounds.scale(scale_factor);
 520        // Render the SVG at twice the size to get a higher quality result.
 521        let params = RenderSvgParams {
 522            path,
 523            size: bounds
 524                .size
 525                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
 526        };
 527
 528        let tile =
 529            self.window
 530                .sprite_atlas
 531                .get_or_insert_with(&params.clone().into(), &mut || {
 532                    let bytes = self.svg_renderer.render(&params)?;
 533                    Ok((params.size, Cow::Owned(bytes)))
 534                })?;
 535        let content_mask = self.content_mask().scale(scale_factor);
 536
 537        let window = &mut *self.window;
 538        window.scene_builder.insert(
 539            &window.current_stacking_order,
 540            MonochromeSprite {
 541                order: 0,
 542                bounds,
 543                content_mask,
 544                color,
 545                tile,
 546            },
 547        );
 548
 549        Ok(())
 550    }
 551
 552    pub fn paint_image(
 553        &mut self,
 554        bounds: Bounds<Pixels>,
 555        corner_radii: Corners<Pixels>,
 556        data: Arc<ImageData>,
 557        grayscale: bool,
 558    ) -> Result<()> {
 559        let scale_factor = self.scale_factor();
 560        let bounds = bounds.scale(scale_factor);
 561        let params = RenderImageParams { image_id: data.id };
 562
 563        let tile = self
 564            .window
 565            .sprite_atlas
 566            .get_or_insert_with(&params.clone().into(), &mut || {
 567                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
 568            })?;
 569        let content_mask = self.content_mask().scale(scale_factor);
 570        let corner_radii = corner_radii.scale(scale_factor);
 571
 572        let window = &mut *self.window;
 573        window.scene_builder.insert(
 574            &window.current_stacking_order,
 575            PolychromeSprite {
 576                order: 0,
 577                bounds,
 578                content_mask,
 579                corner_radii,
 580                tile,
 581                grayscale,
 582            },
 583        );
 584        Ok(())
 585    }
 586
 587    pub(crate) fn draw(&mut self) -> Result<()> {
 588        let unit_entity = self.unit_entity.clone();
 589        self.update_entity(&unit_entity, |view, cx| {
 590            cx.window
 591                .mouse_event_handlers
 592                .values_mut()
 593                .for_each(Vec::clear);
 594
 595            let mut root_view = cx.window.root_view.take().unwrap();
 596            let (root_layout_id, mut frame_state) = root_view.layout(&mut (), cx)?;
 597            let available_space = cx.window.content_size.map(Into::into);
 598
 599            cx.window
 600                .layout_engine
 601                .compute_layout(root_layout_id, available_space)?;
 602            let layout = cx.window.layout_engine.layout_bounds(root_layout_id)?;
 603
 604            root_view.paint(layout, &mut (), &mut frame_state, cx)?;
 605            cx.window.root_view = Some(root_view);
 606            let scene = cx.window.scene_builder.build();
 607
 608            cx.run_on_main(view, |_, cx| {
 609                cx.window
 610                    .platform_window
 611                    .borrow_on_main_thread()
 612                    .draw(scene);
 613                cx.window.dirty = false;
 614            })
 615            .detach();
 616
 617            Ok(())
 618        })
 619    }
 620
 621    fn dispatch_event(&mut self, event: Event) -> bool {
 622        if let Some(any_mouse_event) = event.mouse_event() {
 623            if let Some(mut handlers) = self
 624                .window
 625                .mouse_event_handlers
 626                .remove(&any_mouse_event.type_id())
 627            {
 628                // Because handlers may add other handlers, we sort every time.
 629                handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
 630
 631                // Handlers may set this to false by calling `stop_propagation`
 632                self.window.propagate_event = true;
 633
 634                // Capture phase, events bubble from back to front. Handlers for this phase are used for
 635                // special purposes, such as detecting events outside of a given Bounds.
 636                for (_, handler) in &handlers {
 637                    handler(any_mouse_event, DispatchPhase::Capture, self);
 638                    if !self.window.propagate_event {
 639                        break;
 640                    }
 641                }
 642
 643                // Bubble phase, where most normal handlers do their work.
 644                if self.window.propagate_event {
 645                    for (_, handler) in handlers.iter().rev() {
 646                        handler(any_mouse_event, DispatchPhase::Bubble, self);
 647                        if !self.window.propagate_event {
 648                            break;
 649                        }
 650                    }
 651                }
 652
 653                // Just in case any handlers added new handlers, which is weird, but possible.
 654                handlers.extend(
 655                    self.window
 656                        .mouse_event_handlers
 657                        .get_mut(&any_mouse_event.type_id())
 658                        .into_iter()
 659                        .flat_map(|handlers| handlers.drain(..)),
 660                );
 661                self.window
 662                    .mouse_event_handlers
 663                    .insert(any_mouse_event.type_id(), handlers);
 664            }
 665        }
 666
 667        true
 668    }
 669}
 670
 671impl Context for WindowContext<'_, '_> {
 672    type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
 673    type Result<T> = T;
 674
 675    fn entity<T: Send + Sync + 'static>(
 676        &mut self,
 677        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 678    ) -> Handle<T> {
 679        let slot = self.app.entities.reserve();
 680        let entity = build_entity(&mut ViewContext::mutable(
 681            &mut *self.app,
 682            &mut self.window,
 683            slot.id,
 684        ));
 685        self.entities.insert(slot, entity)
 686    }
 687
 688    fn update_entity<T: Send + Sync + 'static, R>(
 689        &mut self,
 690        handle: &Handle<T>,
 691        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 692    ) -> R {
 693        let mut entity = self.entities.lease(handle);
 694        let result = update(
 695            &mut *entity,
 696            &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id),
 697        );
 698        self.entities.end_lease(entity);
 699        result
 700    }
 701}
 702
 703impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
 704    type Target = AppContext;
 705
 706    fn deref(&self) -> &Self::Target {
 707        &self.app
 708    }
 709}
 710
 711impl<'a, 'w> std::ops::DerefMut for WindowContext<'a, 'w> {
 712    fn deref_mut(&mut self) -> &mut Self::Target {
 713        &mut self.app
 714    }
 715}
 716
 717impl BorrowAppContext for WindowContext<'_, '_> {
 718    fn app_mut(&mut self) -> &mut AppContext {
 719        &mut *self.app
 720    }
 721}
 722
 723pub trait BorrowWindow: BorrowAppContext {
 724    fn window(&self) -> &Window;
 725    fn window_mut(&mut self) -> &mut Window;
 726
 727    fn with_content_mask<R>(
 728        &mut self,
 729        mask: ContentMask<Pixels>,
 730        f: impl FnOnce(&mut Self) -> R,
 731    ) -> R {
 732        let mask = mask.intersect(&self.content_mask());
 733        self.window_mut().content_mask_stack.push(mask);
 734        let result = f(self);
 735        self.window_mut().content_mask_stack.pop();
 736        result
 737    }
 738
 739    fn content_mask(&self) -> ContentMask<Pixels> {
 740        self.window()
 741            .content_mask_stack
 742            .last()
 743            .cloned()
 744            .unwrap_or_else(|| ContentMask {
 745                bounds: Bounds {
 746                    origin: Point::default(),
 747                    size: self.window().content_size,
 748                },
 749            })
 750    }
 751
 752    fn rem_size(&self) -> Pixels {
 753        self.window().rem_size
 754    }
 755}
 756
 757impl BorrowWindow for WindowContext<'_, '_> {
 758    fn window(&self) -> &Window {
 759        &*self.window
 760    }
 761
 762    fn window_mut(&mut self) -> &mut Window {
 763        &mut *self.window
 764    }
 765}
 766
 767pub struct ViewContext<'a, 'w, S> {
 768    window_cx: WindowContext<'a, 'w>,
 769    entity_type: PhantomData<S>,
 770    entity_id: EntityId,
 771}
 772
 773impl<S> BorrowAppContext for ViewContext<'_, '_, S> {
 774    fn app_mut(&mut self) -> &mut AppContext {
 775        &mut *self.window_cx.app
 776    }
 777
 778    fn with_text_style<F, R>(&mut self, style: crate::TextStyleRefinement, f: F) -> R
 779    where
 780        F: FnOnce(&mut Self) -> R,
 781    {
 782        self.window_cx.app.push_text_style(style);
 783        let result = f(self);
 784        self.window_cx.app.pop_text_style();
 785        result
 786    }
 787
 788    fn with_state<T: Send + Sync + 'static, F, R>(&mut self, state: T, f: F) -> R
 789    where
 790        F: FnOnce(&mut Self) -> R,
 791    {
 792        self.window_cx.app.push_state(state);
 793        let result = f(self);
 794        self.window_cx.app.pop_state::<T>();
 795        result
 796    }
 797}
 798
 799impl<S> BorrowWindow for ViewContext<'_, '_, S> {
 800    fn window(&self) -> &Window {
 801        &self.window_cx.window
 802    }
 803
 804    fn window_mut(&mut self) -> &mut Window {
 805        &mut *self.window_cx.window
 806    }
 807}
 808
 809impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
 810    fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
 811        Self {
 812            window_cx: WindowContext::mutable(app, window),
 813            entity_id,
 814            entity_type: PhantomData,
 815        }
 816    }
 817
 818    pub fn handle(&self) -> WeakHandle<S> {
 819        self.entities.weak_handle(self.entity_id)
 820    }
 821
 822    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
 823        self.window.current_stacking_order.push(order);
 824        let result = f(self);
 825        self.window.current_stacking_order.pop();
 826        result
 827    }
 828
 829    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut S, &mut ViewContext<S>) + Send + 'static) {
 830        let entity = self.handle();
 831        self.window_cx.on_next_frame(move |cx| {
 832            entity.update(cx, f).ok();
 833        });
 834    }
 835
 836    pub fn observe<E: Send + Sync + 'static>(
 837        &mut self,
 838        handle: &Handle<E>,
 839        on_notify: impl Fn(&mut S, Handle<E>, &mut ViewContext<'_, '_, S>) + Send + Sync + 'static,
 840    ) {
 841        let this = self.handle();
 842        let handle = handle.downgrade();
 843        let window_handle = self.window.handle;
 844        self.app
 845            .observers
 846            .entry(handle.id)
 847            .or_default()
 848            .push(Arc::new(move |cx| {
 849                cx.update_window(window_handle.id, |cx| {
 850                    if let Some(handle) = handle.upgrade(cx) {
 851                        this.update(cx, |this, cx| on_notify(this, handle, cx))
 852                            .is_ok()
 853                    } else {
 854                        false
 855                    }
 856                })
 857                .unwrap_or(false)
 858            }));
 859    }
 860
 861    pub fn notify(&mut self) {
 862        self.window_cx.notify();
 863        self.window_cx
 864            .app
 865            .pending_effects
 866            .push_back(Effect::Notify(self.entity_id));
 867    }
 868
 869    pub fn run_on_main<R>(
 870        &mut self,
 871        view: &mut S,
 872        f: impl FnOnce(&mut S, &mut MainThread<ViewContext<'_, '_, S>>) -> R + Send + 'static,
 873    ) -> Task<Result<R>>
 874    where
 875        R: Send + 'static,
 876    {
 877        if self.executor.is_main_thread() {
 878            let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
 879            Task::ready(Ok(f(view, cx)))
 880        } else {
 881            let handle = self.handle().upgrade(self).unwrap();
 882            self.window_cx.run_on_main(move |cx| handle.update(cx, f))
 883        }
 884    }
 885
 886    pub fn spawn<Fut, R>(
 887        &mut self,
 888        f: impl FnOnce(WeakHandle<S>, AsyncWindowContext) -> Fut + Send + 'static,
 889    ) -> Task<R>
 890    where
 891        R: Send + 'static,
 892        Fut: Future<Output = R> + Send + 'static,
 893    {
 894        let handle = self.handle();
 895        self.window_cx.spawn(move |_, cx| {
 896            let result = f(handle, cx);
 897            async move { result.await }
 898        })
 899    }
 900
 901    pub fn on_mouse_event<Event: 'static>(
 902        &mut self,
 903        handler: impl Fn(&mut S, &Event, DispatchPhase, &mut ViewContext<S>) + Send + Sync + 'static,
 904    ) {
 905        let handle = self.handle().upgrade(self).unwrap();
 906        self.window_cx.on_mouse_event(move |event, phase, cx| {
 907            handle.update(cx, |view, cx| {
 908                handler(view, event, phase, cx);
 909            })
 910        });
 911    }
 912
 913    pub(crate) fn erase_state<R>(&mut self, f: impl FnOnce(&mut ViewContext<()>) -> R) -> R {
 914        let entity_id = self.unit_entity.id;
 915        let mut cx = ViewContext::mutable(
 916            &mut *self.window_cx.app,
 917            &mut *self.window_cx.window,
 918            entity_id,
 919        );
 920        f(&mut cx)
 921    }
 922}
 923
 924impl<'a, 'w, S> Context for ViewContext<'a, 'w, S> {
 925    type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
 926    type Result<U> = U;
 927
 928    fn entity<T2: Send + Sync + 'static>(
 929        &mut self,
 930        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
 931    ) -> Handle<T2> {
 932        self.window_cx.entity(build_entity)
 933    }
 934
 935    fn update_entity<U: Send + Sync + 'static, R>(
 936        &mut self,
 937        handle: &Handle<U>,
 938        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
 939    ) -> R {
 940        self.window_cx.update_entity(handle, update)
 941    }
 942}
 943
 944impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
 945    type Target = WindowContext<'a, 'w>;
 946
 947    fn deref(&self) -> &Self::Target {
 948        &self.window_cx
 949    }
 950}
 951
 952impl<'a, 'w, S: 'static> std::ops::DerefMut for ViewContext<'a, 'w, S> {
 953    fn deref_mut(&mut self) -> &mut Self::Target {
 954        &mut self.window_cx
 955    }
 956}
 957
 958// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
 959slotmap::new_key_type! { pub struct WindowId; }
 960
 961#[derive(PartialEq, Eq)]
 962pub struct WindowHandle<S> {
 963    id: WindowId,
 964    state_type: PhantomData<S>,
 965}
 966
 967impl<S> Copy for WindowHandle<S> {}
 968
 969impl<S> Clone for WindowHandle<S> {
 970    fn clone(&self) -> Self {
 971        WindowHandle {
 972            id: self.id,
 973            state_type: PhantomData,
 974        }
 975    }
 976}
 977
 978impl<S> WindowHandle<S> {
 979    pub fn new(id: WindowId) -> Self {
 980        WindowHandle {
 981            id,
 982            state_type: PhantomData,
 983        }
 984    }
 985}
 986
 987impl<S: 'static> Into<AnyWindowHandle> for WindowHandle<S> {
 988    fn into(self) -> AnyWindowHandle {
 989        AnyWindowHandle {
 990            id: self.id,
 991            state_type: TypeId::of::<S>(),
 992        }
 993    }
 994}
 995
 996#[derive(Copy, Clone, PartialEq, Eq)]
 997pub struct AnyWindowHandle {
 998    pub(crate) id: WindowId,
 999    state_type: TypeId,
1000}
1001
1002#[cfg(any(test, feature = "test"))]
1003impl From<SmallVec<[u32; 16]>> for StackingOrder {
1004    fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
1005        StackingOrder(small_vec)
1006    }
1007}