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