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