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(¶ms)?;
443 if !raster_bounds.is_zero() {
444 let tile =
445 self.window
446 .sprite_atlas
447 .get_or_insert_with(¶ms.clone().into(), &mut || {
448 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
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(¶ms)?;
491 if !raster_bounds.is_zero() {
492 let tile =
493 self.window
494 .sprite_atlas
495 .get_or_insert_with(¶ms.clone().into(), &mut || {
496 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
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(¶ms.clone().into(), &mut || {
541 let bytes = self.svg_renderer.render(¶ms)?;
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(¶ms.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}