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>, color: impl Into<Hsla>) {
 367        let scale_factor = self.scale_factor();
 368        let content_mask = self.content_mask();
 369        path.content_mask = content_mask;
 370        path.color = color.into();
 371        let window = &mut *self.window;
 372        window
 373            .scene_builder
 374            .insert(&window.current_stacking_order, path.scale(scale_factor));
 375    }
 376
 377    pub fn paint_underline(
 378        &mut self,
 379        origin: Point<Pixels>,
 380        width: Pixels,
 381        style: &UnderlineStyle,
 382    ) -> Result<()> {
 383        let scale_factor = self.scale_factor();
 384        let height = if style.wavy {
 385            style.thickness * 3.
 386        } else {
 387            style.thickness
 388        };
 389        let bounds = Bounds {
 390            origin,
 391            size: size(width, height),
 392        };
 393        let content_mask = self.content_mask();
 394        let window = &mut *self.window;
 395        window.scene_builder.insert(
 396            &window.current_stacking_order,
 397            Underline {
 398                order: 0,
 399                bounds: bounds.scale(scale_factor),
 400                content_mask: content_mask.scale(scale_factor),
 401                thickness: style.thickness.scale(scale_factor),
 402                color: style.color.unwrap_or_default(),
 403                wavy: style.wavy,
 404            },
 405        );
 406        Ok(())
 407    }
 408
 409    pub fn paint_glyph(
 410        &mut self,
 411        origin: Point<Pixels>,
 412        font_id: FontId,
 413        glyph_id: GlyphId,
 414        font_size: Pixels,
 415        color: Hsla,
 416    ) -> Result<()> {
 417        let scale_factor = self.scale_factor();
 418        let glyph_origin = origin.scale(scale_factor);
 419        let subpixel_variant = Point {
 420            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 421            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 422        };
 423        let params = RenderGlyphParams {
 424            font_id,
 425            glyph_id,
 426            font_size,
 427            subpixel_variant,
 428            scale_factor,
 429            is_emoji: false,
 430        };
 431
 432        let raster_bounds = self.text_system().raster_bounds(&params)?;
 433        if !raster_bounds.is_zero() {
 434            let tile =
 435                self.window
 436                    .sprite_atlas
 437                    .get_or_insert_with(&params.clone().into(), &mut || {
 438                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 439                        Ok((size, Cow::Owned(bytes)))
 440                    })?;
 441            let bounds = Bounds {
 442                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 443                size: tile.bounds.size.map(Into::into),
 444            };
 445            let content_mask = self.content_mask().scale(scale_factor);
 446            let window = &mut *self.window;
 447            window.scene_builder.insert(
 448                &window.current_stacking_order,
 449                MonochromeSprite {
 450                    order: 0,
 451                    bounds,
 452                    content_mask,
 453                    color,
 454                    tile,
 455                },
 456            );
 457        }
 458        Ok(())
 459    }
 460
 461    pub fn paint_emoji(
 462        &mut self,
 463        origin: Point<Pixels>,
 464        font_id: FontId,
 465        glyph_id: GlyphId,
 466        font_size: Pixels,
 467    ) -> Result<()> {
 468        let scale_factor = self.scale_factor();
 469        let glyph_origin = origin.scale(scale_factor);
 470        let params = RenderGlyphParams {
 471            font_id,
 472            glyph_id,
 473            font_size,
 474            // We don't render emojis with subpixel variants.
 475            subpixel_variant: Default::default(),
 476            scale_factor,
 477            is_emoji: true,
 478        };
 479
 480        let raster_bounds = self.text_system().raster_bounds(&params)?;
 481        if !raster_bounds.is_zero() {
 482            let tile =
 483                self.window
 484                    .sprite_atlas
 485                    .get_or_insert_with(&params.clone().into(), &mut || {
 486                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 487                        Ok((size, Cow::Owned(bytes)))
 488                    })?;
 489            let bounds = Bounds {
 490                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 491                size: tile.bounds.size.map(Into::into),
 492            };
 493            let content_mask = self.content_mask().scale(scale_factor);
 494            let window = &mut *self.window;
 495
 496            window.scene_builder.insert(
 497                &window.current_stacking_order,
 498                PolychromeSprite {
 499                    order: 0,
 500                    bounds,
 501                    corner_radii: Default::default(),
 502                    content_mask,
 503                    tile,
 504                    grayscale: false,
 505                },
 506            );
 507        }
 508        Ok(())
 509    }
 510
 511    pub fn paint_svg(
 512        &mut self,
 513        bounds: Bounds<Pixels>,
 514        path: SharedString,
 515        color: Hsla,
 516    ) -> Result<()> {
 517        let scale_factor = self.scale_factor();
 518        let bounds = bounds.scale(scale_factor);
 519        // Render the SVG at twice the size to get a higher quality result.
 520        let params = RenderSvgParams {
 521            path,
 522            size: bounds
 523                .size
 524                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
 525        };
 526
 527        let tile =
 528            self.window
 529                .sprite_atlas
 530                .get_or_insert_with(&params.clone().into(), &mut || {
 531                    let bytes = self.svg_renderer.render(&params)?;
 532                    Ok((params.size, Cow::Owned(bytes)))
 533                })?;
 534        let content_mask = self.content_mask().scale(scale_factor);
 535
 536        let window = &mut *self.window;
 537        window.scene_builder.insert(
 538            &window.current_stacking_order,
 539            MonochromeSprite {
 540                order: 0,
 541                bounds,
 542                content_mask,
 543                color,
 544                tile,
 545            },
 546        );
 547
 548        Ok(())
 549    }
 550
 551    pub fn paint_image(
 552        &mut self,
 553        bounds: Bounds<Pixels>,
 554        corner_radii: Corners<Pixels>,
 555        data: Arc<ImageData>,
 556        grayscale: bool,
 557    ) -> Result<()> {
 558        let scale_factor = self.scale_factor();
 559        let bounds = bounds.scale(scale_factor);
 560        let params = RenderImageParams { image_id: data.id };
 561
 562        let tile = self
 563            .window
 564            .sprite_atlas
 565            .get_or_insert_with(&params.clone().into(), &mut || {
 566                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
 567            })?;
 568        let content_mask = self.content_mask().scale(scale_factor);
 569        let corner_radii = corner_radii.scale(scale_factor);
 570
 571        let window = &mut *self.window;
 572        window.scene_builder.insert(
 573            &window.current_stacking_order,
 574            PolychromeSprite {
 575                order: 0,
 576                bounds,
 577                content_mask,
 578                corner_radii,
 579                tile,
 580                grayscale,
 581            },
 582        );
 583        Ok(())
 584    }
 585
 586    pub(crate) fn draw(&mut self) -> Result<()> {
 587        let unit_entity = self.unit_entity.clone();
 588        self.update_entity(&unit_entity, |view, cx| {
 589            cx.window
 590                .mouse_event_handlers
 591                .values_mut()
 592                .for_each(Vec::clear);
 593
 594            let mut root_view = cx.window.root_view.take().unwrap();
 595            let (root_layout_id, mut frame_state) = root_view.layout(&mut (), cx)?;
 596            let available_space = cx.window.content_size.map(Into::into);
 597
 598            cx.window
 599                .layout_engine
 600                .compute_layout(root_layout_id, available_space)?;
 601            let layout = cx.window.layout_engine.layout_bounds(root_layout_id)?;
 602
 603            root_view.paint(layout, &mut (), &mut frame_state, cx)?;
 604            cx.window.root_view = Some(root_view);
 605            let scene = cx.window.scene_builder.build();
 606
 607            cx.run_on_main(view, |_, cx| {
 608                cx.window
 609                    .platform_window
 610                    .borrow_on_main_thread()
 611                    .draw(scene);
 612                cx.window.dirty = false;
 613            })
 614            .detach();
 615
 616            Ok(())
 617        })
 618    }
 619
 620    fn dispatch_event(&mut self, event: Event) -> bool {
 621        if let Some(any_mouse_event) = event.mouse_event() {
 622            if let Some(mut handlers) = self
 623                .window
 624                .mouse_event_handlers
 625                .remove(&any_mouse_event.type_id())
 626            {
 627                // Because handlers may add other handlers, we sort every time.
 628                handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
 629
 630                // Handlers may set this to false by calling `stop_propagation`
 631                self.window.propagate_event = true;
 632
 633                // Capture phase, events bubble from back to front. Handlers for this phase are used for
 634                // special purposes, such as detecting events outside of a given Bounds.
 635                for (_, handler) in &handlers {
 636                    handler(any_mouse_event, DispatchPhase::Capture, self);
 637                    if !self.window.propagate_event {
 638                        break;
 639                    }
 640                }
 641
 642                // Bubble phase, where most normal handlers do their work.
 643                if self.window.propagate_event {
 644                    for (_, handler) in handlers.iter().rev() {
 645                        handler(any_mouse_event, DispatchPhase::Bubble, self);
 646                        if !self.window.propagate_event {
 647                            break;
 648                        }
 649                    }
 650                }
 651
 652                // Just in case any handlers added new handlers, which is weird, but possible.
 653                handlers.extend(
 654                    self.window
 655                        .mouse_event_handlers
 656                        .get_mut(&any_mouse_event.type_id())
 657                        .into_iter()
 658                        .flat_map(|handlers| handlers.drain(..)),
 659                );
 660                self.window
 661                    .mouse_event_handlers
 662                    .insert(any_mouse_event.type_id(), handlers);
 663            }
 664        }
 665
 666        true
 667    }
 668}
 669
 670impl Context for WindowContext<'_, '_> {
 671    type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
 672    type Result<T> = T;
 673
 674    fn entity<T: Send + Sync + 'static>(
 675        &mut self,
 676        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 677    ) -> Handle<T> {
 678        let slot = self.app.entities.reserve();
 679        let entity = build_entity(&mut ViewContext::mutable(
 680            &mut *self.app,
 681            &mut self.window,
 682            slot.id,
 683        ));
 684        self.entities.insert(slot, entity)
 685    }
 686
 687    fn update_entity<T: Send + Sync + 'static, R>(
 688        &mut self,
 689        handle: &Handle<T>,
 690        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 691    ) -> R {
 692        let mut entity = self.entities.lease(handle);
 693        let result = update(
 694            &mut *entity,
 695            &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id),
 696        );
 697        self.entities.end_lease(entity);
 698        result
 699    }
 700}
 701
 702impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
 703    type Target = AppContext;
 704
 705    fn deref(&self) -> &Self::Target {
 706        &self.app
 707    }
 708}
 709
 710impl<'a, 'w> std::ops::DerefMut for WindowContext<'a, 'w> {
 711    fn deref_mut(&mut self) -> &mut Self::Target {
 712        &mut self.app
 713    }
 714}
 715
 716impl BorrowAppContext for WindowContext<'_, '_> {
 717    fn app_mut(&mut self) -> &mut AppContext {
 718        &mut *self.app
 719    }
 720}
 721
 722pub trait BorrowWindow: BorrowAppContext {
 723    fn window(&self) -> &Window;
 724    fn window_mut(&mut self) -> &mut Window;
 725
 726    fn with_content_mask<R>(
 727        &mut self,
 728        mask: ContentMask<Pixels>,
 729        f: impl FnOnce(&mut Self) -> R,
 730    ) -> R {
 731        let mask = mask.intersect(&self.content_mask());
 732        self.window_mut().content_mask_stack.push(mask);
 733        let result = f(self);
 734        self.window_mut().content_mask_stack.pop();
 735        result
 736    }
 737
 738    fn content_mask(&self) -> ContentMask<Pixels> {
 739        self.window()
 740            .content_mask_stack
 741            .last()
 742            .cloned()
 743            .unwrap_or_else(|| ContentMask {
 744                bounds: Bounds {
 745                    origin: Point::default(),
 746                    size: self.window().content_size,
 747                },
 748            })
 749    }
 750
 751    fn rem_size(&self) -> Pixels {
 752        self.window().rem_size
 753    }
 754}
 755
 756impl BorrowWindow for WindowContext<'_, '_> {
 757    fn window(&self) -> &Window {
 758        &*self.window
 759    }
 760
 761    fn window_mut(&mut self) -> &mut Window {
 762        &mut *self.window
 763    }
 764}
 765
 766pub struct ViewContext<'a, 'w, S> {
 767    window_cx: WindowContext<'a, 'w>,
 768    entity_type: PhantomData<S>,
 769    entity_id: EntityId,
 770}
 771
 772impl<S> BorrowAppContext for ViewContext<'_, '_, S> {
 773    fn app_mut(&mut self) -> &mut AppContext {
 774        &mut *self.window_cx.app
 775    }
 776
 777    fn with_text_style<F, R>(&mut self, style: crate::TextStyleRefinement, f: F) -> R
 778    where
 779        F: FnOnce(&mut Self) -> R,
 780    {
 781        self.window_cx.app.push_text_style(style);
 782        let result = f(self);
 783        self.window_cx.app.pop_text_style();
 784        result
 785    }
 786
 787    fn with_state<T: Send + Sync + 'static, F, R>(&mut self, state: T, f: F) -> R
 788    where
 789        F: FnOnce(&mut Self) -> R,
 790    {
 791        self.window_cx.app.push_state(state);
 792        let result = f(self);
 793        self.window_cx.app.pop_state::<T>();
 794        result
 795    }
 796}
 797
 798impl<S> BorrowWindow for ViewContext<'_, '_, S> {
 799    fn window(&self) -> &Window {
 800        &self.window_cx.window
 801    }
 802
 803    fn window_mut(&mut self) -> &mut Window {
 804        &mut *self.window_cx.window
 805    }
 806}
 807
 808impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
 809    fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
 810        Self {
 811            window_cx: WindowContext::mutable(app, window),
 812            entity_id,
 813            entity_type: PhantomData,
 814        }
 815    }
 816
 817    pub fn handle(&self) -> WeakHandle<S> {
 818        self.entities.weak_handle(self.entity_id)
 819    }
 820
 821    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
 822        self.window.current_stacking_order.push(order);
 823        let result = f(self);
 824        self.window.current_stacking_order.pop();
 825        result
 826    }
 827
 828    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut S, &mut ViewContext<S>) + Send + 'static) {
 829        let entity = self.handle();
 830        self.window_cx.on_next_frame(move |cx| {
 831            entity.update(cx, f).ok();
 832        });
 833    }
 834
 835    pub fn observe<E: Send + Sync + 'static>(
 836        &mut self,
 837        handle: &Handle<E>,
 838        on_notify: impl Fn(&mut S, Handle<E>, &mut ViewContext<'_, '_, S>) + Send + Sync + 'static,
 839    ) {
 840        let this = self.handle();
 841        let handle = handle.downgrade();
 842        let window_handle = self.window.handle;
 843        self.app
 844            .observers
 845            .entry(handle.id)
 846            .or_default()
 847            .push(Arc::new(move |cx| {
 848                cx.update_window(window_handle.id, |cx| {
 849                    if let Some(handle) = handle.upgrade(cx) {
 850                        this.update(cx, |this, cx| on_notify(this, handle, cx))
 851                            .is_ok()
 852                    } else {
 853                        false
 854                    }
 855                })
 856                .unwrap_or(false)
 857            }));
 858    }
 859
 860    pub fn notify(&mut self) {
 861        self.window_cx.notify();
 862        self.window_cx
 863            .app
 864            .pending_effects
 865            .push_back(Effect::Notify(self.entity_id));
 866    }
 867
 868    pub fn run_on_main<R>(
 869        &mut self,
 870        view: &mut S,
 871        f: impl FnOnce(&mut S, &mut MainThread<ViewContext<'_, '_, S>>) -> R + Send + 'static,
 872    ) -> Task<Result<R>>
 873    where
 874        R: Send + 'static,
 875    {
 876        if self.executor.is_main_thread() {
 877            let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
 878            Task::ready(Ok(f(view, cx)))
 879        } else {
 880            let handle = self.handle().upgrade(self).unwrap();
 881            self.window_cx.run_on_main(move |cx| handle.update(cx, f))
 882        }
 883    }
 884
 885    pub fn spawn<Fut, R>(
 886        &mut self,
 887        f: impl FnOnce(WeakHandle<S>, AsyncWindowContext) -> Fut + Send + 'static,
 888    ) -> Task<R>
 889    where
 890        R: Send + 'static,
 891        Fut: Future<Output = R> + Send + 'static,
 892    {
 893        let handle = self.handle();
 894        self.window_cx.spawn(move |_, cx| {
 895            let result = f(handle, cx);
 896            async move { result.await }
 897        })
 898    }
 899
 900    pub fn on_mouse_event<Event: 'static>(
 901        &mut self,
 902        handler: impl Fn(&mut S, &Event, DispatchPhase, &mut ViewContext<S>) + Send + Sync + 'static,
 903    ) {
 904        let handle = self.handle().upgrade(self).unwrap();
 905        self.window_cx.on_mouse_event(move |event, phase, cx| {
 906            handle.update(cx, |view, cx| {
 907                handler(view, event, phase, cx);
 908            })
 909        });
 910    }
 911
 912    pub(crate) fn erase_state<R>(&mut self, f: impl FnOnce(&mut ViewContext<()>) -> R) -> R {
 913        let entity_id = self.unit_entity.id;
 914        let mut cx = ViewContext::mutable(
 915            &mut *self.window_cx.app,
 916            &mut *self.window_cx.window,
 917            entity_id,
 918        );
 919        f(&mut cx)
 920    }
 921}
 922
 923impl<'a, 'w, S> Context for ViewContext<'a, 'w, S> {
 924    type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
 925    type Result<U> = U;
 926
 927    fn entity<T2: Send + Sync + 'static>(
 928        &mut self,
 929        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
 930    ) -> Handle<T2> {
 931        self.window_cx.entity(build_entity)
 932    }
 933
 934    fn update_entity<U: Send + Sync + 'static, R>(
 935        &mut self,
 936        handle: &Handle<U>,
 937        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
 938    ) -> R {
 939        self.window_cx.update_entity(handle, update)
 940    }
 941}
 942
 943impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
 944    type Target = WindowContext<'a, 'w>;
 945
 946    fn deref(&self) -> &Self::Target {
 947        &self.window_cx
 948    }
 949}
 950
 951impl<'a, 'w, S: 'static> std::ops::DerefMut for ViewContext<'a, 'w, S> {
 952    fn deref_mut(&mut self) -> &mut Self::Target {
 953        &mut self.window_cx
 954    }
 955}
 956
 957// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
 958slotmap::new_key_type! { pub struct WindowId; }
 959
 960#[derive(PartialEq, Eq)]
 961pub struct WindowHandle<S> {
 962    id: WindowId,
 963    state_type: PhantomData<S>,
 964}
 965
 966impl<S> Copy for WindowHandle<S> {}
 967
 968impl<S> Clone for WindowHandle<S> {
 969    fn clone(&self) -> Self {
 970        WindowHandle {
 971            id: self.id,
 972            state_type: PhantomData,
 973        }
 974    }
 975}
 976
 977impl<S> WindowHandle<S> {
 978    pub fn new(id: WindowId) -> Self {
 979        WindowHandle {
 980            id,
 981            state_type: PhantomData,
 982        }
 983    }
 984}
 985
 986impl<S: 'static> Into<AnyWindowHandle> for WindowHandle<S> {
 987    fn into(self) -> AnyWindowHandle {
 988        AnyWindowHandle {
 989            id: self.id,
 990            state_type: TypeId::of::<S>(),
 991        }
 992    }
 993}
 994
 995#[derive(Copy, Clone, PartialEq, Eq)]
 996pub struct AnyWindowHandle {
 997    pub(crate) id: WindowId,
 998    state_type: TypeId,
 999}
1000
1001#[cfg(any(test, feature = "test"))]
1002impl From<SmallVec<[u32; 16]>> for StackingOrder {
1003    fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
1004        StackingOrder(small_vec)
1005    }
1006}