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