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