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