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(¶ms)?;
439 if !raster_bounds.is_zero() {
440 let tile =
441 self.window
442 .sprite_atlas
443 .get_or_insert_with(¶ms.clone().into(), &mut || {
444 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
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(¶ms)?;
487 if !raster_bounds.is_zero() {
488 let tile =
489 self.window
490 .sprite_atlas
491 .get_or_insert_with(¶ms.clone().into(), &mut || {
492 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
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(¶ms.clone().into(), &mut || {
537 let bytes = self.svg_renderer.render(¶ms)?;
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(¶ms.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}