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