window.rs

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