1use crate::{
2 px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
3 Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
4 Element, EntityId, EventEmitter, ExternalPaths, FileDropEvent, FocusEvent, FontId,
5 GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
6 KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Modifiers, MonochromeSprite,
7 MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas,
8 PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
9 RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription,
10 TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
11 SUBPIXEL_VARIANTS,
12};
13use anyhow::Result;
14use collections::HashMap;
15use derive_more::{Deref, DerefMut};
16use parking_lot::RwLock;
17use slotmap::SlotMap;
18use smallvec::SmallVec;
19use std::{
20 any::{Any, TypeId},
21 borrow::{Borrow, BorrowMut, Cow},
22 fmt::Debug,
23 future::Future,
24 marker::PhantomData,
25 mem,
26 sync::{
27 atomic::{AtomicUsize, Ordering::SeqCst},
28 Arc,
29 },
30};
31use util::ResultExt;
32
33#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default)]
34pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
35
36#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
37pub enum DispatchPhase {
38 /// After the capture phase comes the bubble phase, in which event handlers are
39 /// invoked front to back. This is the phase you'll usually want to use for event handlers.
40 #[default]
41 Bubble,
42 /// During the initial capture phase, event handlers are invoked back to front. This phase
43 /// is used for special purposes such as clearing the "pressed" state for click events. If
44 /// you stop event propagation during this phase, you need to know what you're doing. Handlers
45 /// outside of the immediate region may rely on detecting non-local events during this phase.
46 Capture,
47}
48
49type AnyListener = Arc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
50type AnyKeyListener = Arc<
51 dyn Fn(
52 &dyn Any,
53 &[&DispatchContext],
54 DispatchPhase,
55 &mut WindowContext,
56 ) -> Option<Box<dyn Action>>
57 + Send
58 + Sync
59 + 'static,
60>;
61type AnyFocusListener = Arc<dyn Fn(&FocusEvent, &mut WindowContext) + Send + Sync + 'static>;
62
63slotmap::new_key_type! { pub struct FocusId; }
64
65pub struct FocusHandle {
66 pub(crate) id: FocusId,
67 handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
68}
69
70impl FocusHandle {
71 pub(crate) fn new(handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>) -> Self {
72 let id = handles.write().insert(AtomicUsize::new(1));
73 Self {
74 id,
75 handles: handles.clone(),
76 }
77 }
78
79 pub(crate) fn for_id(
80 id: FocusId,
81 handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
82 ) -> Option<Self> {
83 let lock = handles.read();
84 let ref_count = lock.get(id)?;
85 if ref_count.load(SeqCst) == 0 {
86 None
87 } else {
88 ref_count.fetch_add(1, SeqCst);
89 Some(Self {
90 id,
91 handles: handles.clone(),
92 })
93 }
94 }
95
96 pub fn is_focused(&self, cx: &WindowContext) -> bool {
97 cx.window.focus == Some(self.id)
98 }
99
100 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
101 cx.focused()
102 .map_or(false, |focused| self.contains(&focused, cx))
103 }
104
105 pub fn within_focused(&self, cx: &WindowContext) -> bool {
106 let focused = cx.focused();
107 focused.map_or(false, |focused| focused.contains(self, cx))
108 }
109
110 pub(crate) fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
111 let mut ancestor = Some(other.id);
112 while let Some(ancestor_id) = ancestor {
113 if self.id == ancestor_id {
114 return true;
115 } else {
116 ancestor = cx.window.focus_parents_by_child.get(&ancestor_id).copied();
117 }
118 }
119 false
120 }
121}
122
123impl Clone for FocusHandle {
124 fn clone(&self) -> Self {
125 Self::for_id(self.id, &self.handles).unwrap()
126 }
127}
128
129impl PartialEq for FocusHandle {
130 fn eq(&self, other: &Self) -> bool {
131 self.id == other.id
132 }
133}
134
135impl Eq for FocusHandle {}
136
137impl Drop for FocusHandle {
138 fn drop(&mut self) {
139 self.handles
140 .read()
141 .get(self.id)
142 .unwrap()
143 .fetch_sub(1, SeqCst);
144 }
145}
146
147pub struct Window {
148 handle: AnyWindowHandle,
149 platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
150 display_id: DisplayId,
151 sprite_atlas: Arc<dyn PlatformAtlas>,
152 rem_size: Pixels,
153 content_size: Size<Pixels>,
154 layout_engine: TaffyLayoutEngine,
155 pub(crate) root_view: Option<AnyView>,
156 pub(crate) element_id_stack: GlobalElementId,
157 prev_frame_element_states: HashMap<GlobalElementId, AnyBox>,
158 element_states: HashMap<GlobalElementId, AnyBox>,
159 prev_frame_key_matchers: HashMap<GlobalElementId, KeyMatcher>,
160 key_matchers: HashMap<GlobalElementId, KeyMatcher>,
161 z_index_stack: StackingOrder,
162 content_mask_stack: Vec<ContentMask<Pixels>>,
163 element_offset_stack: Vec<Point<Pixels>>,
164 mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyListener)>>,
165 key_dispatch_stack: Vec<KeyDispatchStackFrame>,
166 freeze_key_dispatch_stack: bool,
167 focus_stack: Vec<FocusId>,
168 focus_parents_by_child: HashMap<FocusId, FocusId>,
169 pub(crate) focus_listeners: Vec<AnyFocusListener>,
170 pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
171 default_prevented: bool,
172 mouse_position: Point<Pixels>,
173 scale_factor: f32,
174 pub(crate) scene_builder: SceneBuilder,
175 pub(crate) dirty: bool,
176 pub(crate) last_blur: Option<Option<FocusId>>,
177 pub(crate) focus: Option<FocusId>,
178}
179
180impl Window {
181 pub(crate) fn new(
182 handle: AnyWindowHandle,
183 options: WindowOptions,
184 cx: &mut MainThread<AppContext>,
185 ) -> Self {
186 let platform_window = cx.platform().open_window(handle, options);
187 let display_id = platform_window.display().id();
188 let sprite_atlas = platform_window.sprite_atlas();
189 let mouse_position = platform_window.mouse_position();
190 let content_size = platform_window.content_size();
191 let scale_factor = platform_window.scale_factor();
192 platform_window.on_resize(Box::new({
193 let cx = cx.to_async();
194 move |content_size, scale_factor| {
195 cx.update_window(handle, |cx| {
196 cx.window.scale_factor = scale_factor;
197 cx.window.scene_builder = SceneBuilder::new();
198 cx.window.content_size = content_size;
199 cx.window.display_id = cx
200 .window
201 .platform_window
202 .borrow_on_main_thread()
203 .display()
204 .id();
205 cx.window.dirty = true;
206 })
207 .log_err();
208 }
209 }));
210
211 platform_window.on_input({
212 let cx = cx.to_async();
213 Box::new(move |event| {
214 cx.update_window(handle, |cx| cx.dispatch_event(event))
215 .log_err()
216 .unwrap_or(true)
217 })
218 });
219
220 let platform_window = MainThreadOnly::new(Arc::new(platform_window), cx.executor.clone());
221
222 Window {
223 handle,
224 platform_window,
225 display_id,
226 sprite_atlas,
227 rem_size: px(16.),
228 content_size,
229 layout_engine: TaffyLayoutEngine::new(),
230 root_view: None,
231 element_id_stack: GlobalElementId::default(),
232 prev_frame_element_states: HashMap::default(),
233 element_states: HashMap::default(),
234 prev_frame_key_matchers: HashMap::default(),
235 key_matchers: HashMap::default(),
236 z_index_stack: StackingOrder(SmallVec::new()),
237 content_mask_stack: Vec::new(),
238 element_offset_stack: Vec::new(),
239 mouse_listeners: HashMap::default(),
240 key_dispatch_stack: Vec::new(),
241 freeze_key_dispatch_stack: false,
242 focus_stack: Vec::new(),
243 focus_parents_by_child: HashMap::default(),
244 focus_listeners: Vec::new(),
245 focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
246 default_prevented: true,
247 mouse_position,
248 scale_factor,
249 scene_builder: SceneBuilder::new(),
250 dirty: true,
251 last_blur: None,
252 focus: None,
253 }
254 }
255}
256
257enum KeyDispatchStackFrame {
258 Listener {
259 event_type: TypeId,
260 listener: AnyKeyListener,
261 },
262 Context(DispatchContext),
263}
264
265#[derive(Clone, Debug, Default, PartialEq, Eq)]
266#[repr(C)]
267pub struct ContentMask<P: Clone + Default + Debug> {
268 pub bounds: Bounds<P>,
269}
270
271impl ContentMask<Pixels> {
272 pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
273 ContentMask {
274 bounds: self.bounds.scale(factor),
275 }
276 }
277
278 pub fn intersect(&self, other: &Self) -> Self {
279 let bounds = self.bounds.intersect(&other.bounds);
280 ContentMask { bounds }
281 }
282}
283
284pub struct WindowContext<'a, 'w> {
285 app: Reference<'a, AppContext>,
286 pub(crate) window: Reference<'w, Window>,
287}
288
289impl<'a, 'w> WindowContext<'a, 'w> {
290 pub(crate) fn immutable(app: &'a AppContext, window: &'w Window) -> Self {
291 Self {
292 app: Reference::Immutable(app),
293 window: Reference::Immutable(window),
294 }
295 }
296
297 pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self {
298 Self {
299 app: Reference::Mutable(app),
300 window: Reference::Mutable(window),
301 }
302 }
303
304 pub fn window_handle(&self) -> AnyWindowHandle {
305 self.window.handle
306 }
307
308 pub fn notify(&mut self) {
309 self.window.dirty = true;
310 }
311
312 pub fn focus_handle(&mut self) -> FocusHandle {
313 FocusHandle::new(&self.window.focus_handles)
314 }
315
316 pub fn focused(&self) -> Option<FocusHandle> {
317 self.window
318 .focus
319 .and_then(|id| FocusHandle::for_id(id, &self.window.focus_handles))
320 }
321
322 pub fn focus(&mut self, handle: &FocusHandle) {
323 if self.window.last_blur.is_none() {
324 self.window.last_blur = Some(self.window.focus);
325 }
326
327 let window_id = self.window.handle.id;
328 self.window.focus = Some(handle.id);
329 self.app.push_effect(Effect::FocusChanged {
330 window_id,
331 focused: Some(handle.id),
332 });
333 self.notify();
334 }
335
336 pub fn blur(&mut self) {
337 if self.window.last_blur.is_none() {
338 self.window.last_blur = Some(self.window.focus);
339 }
340
341 let window_id = self.window.handle.id;
342 self.window.focus = None;
343 self.app.push_effect(Effect::FocusChanged {
344 window_id,
345 focused: None,
346 });
347 self.notify();
348 }
349
350 pub fn run_on_main<R>(
351 &mut self,
352 f: impl FnOnce(&mut MainThread<WindowContext<'_, '_>>) -> R + Send + 'static,
353 ) -> Task<Result<R>>
354 where
355 R: Send + 'static,
356 {
357 if self.executor.is_main_thread() {
358 Task::ready(Ok(f(unsafe {
359 mem::transmute::<&mut Self, &mut MainThread<Self>>(self)
360 })))
361 } else {
362 let id = self.window.handle.id;
363 self.app.run_on_main(move |cx| cx.update_window(id, f))
364 }
365 }
366
367 pub fn to_async(&self) -> AsyncWindowContext {
368 AsyncWindowContext::new(self.app.to_async(), self.window.handle)
369 }
370
371 pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
372 let f = Box::new(f);
373 let display_id = self.window.display_id;
374 self.run_on_main(move |cx| {
375 if let Some(callbacks) = cx.next_frame_callbacks.get_mut(&display_id) {
376 callbacks.push(f);
377 // If there was already a callback, it means that we already scheduled a frame.
378 if callbacks.len() > 1 {
379 return;
380 }
381 } else {
382 let async_cx = cx.to_async();
383 cx.next_frame_callbacks.insert(display_id, vec![f]);
384 cx.platform().set_display_link_output_callback(
385 display_id,
386 Box::new(move |_current_time, _output_time| {
387 let _ = async_cx.update(|cx| {
388 let callbacks = cx
389 .next_frame_callbacks
390 .get_mut(&display_id)
391 .unwrap()
392 .drain(..)
393 .collect::<Vec<_>>();
394 for callback in callbacks {
395 callback(cx);
396 }
397
398 cx.run_on_main(move |cx| {
399 if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
400 cx.platform().stop_display_link(display_id);
401 }
402 })
403 .detach();
404 });
405 }),
406 );
407 }
408
409 cx.platform().start_display_link(display_id);
410 })
411 .detach();
412 }
413
414 pub fn spawn<Fut, R>(
415 &mut self,
416 f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static,
417 ) -> Task<R>
418 where
419 R: Send + 'static,
420 Fut: Future<Output = R> + Send + 'static,
421 {
422 let window = self.window.handle;
423 self.app.spawn(move |app| {
424 let cx = AsyncWindowContext::new(app, window);
425 let future = f(window, cx);
426 async move { future.await }
427 })
428 }
429
430 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
431 where
432 G: 'static,
433 {
434 let mut global = self.app.lease_global::<G>();
435 let result = f(&mut global, self);
436 self.app.end_global_lease(global);
437 result
438 }
439
440 pub fn request_layout(
441 &mut self,
442 style: &Style,
443 children: impl IntoIterator<Item = LayoutId>,
444 ) -> LayoutId {
445 self.app.layout_id_buffer.clear();
446 self.app.layout_id_buffer.extend(children.into_iter());
447 let rem_size = self.rem_size();
448
449 self.window
450 .layout_engine
451 .request_layout(style, rem_size, &self.app.layout_id_buffer)
452 }
453
454 pub fn request_measured_layout<
455 F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync + 'static,
456 >(
457 &mut self,
458 style: Style,
459 rem_size: Pixels,
460 measure: F,
461 ) -> LayoutId {
462 self.window
463 .layout_engine
464 .request_measured_layout(style, rem_size, measure)
465 }
466
467 pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
468 let mut bounds = self
469 .window
470 .layout_engine
471 .layout_bounds(layout_id)
472 .map(Into::into);
473 bounds.origin += self.element_offset();
474 bounds
475 }
476
477 pub fn scale_factor(&self) -> f32 {
478 self.window.scale_factor
479 }
480
481 pub fn rem_size(&self) -> Pixels {
482 self.window.rem_size
483 }
484
485 pub fn line_height(&self) -> Pixels {
486 let rem_size = self.rem_size();
487 let text_style = self.text_style();
488 text_style
489 .line_height
490 .to_pixels(text_style.font_size.into(), rem_size)
491 }
492
493 pub fn prevent_default(&mut self) {
494 self.window.default_prevented = true;
495 }
496
497 pub fn default_prevented(&self) -> bool {
498 self.window.default_prevented
499 }
500
501 pub fn on_mouse_event<Event: 'static>(
502 &mut self,
503 handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + Sync + 'static,
504 ) {
505 let order = self.window.z_index_stack.clone();
506 self.window
507 .mouse_listeners
508 .entry(TypeId::of::<Event>())
509 .or_default()
510 .push((
511 order,
512 Arc::new(move |event: &dyn Any, phase, cx| {
513 handler(event.downcast_ref().unwrap(), phase, cx)
514 }),
515 ))
516 }
517
518 pub fn mouse_position(&self) -> Point<Pixels> {
519 self.window.mouse_position
520 }
521
522 pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
523 self.window.z_index_stack.push(order);
524 let result = f(self);
525 self.window.z_index_stack.pop();
526 result
527 }
528
529 pub fn paint_shadows(
530 &mut self,
531 bounds: Bounds<Pixels>,
532 corner_radii: Corners<Pixels>,
533 shadows: &[BoxShadow],
534 ) {
535 let scale_factor = self.scale_factor();
536 let content_mask = self.content_mask();
537 let window = &mut *self.window;
538 for shadow in shadows {
539 let mut shadow_bounds = bounds;
540 shadow_bounds.origin += shadow.offset;
541 shadow_bounds.dilate(shadow.spread_radius);
542 window.scene_builder.insert(
543 &window.z_index_stack,
544 Shadow {
545 order: 0,
546 bounds: shadow_bounds.scale(scale_factor),
547 content_mask: content_mask.scale(scale_factor),
548 corner_radii: corner_radii.scale(scale_factor),
549 color: shadow.color,
550 blur_radius: shadow.blur_radius.scale(scale_factor),
551 },
552 );
553 }
554 }
555
556 pub fn paint_quad(
557 &mut self,
558 bounds: Bounds<Pixels>,
559 corner_radii: Corners<Pixels>,
560 background: impl Into<Hsla>,
561 border_widths: Edges<Pixels>,
562 border_color: impl Into<Hsla>,
563 ) {
564 let scale_factor = self.scale_factor();
565 let content_mask = self.content_mask();
566
567 let window = &mut *self.window;
568 window.scene_builder.insert(
569 &window.z_index_stack,
570 Quad {
571 order: 0,
572 bounds: bounds.scale(scale_factor),
573 content_mask: content_mask.scale(scale_factor),
574 background: background.into(),
575 border_color: border_color.into(),
576 corner_radii: corner_radii.scale(scale_factor),
577 border_widths: border_widths.scale(scale_factor),
578 },
579 );
580 }
581
582 pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
583 let scale_factor = self.scale_factor();
584 let content_mask = self.content_mask();
585 path.content_mask = content_mask;
586 path.color = color.into();
587 let window = &mut *self.window;
588 window
589 .scene_builder
590 .insert(&window.z_index_stack, path.scale(scale_factor));
591 }
592
593 pub fn paint_underline(
594 &mut self,
595 origin: Point<Pixels>,
596 width: Pixels,
597 style: &UnderlineStyle,
598 ) -> Result<()> {
599 let scale_factor = self.scale_factor();
600 let height = if style.wavy {
601 style.thickness * 3.
602 } else {
603 style.thickness
604 };
605 let bounds = Bounds {
606 origin,
607 size: size(width, height),
608 };
609 let content_mask = self.content_mask();
610 let window = &mut *self.window;
611 window.scene_builder.insert(
612 &window.z_index_stack,
613 Underline {
614 order: 0,
615 bounds: bounds.scale(scale_factor),
616 content_mask: content_mask.scale(scale_factor),
617 thickness: style.thickness.scale(scale_factor),
618 color: style.color.unwrap_or_default(),
619 wavy: style.wavy,
620 },
621 );
622 Ok(())
623 }
624
625 pub fn paint_glyph(
626 &mut self,
627 origin: Point<Pixels>,
628 font_id: FontId,
629 glyph_id: GlyphId,
630 font_size: Pixels,
631 color: Hsla,
632 ) -> Result<()> {
633 let scale_factor = self.scale_factor();
634 let glyph_origin = origin.scale(scale_factor);
635 let subpixel_variant = Point {
636 x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
637 y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
638 };
639 let params = RenderGlyphParams {
640 font_id,
641 glyph_id,
642 font_size,
643 subpixel_variant,
644 scale_factor,
645 is_emoji: false,
646 };
647
648 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
649 if !raster_bounds.is_zero() {
650 let tile =
651 self.window
652 .sprite_atlas
653 .get_or_insert_with(¶ms.clone().into(), &mut || {
654 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
655 Ok((size, Cow::Owned(bytes)))
656 })?;
657 let bounds = Bounds {
658 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
659 size: tile.bounds.size.map(Into::into),
660 };
661 let content_mask = self.content_mask().scale(scale_factor);
662 let window = &mut *self.window;
663 window.scene_builder.insert(
664 &window.z_index_stack,
665 MonochromeSprite {
666 order: 0,
667 bounds,
668 content_mask,
669 color,
670 tile,
671 },
672 );
673 }
674 Ok(())
675 }
676
677 pub fn paint_emoji(
678 &mut self,
679 origin: Point<Pixels>,
680 font_id: FontId,
681 glyph_id: GlyphId,
682 font_size: Pixels,
683 ) -> Result<()> {
684 let scale_factor = self.scale_factor();
685 let glyph_origin = origin.scale(scale_factor);
686 let params = RenderGlyphParams {
687 font_id,
688 glyph_id,
689 font_size,
690 // We don't render emojis with subpixel variants.
691 subpixel_variant: Default::default(),
692 scale_factor,
693 is_emoji: true,
694 };
695
696 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
697 if !raster_bounds.is_zero() {
698 let tile =
699 self.window
700 .sprite_atlas
701 .get_or_insert_with(¶ms.clone().into(), &mut || {
702 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
703 Ok((size, Cow::Owned(bytes)))
704 })?;
705 let bounds = Bounds {
706 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
707 size: tile.bounds.size.map(Into::into),
708 };
709 let content_mask = self.content_mask().scale(scale_factor);
710 let window = &mut *self.window;
711
712 window.scene_builder.insert(
713 &window.z_index_stack,
714 PolychromeSprite {
715 order: 0,
716 bounds,
717 corner_radii: Default::default(),
718 content_mask,
719 tile,
720 grayscale: false,
721 },
722 );
723 }
724 Ok(())
725 }
726
727 pub fn paint_svg(
728 &mut self,
729 bounds: Bounds<Pixels>,
730 path: SharedString,
731 color: Hsla,
732 ) -> Result<()> {
733 let scale_factor = self.scale_factor();
734 let bounds = bounds.scale(scale_factor);
735 // Render the SVG at twice the size to get a higher quality result.
736 let params = RenderSvgParams {
737 path,
738 size: bounds
739 .size
740 .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
741 };
742
743 let tile =
744 self.window
745 .sprite_atlas
746 .get_or_insert_with(¶ms.clone().into(), &mut || {
747 let bytes = self.svg_renderer.render(¶ms)?;
748 Ok((params.size, Cow::Owned(bytes)))
749 })?;
750 let content_mask = self.content_mask().scale(scale_factor);
751
752 let window = &mut *self.window;
753 window.scene_builder.insert(
754 &window.z_index_stack,
755 MonochromeSprite {
756 order: 0,
757 bounds,
758 content_mask,
759 color,
760 tile,
761 },
762 );
763
764 Ok(())
765 }
766
767 pub fn paint_image(
768 &mut self,
769 bounds: Bounds<Pixels>,
770 corner_radii: Corners<Pixels>,
771 data: Arc<ImageData>,
772 grayscale: bool,
773 ) -> Result<()> {
774 let scale_factor = self.scale_factor();
775 let bounds = bounds.scale(scale_factor);
776 let params = RenderImageParams { image_id: data.id };
777
778 let tile = self
779 .window
780 .sprite_atlas
781 .get_or_insert_with(¶ms.clone().into(), &mut || {
782 Ok((data.size(), Cow::Borrowed(data.as_bytes())))
783 })?;
784 let content_mask = self.content_mask().scale(scale_factor);
785 let corner_radii = corner_radii.scale(scale_factor);
786
787 let window = &mut *self.window;
788 window.scene_builder.insert(
789 &window.z_index_stack,
790 PolychromeSprite {
791 order: 0,
792 bounds,
793 content_mask,
794 corner_radii,
795 tile,
796 grayscale,
797 },
798 );
799 Ok(())
800 }
801
802 pub(crate) fn draw(&mut self) {
803 let unit_entity = self.unit_entity.clone();
804 self.update_entity(&unit_entity, |view, cx| {
805 cx.start_frame();
806
807 let mut root_view = cx.window.root_view.take().unwrap();
808
809 cx.stack(0, |cx| {
810 let available_space = cx.window.content_size.map(Into::into);
811 draw_any_view(&mut root_view, available_space, cx);
812 });
813
814 if let Some(mut active_drag) = cx.active_drag.take() {
815 cx.stack(1, |cx| {
816 let offset = cx.mouse_position() - active_drag.cursor_offset;
817 cx.with_element_offset(Some(offset), |cx| {
818 let available_space =
819 size(AvailableSpace::MinContent, AvailableSpace::MinContent);
820 if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
821 draw_any_view(drag_handle_view, available_space, cx);
822 }
823 cx.active_drag = Some(active_drag);
824 });
825 });
826 }
827
828 cx.window.root_view = Some(root_view);
829 let scene = cx.window.scene_builder.build();
830
831 cx.run_on_main(view, |_, cx| {
832 cx.window
833 .platform_window
834 .borrow_on_main_thread()
835 .draw(scene);
836 cx.window.dirty = false;
837 })
838 .detach();
839 });
840
841 fn draw_any_view(
842 view: &mut AnyView,
843 available_space: Size<AvailableSpace>,
844 cx: &mut ViewContext<()>,
845 ) {
846 cx.with_optional_element_state(view.id(), |element_state, cx| {
847 let mut element_state = view.initialize(&mut (), element_state, cx);
848 let layout_id = view.layout(&mut (), &mut element_state, cx);
849 cx.window
850 .layout_engine
851 .compute_layout(layout_id, available_space);
852 let bounds = cx.window.layout_engine.layout_bounds(layout_id);
853 view.paint(bounds, &mut (), &mut element_state, cx);
854 ((), element_state)
855 });
856 }
857 }
858
859 fn start_frame(&mut self) {
860 self.text_system().start_frame();
861
862 let window = &mut *self.window;
863
864 // Move the current frame element states to the previous frame.
865 // The new empty element states map will be populated for any element states we
866 // reference during the upcoming frame.
867 mem::swap(
868 &mut window.element_states,
869 &mut window.prev_frame_element_states,
870 );
871 window.element_states.clear();
872
873 // Make the current key matchers the previous, and then clear the current.
874 // An empty key matcher map will be created for every identified element in the
875 // upcoming frame.
876 mem::swap(
877 &mut window.key_matchers,
878 &mut window.prev_frame_key_matchers,
879 );
880 window.key_matchers.clear();
881
882 // Clear mouse event listeners, because elements add new element listeners
883 // when the upcoming frame is painted.
884 window.mouse_listeners.values_mut().for_each(Vec::clear);
885
886 // Clear focus state, because we determine what is focused when the new elements
887 // in the upcoming frame are initialized.
888 window.focus_listeners.clear();
889 window.key_dispatch_stack.clear();
890 window.focus_parents_by_child.clear();
891 window.freeze_key_dispatch_stack = false;
892 }
893
894 fn dispatch_event(&mut self, event: InputEvent) -> bool {
895 let event = match event {
896 InputEvent::MouseMove(mouse_move) => {
897 self.window.mouse_position = mouse_move.position;
898 InputEvent::MouseMove(mouse_move)
899 }
900 InputEvent::FileDrop(file_drop) => match file_drop {
901 FileDropEvent::Entered { position, files } => {
902 self.window.mouse_position = position;
903 self.active_drag.get_or_insert_with(|| AnyDrag {
904 drag_handle_view: None,
905 cursor_offset: position,
906 state: Box::new(files),
907 state_type: TypeId::of::<ExternalPaths>(),
908 });
909 InputEvent::MouseDown(MouseDownEvent {
910 position,
911 button: MouseButton::Left,
912 click_count: 1,
913 modifiers: Modifiers::default(),
914 })
915 }
916 FileDropEvent::Pending { position } => {
917 self.window.mouse_position = position;
918 InputEvent::MouseMove(MouseMoveEvent {
919 position,
920 pressed_button: Some(MouseButton::Left),
921 modifiers: Modifiers::default(),
922 })
923 }
924 FileDropEvent::Submit { position } => {
925 self.window.mouse_position = position;
926 InputEvent::MouseUp(MouseUpEvent {
927 button: MouseButton::Left,
928 position,
929 modifiers: Modifiers::default(),
930 click_count: 1,
931 })
932 }
933 FileDropEvent::Exited => InputEvent::MouseUp(MouseUpEvent {
934 button: MouseButton::Left,
935 position: Point::default(),
936 modifiers: Modifiers::default(),
937 click_count: 1,
938 }),
939 },
940 _ => event,
941 };
942
943 if let Some(any_mouse_event) = event.mouse_event() {
944 // Handlers may set this to false by calling `stop_propagation`
945 self.app.propagate_event = true;
946 self.window.default_prevented = false;
947
948 if let Some(mut handlers) = self
949 .window
950 .mouse_listeners
951 .remove(&any_mouse_event.type_id())
952 {
953 // Because handlers may add other handlers, we sort every time.
954 handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
955
956 // Capture phase, events bubble from back to front. Handlers for this phase are used for
957 // special purposes, such as detecting events outside of a given Bounds.
958 for (_, handler) in &handlers {
959 handler(any_mouse_event, DispatchPhase::Capture, self);
960 if !self.app.propagate_event {
961 break;
962 }
963 }
964
965 // Bubble phase, where most normal handlers do their work.
966 if self.app.propagate_event {
967 for (_, handler) in handlers.iter().rev() {
968 handler(any_mouse_event, DispatchPhase::Bubble, self);
969 if !self.app.propagate_event {
970 break;
971 }
972 }
973 }
974
975 if self.app.propagate_event
976 && any_mouse_event.downcast_ref::<MouseUpEvent>().is_some()
977 {
978 self.active_drag = None;
979 }
980
981 // Just in case any handlers added new handlers, which is weird, but possible.
982 handlers.extend(
983 self.window
984 .mouse_listeners
985 .get_mut(&any_mouse_event.type_id())
986 .into_iter()
987 .flat_map(|handlers| handlers.drain(..)),
988 );
989 self.window
990 .mouse_listeners
991 .insert(any_mouse_event.type_id(), handlers);
992 }
993 } else if let Some(any_key_event) = event.keyboard_event() {
994 let key_dispatch_stack = mem::take(&mut self.window.key_dispatch_stack);
995 let key_event_type = any_key_event.type_id();
996 let mut context_stack = SmallVec::<[&DispatchContext; 16]>::new();
997
998 for (ix, frame) in key_dispatch_stack.iter().enumerate() {
999 match frame {
1000 KeyDispatchStackFrame::Listener {
1001 event_type,
1002 listener,
1003 } => {
1004 if key_event_type == *event_type {
1005 if let Some(action) = listener(
1006 any_key_event,
1007 &context_stack,
1008 DispatchPhase::Capture,
1009 self,
1010 ) {
1011 self.dispatch_action(action, &key_dispatch_stack[..ix]);
1012 }
1013 if !self.app.propagate_event {
1014 break;
1015 }
1016 }
1017 }
1018 KeyDispatchStackFrame::Context(context) => {
1019 context_stack.push(&context);
1020 }
1021 }
1022 }
1023
1024 if self.app.propagate_event {
1025 for (ix, frame) in key_dispatch_stack.iter().enumerate().rev() {
1026 match frame {
1027 KeyDispatchStackFrame::Listener {
1028 event_type,
1029 listener,
1030 } => {
1031 if key_event_type == *event_type {
1032 if let Some(action) = listener(
1033 any_key_event,
1034 &context_stack,
1035 DispatchPhase::Bubble,
1036 self,
1037 ) {
1038 self.dispatch_action(action, &key_dispatch_stack[..ix]);
1039 }
1040
1041 if !self.app.propagate_event {
1042 break;
1043 }
1044 }
1045 }
1046 KeyDispatchStackFrame::Context(_) => {
1047 context_stack.pop();
1048 }
1049 }
1050 }
1051 }
1052
1053 drop(context_stack);
1054 self.window.key_dispatch_stack = key_dispatch_stack;
1055 }
1056
1057 true
1058 }
1059
1060 pub fn match_keystroke(
1061 &mut self,
1062 element_id: &GlobalElementId,
1063 keystroke: &Keystroke,
1064 context_stack: &[&DispatchContext],
1065 ) -> KeyMatch {
1066 let key_match = self
1067 .window
1068 .key_matchers
1069 .get_mut(element_id)
1070 .unwrap()
1071 .match_keystroke(keystroke, context_stack);
1072
1073 if key_match.is_some() {
1074 for matcher in self.window.key_matchers.values_mut() {
1075 matcher.clear_pending();
1076 }
1077 }
1078
1079 key_match
1080 }
1081
1082 pub fn observe_global<G: 'static>(
1083 &mut self,
1084 f: impl Fn(&mut WindowContext<'_, '_>) + Send + Sync + 'static,
1085 ) -> Subscription {
1086 let window_id = self.window.handle.id;
1087 self.global_observers.insert(
1088 TypeId::of::<G>(),
1089 Box::new(move |cx| cx.update_window(window_id, |cx| f(cx)).is_ok()),
1090 )
1091 }
1092
1093 fn dispatch_action(
1094 &mut self,
1095 action: Box<dyn Action>,
1096 dispatch_stack: &[KeyDispatchStackFrame],
1097 ) {
1098 let action_type = action.as_any().type_id();
1099
1100 if let Some(mut global_listeners) = self.app.global_action_listeners.remove(&action_type) {
1101 for listener in &global_listeners {
1102 listener(action.as_ref(), DispatchPhase::Capture, self);
1103 if !self.app.propagate_event {
1104 break;
1105 }
1106 }
1107 global_listeners.extend(
1108 self.global_action_listeners
1109 .remove(&action_type)
1110 .unwrap_or_default(),
1111 );
1112 self.global_action_listeners
1113 .insert(action_type, global_listeners);
1114 }
1115
1116 if self.app.propagate_event {
1117 for stack_frame in dispatch_stack {
1118 if let KeyDispatchStackFrame::Listener {
1119 event_type,
1120 listener,
1121 } = stack_frame
1122 {
1123 if action_type == *event_type {
1124 listener(action.as_any(), &[], DispatchPhase::Capture, self);
1125 if !self.app.propagate_event {
1126 break;
1127 }
1128 }
1129 }
1130 }
1131 }
1132
1133 if self.app.propagate_event {
1134 for stack_frame in dispatch_stack.iter().rev() {
1135 if let KeyDispatchStackFrame::Listener {
1136 event_type,
1137 listener,
1138 } = stack_frame
1139 {
1140 if action_type == *event_type {
1141 listener(action.as_any(), &[], DispatchPhase::Bubble, self);
1142 if !self.app.propagate_event {
1143 break;
1144 }
1145 }
1146 }
1147 }
1148 }
1149
1150 if self.app.propagate_event {
1151 if let Some(mut global_listeners) =
1152 self.app.global_action_listeners.remove(&action_type)
1153 {
1154 for listener in global_listeners.iter().rev() {
1155 listener(action.as_ref(), DispatchPhase::Bubble, self);
1156 if !self.app.propagate_event {
1157 break;
1158 }
1159 }
1160 global_listeners.extend(
1161 self.global_action_listeners
1162 .remove(&action_type)
1163 .unwrap_or_default(),
1164 );
1165 self.global_action_listeners
1166 .insert(action_type, global_listeners);
1167 }
1168 }
1169 }
1170}
1171
1172impl Context for WindowContext<'_, '_> {
1173 type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
1174 type Result<T> = T;
1175
1176 fn entity<T>(
1177 &mut self,
1178 build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
1179 ) -> Handle<T>
1180 where
1181 T: Any + Send + Sync,
1182 {
1183 let slot = self.app.entities.reserve();
1184 let entity = build_entity(&mut ViewContext::mutable(
1185 &mut *self.app,
1186 &mut self.window,
1187 slot.downgrade(),
1188 ));
1189 self.entities.insert(slot, entity)
1190 }
1191
1192 fn update_entity<T: 'static, R>(
1193 &mut self,
1194 handle: &Handle<T>,
1195 update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
1196 ) -> R {
1197 let mut entity = self.entities.lease(handle);
1198 let result = update(
1199 &mut *entity,
1200 &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.downgrade()),
1201 );
1202 self.entities.end_lease(entity);
1203 result
1204 }
1205}
1206
1207impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
1208 type Target = AppContext;
1209
1210 fn deref(&self) -> &Self::Target {
1211 &self.app
1212 }
1213}
1214
1215impl<'a, 'w> std::ops::DerefMut for WindowContext<'a, 'w> {
1216 fn deref_mut(&mut self) -> &mut Self::Target {
1217 &mut self.app
1218 }
1219}
1220
1221impl<'a, 'w> Borrow<AppContext> for WindowContext<'a, 'w> {
1222 fn borrow(&self) -> &AppContext {
1223 &self.app
1224 }
1225}
1226
1227impl<'a, 'w> BorrowMut<AppContext> for WindowContext<'a, 'w> {
1228 fn borrow_mut(&mut self) -> &mut AppContext {
1229 &mut self.app
1230 }
1231}
1232
1233pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
1234 fn app_mut(&mut self) -> &mut AppContext {
1235 self.borrow_mut()
1236 }
1237
1238 fn window(&self) -> &Window {
1239 self.borrow()
1240 }
1241
1242 fn window_mut(&mut self) -> &mut Window {
1243 self.borrow_mut()
1244 }
1245
1246 fn with_element_id<R>(
1247 &mut self,
1248 id: impl Into<ElementId>,
1249 f: impl FnOnce(GlobalElementId, &mut Self) -> R,
1250 ) -> R {
1251 let keymap = self.app_mut().keymap.clone();
1252 let window = self.window_mut();
1253 window.element_id_stack.push(id.into());
1254 let global_id = window.element_id_stack.clone();
1255
1256 if window.key_matchers.get(&global_id).is_none() {
1257 window.key_matchers.insert(
1258 global_id.clone(),
1259 window
1260 .prev_frame_key_matchers
1261 .remove(&global_id)
1262 .unwrap_or_else(|| KeyMatcher::new(keymap)),
1263 );
1264 }
1265
1266 let result = f(global_id, self);
1267 let window: &mut Window = self.borrow_mut();
1268 window.element_id_stack.pop();
1269 result
1270 }
1271
1272 fn with_content_mask<R>(
1273 &mut self,
1274 mask: ContentMask<Pixels>,
1275 f: impl FnOnce(&mut Self) -> R,
1276 ) -> R {
1277 let mask = mask.intersect(&self.content_mask());
1278 self.window_mut().content_mask_stack.push(mask);
1279 let result = f(self);
1280 self.window_mut().content_mask_stack.pop();
1281 result
1282 }
1283
1284 fn with_element_offset<R>(
1285 &mut self,
1286 offset: Option<Point<Pixels>>,
1287 f: impl FnOnce(&mut Self) -> R,
1288 ) -> R {
1289 let Some(offset) = offset else {
1290 return f(self);
1291 };
1292
1293 let offset = self.element_offset() + offset;
1294 self.window_mut().element_offset_stack.push(offset);
1295 let result = f(self);
1296 self.window_mut().element_offset_stack.pop();
1297 result
1298 }
1299
1300 fn element_offset(&self) -> Point<Pixels> {
1301 self.window()
1302 .element_offset_stack
1303 .last()
1304 .copied()
1305 .unwrap_or_default()
1306 }
1307
1308 fn with_element_state<S, R>(
1309 &mut self,
1310 id: ElementId,
1311 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
1312 ) -> R
1313 where
1314 S: Any + Send + Sync,
1315 {
1316 self.with_element_id(id, |global_id, cx| {
1317 if let Some(any) = cx
1318 .window_mut()
1319 .element_states
1320 .remove(&global_id)
1321 .or_else(|| cx.window_mut().prev_frame_element_states.remove(&global_id))
1322 {
1323 // Using the extra inner option to avoid needing to reallocate a new box.
1324 let mut state_box = any
1325 .downcast::<Option<S>>()
1326 .expect("invalid element state type for id");
1327 let state = state_box
1328 .take()
1329 .expect("element state is already on the stack");
1330 let (result, state) = f(Some(state), cx);
1331 state_box.replace(state);
1332 cx.window_mut().element_states.insert(global_id, state_box);
1333 result
1334 } else {
1335 let (result, state) = f(None, cx);
1336 cx.window_mut()
1337 .element_states
1338 .insert(global_id, Box::new(Some(state)));
1339 result
1340 }
1341 })
1342 }
1343
1344 fn with_optional_element_state<S, R>(
1345 &mut self,
1346 element_id: Option<ElementId>,
1347 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
1348 ) -> R
1349 where
1350 S: Any + Send + Sync,
1351 {
1352 if let Some(element_id) = element_id {
1353 self.with_element_state(element_id, f)
1354 } else {
1355 f(None, self).0
1356 }
1357 }
1358
1359 fn content_mask(&self) -> ContentMask<Pixels> {
1360 self.window()
1361 .content_mask_stack
1362 .last()
1363 .cloned()
1364 .unwrap_or_else(|| ContentMask {
1365 bounds: Bounds {
1366 origin: Point::default(),
1367 size: self.window().content_size,
1368 },
1369 })
1370 }
1371
1372 fn rem_size(&self) -> Pixels {
1373 self.window().rem_size
1374 }
1375}
1376
1377impl Borrow<Window> for WindowContext<'_, '_> {
1378 fn borrow(&self) -> &Window {
1379 &self.window
1380 }
1381}
1382
1383impl BorrowMut<Window> for WindowContext<'_, '_> {
1384 fn borrow_mut(&mut self) -> &mut Window {
1385 &mut self.window
1386 }
1387}
1388
1389impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
1390
1391pub struct ViewContext<'a, 'w, V> {
1392 window_cx: WindowContext<'a, 'w>,
1393 view_state: WeakHandle<V>,
1394}
1395
1396impl<V> Borrow<AppContext> for ViewContext<'_, '_, V> {
1397 fn borrow(&self) -> &AppContext {
1398 &*self.window_cx.app
1399 }
1400}
1401
1402impl<V> BorrowMut<AppContext> for ViewContext<'_, '_, V> {
1403 fn borrow_mut(&mut self) -> &mut AppContext {
1404 &mut *self.window_cx.app
1405 }
1406}
1407
1408impl<V> Borrow<Window> for ViewContext<'_, '_, V> {
1409 fn borrow(&self) -> &Window {
1410 &*self.window_cx.window
1411 }
1412}
1413
1414impl<V> BorrowMut<Window> for ViewContext<'_, '_, V> {
1415 fn borrow_mut(&mut self) -> &mut Window {
1416 &mut *self.window_cx.window
1417 }
1418}
1419
1420impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
1421 fn mutable(app: &'a mut AppContext, window: &'w mut Window, view_state: WeakHandle<V>) -> Self {
1422 Self {
1423 window_cx: WindowContext::mutable(app, window),
1424 view_state,
1425 }
1426 }
1427
1428 pub fn handle(&self) -> WeakHandle<V> {
1429 self.view_state.clone()
1430 }
1431
1432 pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
1433 self.window.z_index_stack.push(order);
1434 let result = f(self);
1435 self.window.z_index_stack.pop();
1436 result
1437 }
1438
1439 pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + Send + 'static)
1440 where
1441 V: Any + Send + Sync,
1442 {
1443 let entity = self.handle();
1444 self.window_cx.on_next_frame(move |cx| {
1445 entity.update(cx, f).ok();
1446 });
1447 }
1448
1449 pub fn observe<E>(
1450 &mut self,
1451 handle: &Handle<E>,
1452 mut on_notify: impl FnMut(&mut V, Handle<E>, &mut ViewContext<'_, '_, V>)
1453 + Send
1454 + Sync
1455 + 'static,
1456 ) -> Subscription
1457 where
1458 E: 'static,
1459 V: Any + Send + Sync,
1460 {
1461 let this = self.handle();
1462 let handle = handle.downgrade();
1463 let window_handle = self.window.handle;
1464 self.app.observers.insert(
1465 handle.entity_id,
1466 Box::new(move |cx| {
1467 cx.update_window(window_handle.id, |cx| {
1468 if let Some(handle) = handle.upgrade() {
1469 this.update(cx, |this, cx| on_notify(this, handle, cx))
1470 .is_ok()
1471 } else {
1472 false
1473 }
1474 })
1475 .unwrap_or(false)
1476 }),
1477 )
1478 }
1479
1480 pub fn subscribe<E: EventEmitter>(
1481 &mut self,
1482 handle: &Handle<E>,
1483 mut on_event: impl FnMut(&mut V, Handle<E>, &E::Event, &mut ViewContext<'_, '_, V>)
1484 + Send
1485 + Sync
1486 + 'static,
1487 ) -> Subscription {
1488 let this = self.handle();
1489 let handle = handle.downgrade();
1490 let window_handle = self.window.handle;
1491 self.app.event_listeners.insert(
1492 handle.entity_id,
1493 Box::new(move |event, cx| {
1494 cx.update_window(window_handle.id, |cx| {
1495 if let Some(handle) = handle.upgrade() {
1496 let event = event.downcast_ref().expect("invalid event type");
1497 this.update(cx, |this, cx| on_event(this, handle, event, cx))
1498 .is_ok()
1499 } else {
1500 false
1501 }
1502 })
1503 .unwrap_or(false)
1504 }),
1505 )
1506 }
1507
1508 pub fn on_release(
1509 &mut self,
1510 mut on_release: impl FnMut(&mut V, &mut WindowContext) + Send + Sync + 'static,
1511 ) -> Subscription {
1512 let window_handle = self.window.handle;
1513 self.app.release_listeners.insert(
1514 self.view_state.entity_id,
1515 Box::new(move |this, cx| {
1516 let this = this.downcast_mut().expect("invalid entity type");
1517 // todo!("are we okay with silently swallowing the error?")
1518 let _ = cx.update_window(window_handle.id, |cx| on_release(this, cx));
1519 }),
1520 )
1521 }
1522
1523 pub fn observe_release<T: 'static>(
1524 &mut self,
1525 handle: &Handle<T>,
1526 mut on_release: impl FnMut(&mut V, &mut T, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
1527 ) -> Subscription
1528 where
1529 V: Any + Send + Sync,
1530 {
1531 let this = self.handle();
1532 let window_handle = self.window.handle;
1533 self.app.release_listeners.insert(
1534 handle.entity_id,
1535 Box::new(move |entity, cx| {
1536 let entity = entity.downcast_mut().expect("invalid entity type");
1537 // todo!("are we okay with silently swallowing the error?")
1538 let _ = cx.update_window(window_handle.id, |cx| {
1539 this.update(cx, |this, cx| on_release(this, entity, cx))
1540 });
1541 }),
1542 )
1543 }
1544
1545 pub fn notify(&mut self) {
1546 self.window_cx.notify();
1547 self.window_cx.app.push_effect(Effect::Notify {
1548 emitter: self.view_state.entity_id,
1549 });
1550 }
1551
1552 pub fn on_focus_changed(
1553 &mut self,
1554 listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext<V>) + Send + Sync + 'static,
1555 ) {
1556 let handle = self.handle();
1557 self.window.focus_listeners.push(Arc::new(move |event, cx| {
1558 handle
1559 .update(cx, |view, cx| listener(view, event, cx))
1560 .log_err();
1561 }));
1562 }
1563
1564 pub fn with_key_listeners<R>(
1565 &mut self,
1566 key_listeners: &[(TypeId, KeyListener<V>)],
1567 f: impl FnOnce(&mut Self) -> R,
1568 ) -> R {
1569 if !self.window.freeze_key_dispatch_stack {
1570 for (event_type, listener) in key_listeners.iter().cloned() {
1571 let handle = self.handle();
1572 let listener = Arc::new(
1573 move |event: &dyn Any,
1574 context_stack: &[&DispatchContext],
1575 phase: DispatchPhase,
1576 cx: &mut WindowContext<'_, '_>| {
1577 handle
1578 .update(cx, |view, cx| {
1579 listener(view, event, context_stack, phase, cx)
1580 })
1581 .log_err()
1582 .flatten()
1583 },
1584 );
1585 self.window
1586 .key_dispatch_stack
1587 .push(KeyDispatchStackFrame::Listener {
1588 event_type,
1589 listener,
1590 });
1591 }
1592 }
1593
1594 let result = f(self);
1595
1596 if !self.window.freeze_key_dispatch_stack {
1597 let prev_len = self.window.key_dispatch_stack.len() - key_listeners.len();
1598 self.window.key_dispatch_stack.truncate(prev_len);
1599 }
1600
1601 result
1602 }
1603
1604 pub fn with_key_dispatch_context<R>(
1605 &mut self,
1606 context: DispatchContext,
1607 f: impl FnOnce(&mut Self) -> R,
1608 ) -> R {
1609 if context.is_empty() {
1610 return f(self);
1611 }
1612
1613 if !self.window.freeze_key_dispatch_stack {
1614 self.window
1615 .key_dispatch_stack
1616 .push(KeyDispatchStackFrame::Context(context));
1617 }
1618
1619 let result = f(self);
1620
1621 if !self.window.freeze_key_dispatch_stack {
1622 self.window.key_dispatch_stack.pop();
1623 }
1624
1625 result
1626 }
1627
1628 pub fn with_focus<R>(
1629 &mut self,
1630 focus_handle: FocusHandle,
1631 f: impl FnOnce(&mut Self) -> R,
1632 ) -> R {
1633 if let Some(parent_focus_id) = self.window.focus_stack.last().copied() {
1634 self.window
1635 .focus_parents_by_child
1636 .insert(focus_handle.id, parent_focus_id);
1637 }
1638 self.window.focus_stack.push(focus_handle.id);
1639
1640 if Some(focus_handle.id) == self.window.focus {
1641 self.window.freeze_key_dispatch_stack = true;
1642 }
1643
1644 let result = f(self);
1645
1646 self.window.focus_stack.pop();
1647 result
1648 }
1649
1650 pub fn run_on_main<R>(
1651 &mut self,
1652 view: &mut V,
1653 f: impl FnOnce(&mut V, &mut MainThread<ViewContext<'_, '_, V>>) -> R + Send + 'static,
1654 ) -> Task<Result<R>>
1655 where
1656 R: Send + 'static,
1657 {
1658 if self.executor.is_main_thread() {
1659 let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
1660 Task::ready(Ok(f(view, cx)))
1661 } else {
1662 let handle = self.handle().upgrade().unwrap();
1663 self.window_cx.run_on_main(move |cx| handle.update(cx, f))
1664 }
1665 }
1666
1667 pub fn spawn<Fut, R>(
1668 &mut self,
1669 f: impl FnOnce(WeakHandle<V>, AsyncWindowContext) -> Fut + Send + 'static,
1670 ) -> Task<R>
1671 where
1672 R: Send + 'static,
1673 Fut: Future<Output = R> + Send + 'static,
1674 {
1675 let handle = self.handle();
1676 self.window_cx.spawn(move |_, cx| {
1677 let result = f(handle, cx);
1678 async move { result.await }
1679 })
1680 }
1681
1682 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
1683 where
1684 G: 'static + Send + Sync,
1685 {
1686 let mut global = self.app.lease_global::<G>();
1687 let result = f(&mut global, self);
1688 self.app.end_global_lease(global);
1689 result
1690 }
1691
1692 pub fn observe_global<G: 'static>(
1693 &mut self,
1694 f: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
1695 ) -> Subscription {
1696 let window_id = self.window.handle.id;
1697 let handle = self.handle();
1698 self.global_observers.insert(
1699 TypeId::of::<G>(),
1700 Box::new(move |cx| {
1701 cx.update_window(window_id, |cx| {
1702 handle.update(cx, |view, cx| f(view, cx)).is_ok()
1703 })
1704 .unwrap_or(false)
1705 }),
1706 )
1707 }
1708
1709 pub fn on_mouse_event<Event: 'static>(
1710 &mut self,
1711 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static,
1712 ) {
1713 let handle = self.handle().upgrade().unwrap();
1714 self.window_cx.on_mouse_event(move |event, phase, cx| {
1715 handle.update(cx, |view, cx| {
1716 handler(view, event, phase, cx);
1717 })
1718 });
1719 }
1720}
1721
1722impl<'a, 'w, V> ViewContext<'a, 'w, V>
1723where
1724 V: EventEmitter,
1725 V::Event: Any + Send + Sync,
1726{
1727 pub fn emit(&mut self, event: V::Event) {
1728 let emitter = self.view_state.entity_id;
1729 self.app.push_effect(Effect::Emit {
1730 emitter,
1731 event: Box::new(event),
1732 });
1733 }
1734}
1735
1736impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
1737 type EntityContext<'b, 'c, U> = ViewContext<'b, 'c, U>;
1738 type Result<U> = U;
1739
1740 fn entity<T>(
1741 &mut self,
1742 build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
1743 ) -> Handle<T>
1744 where
1745 T: 'static + Send + Sync,
1746 {
1747 self.window_cx.entity(build_entity)
1748 }
1749
1750 fn update_entity<T: 'static, R>(
1751 &mut self,
1752 handle: &Handle<T>,
1753 update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
1754 ) -> R {
1755 self.window_cx.update_entity(handle, update)
1756 }
1757}
1758
1759impl<'a, 'w, V> std::ops::Deref for ViewContext<'a, 'w, V> {
1760 type Target = WindowContext<'a, 'w>;
1761
1762 fn deref(&self) -> &Self::Target {
1763 &self.window_cx
1764 }
1765}
1766
1767impl<'a, 'w, V> std::ops::DerefMut for ViewContext<'a, 'w, V> {
1768 fn deref_mut(&mut self) -> &mut Self::Target {
1769 &mut self.window_cx
1770 }
1771}
1772
1773// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
1774slotmap::new_key_type! { pub struct WindowId; }
1775
1776impl WindowId {
1777 pub fn as_u64(&self) -> u64 {
1778 self.0.as_ffi()
1779 }
1780}
1781
1782#[derive(PartialEq, Eq)]
1783pub struct WindowHandle<V> {
1784 id: WindowId,
1785 state_type: PhantomData<V>,
1786}
1787
1788impl<S> Copy for WindowHandle<S> {}
1789
1790impl<S> Clone for WindowHandle<S> {
1791 fn clone(&self) -> Self {
1792 WindowHandle {
1793 id: self.id,
1794 state_type: PhantomData,
1795 }
1796 }
1797}
1798
1799impl<S> WindowHandle<S> {
1800 pub fn new(id: WindowId) -> Self {
1801 WindowHandle {
1802 id,
1803 state_type: PhantomData,
1804 }
1805 }
1806}
1807
1808impl<S: 'static> Into<AnyWindowHandle> for WindowHandle<S> {
1809 fn into(self) -> AnyWindowHandle {
1810 AnyWindowHandle {
1811 id: self.id,
1812 state_type: TypeId::of::<S>(),
1813 }
1814 }
1815}
1816
1817#[derive(Copy, Clone, PartialEq, Eq)]
1818pub struct AnyWindowHandle {
1819 pub(crate) id: WindowId,
1820 state_type: TypeId,
1821}
1822
1823impl AnyWindowHandle {
1824 pub fn window_id(&self) -> WindowId {
1825 self.id
1826 }
1827}
1828
1829#[cfg(any(test, feature = "test-support"))]
1830impl From<SmallVec<[u32; 16]>> for StackingOrder {
1831 fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
1832 StackingOrder(small_vec)
1833 }
1834}
1835
1836#[derive(Clone, Debug, Eq, PartialEq, Hash)]
1837pub enum ElementId {
1838 View(EntityId),
1839 Number(usize),
1840 Name(SharedString),
1841 FocusHandle(FocusId),
1842}
1843
1844impl From<EntityId> for ElementId {
1845 fn from(id: EntityId) -> Self {
1846 ElementId::View(id)
1847 }
1848}
1849
1850impl From<usize> for ElementId {
1851 fn from(id: usize) -> Self {
1852 ElementId::Number(id)
1853 }
1854}
1855
1856impl From<i32> for ElementId {
1857 fn from(id: i32) -> Self {
1858 Self::Number(id as usize)
1859 }
1860}
1861
1862impl From<SharedString> for ElementId {
1863 fn from(name: SharedString) -> Self {
1864 ElementId::Name(name)
1865 }
1866}
1867
1868impl From<&'static str> for ElementId {
1869 fn from(name: &'static str) -> Self {
1870 ElementId::Name(name.into())
1871 }
1872}
1873
1874impl<'a> From<&'a FocusHandle> for ElementId {
1875 fn from(handle: &'a FocusHandle) -> Self {
1876 ElementId::FocusHandle(handle.id)
1877 }
1878}