1use crate::{
2 key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext,
3 AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
4 DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
5 EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
6 ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId,
7 Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent,
8 Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
9 PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
10 RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style,
11 SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View,
12 VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
13};
14use anyhow::{anyhow, Context as _, Result};
15use collections::HashMap;
16use derive_more::{Deref, DerefMut};
17use futures::{
18 channel::{mpsc, oneshot},
19 StreamExt,
20};
21use media::core_video::CVImageBuffer;
22use parking_lot::RwLock;
23use slotmap::SlotMap;
24use smallvec::SmallVec;
25use std::{
26 any::{Any, TypeId},
27 borrow::{Borrow, BorrowMut, Cow},
28 fmt::Debug,
29 future::Future,
30 hash::{Hash, Hasher},
31 marker::PhantomData,
32 mem,
33 rc::Rc,
34 sync::{
35 atomic::{AtomicUsize, Ordering::SeqCst},
36 Arc,
37 },
38};
39use util::ResultExt;
40
41const ACTIVE_DRAG_Z_INDEX: u32 = 1;
42
43/// A global stacking order, which is created by stacking successive z-index values.
44/// Each z-index will always be interpreted in the context of its parent z-index.
45#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default, Debug)]
46pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
47
48/// Represents the two different phases when dispatching events.
49#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
50pub enum DispatchPhase {
51 /// After the capture phase comes the bubble phase, in which mouse event listeners are
52 /// invoked front to back and keyboard event listeners are invoked from the focused element
53 /// to the root of the element tree. This is the phase you'll most commonly want to use when
54 /// registering event listeners.
55 #[default]
56 Bubble,
57 /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard
58 /// listeners are invoked from the root of the tree downward toward the focused element. This phase
59 /// is used for special purposes such as clearing the "pressed" state for click events. If
60 /// you stop event propagation during this phase, you need to know what you're doing. Handlers
61 /// outside of the immediate region may rely on detecting non-local events during this phase.
62 Capture,
63}
64
65impl DispatchPhase {
66 pub fn bubble(self) -> bool {
67 self == DispatchPhase::Bubble
68 }
69
70 pub fn capture(self) -> bool {
71 self == DispatchPhase::Capture
72 }
73}
74
75type AnyObserver = Box<dyn FnMut(&mut WindowContext) -> bool + 'static>;
76type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut WindowContext) + 'static>;
77type AnyFocusListener = Box<dyn Fn(&FocusEvent, &mut WindowContext) + 'static>;
78type AnyWindowFocusListener = Box<dyn FnMut(&FocusEvent, &mut WindowContext) -> bool + 'static>;
79
80slotmap::new_key_type! { pub struct FocusId; }
81
82impl FocusId {
83 /// Obtains whether the element associated with this handle is currently focused.
84 pub fn is_focused(&self, cx: &WindowContext) -> bool {
85 cx.window.focus == Some(*self)
86 }
87
88 /// Obtains whether the element associated with this handle contains the focused
89 /// element or is itself focused.
90 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
91 cx.focused()
92 .map_or(false, |focused| self.contains(focused.id, cx))
93 }
94
95 /// Obtains whether the element associated with this handle is contained within the
96 /// focused element or is itself focused.
97 pub fn within_focused(&self, cx: &WindowContext) -> bool {
98 let focused = cx.focused();
99 focused.map_or(false, |focused| focused.id.contains(*self, cx))
100 }
101
102 /// Obtains whether this handle contains the given handle in the most recently rendered frame.
103 pub(crate) fn contains(&self, other: Self, cx: &WindowContext) -> bool {
104 cx.window
105 .rendered_frame
106 .dispatch_tree
107 .focus_contains(*self, other)
108 }
109}
110
111/// A handle which can be used to track and manipulate the focused element in a window.
112pub struct FocusHandle {
113 pub(crate) id: FocusId,
114 handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
115}
116
117impl std::fmt::Debug for FocusHandle {
118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 f.write_fmt(format_args!("FocusHandle({:?})", self.id))
120 }
121}
122
123impl FocusHandle {
124 pub(crate) fn new(handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>) -> Self {
125 let id = handles.write().insert(AtomicUsize::new(1));
126 Self {
127 id,
128 handles: handles.clone(),
129 }
130 }
131
132 pub(crate) fn for_id(
133 id: FocusId,
134 handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
135 ) -> Option<Self> {
136 let lock = handles.read();
137 let ref_count = lock.get(id)?;
138 if ref_count.load(SeqCst) == 0 {
139 None
140 } else {
141 ref_count.fetch_add(1, SeqCst);
142 Some(Self {
143 id,
144 handles: handles.clone(),
145 })
146 }
147 }
148
149 /// Moves the focus to the element associated with this handle.
150 pub fn focus(&self, cx: &mut WindowContext) {
151 cx.focus(self)
152 }
153
154 /// Obtains whether the element associated with this handle is currently focused.
155 pub fn is_focused(&self, cx: &WindowContext) -> bool {
156 self.id.is_focused(cx)
157 }
158
159 /// Obtains whether the element associated with this handle contains the focused
160 /// element or is itself focused.
161 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
162 self.id.contains_focused(cx)
163 }
164
165 /// Obtains whether the element associated with this handle is contained within the
166 /// focused element or is itself focused.
167 pub fn within_focused(&self, cx: &WindowContext) -> bool {
168 self.id.within_focused(cx)
169 }
170
171 // TODO kb now never used?
172 /// Obtains whether this handle contains the given handle in the most recently rendered frame.
173 pub(crate) fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
174 self.id.contains(other.id, cx)
175 }
176}
177
178impl Clone for FocusHandle {
179 fn clone(&self) -> Self {
180 Self::for_id(self.id, &self.handles).unwrap()
181 }
182}
183
184impl PartialEq for FocusHandle {
185 fn eq(&self, other: &Self) -> bool {
186 self.id == other.id
187 }
188}
189
190impl Eq for FocusHandle {}
191
192impl Drop for FocusHandle {
193 fn drop(&mut self) {
194 self.handles
195 .read()
196 .get(self.id)
197 .unwrap()
198 .fetch_sub(1, SeqCst);
199 }
200}
201
202/// FocusableView allows users of your view to easily
203/// focus it (using cx.focus_view(view))
204pub trait FocusableView: 'static + Render {
205 fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
206}
207
208/// ManagedView is a view (like a Modal, Popover, Menu, etc.)
209/// where the lifecycle of the view is handled by another view.
210pub trait ManagedView: FocusableView + EventEmitter<DismissEvent> {}
211
212impl<M: FocusableView + EventEmitter<DismissEvent>> ManagedView for M {}
213
214pub struct DismissEvent;
215
216// Holds the state for a specific window.
217pub struct Window {
218 pub(crate) handle: AnyWindowHandle,
219 pub(crate) removed: bool,
220 pub(crate) platform_window: Box<dyn PlatformWindow>,
221 display_id: DisplayId,
222 sprite_atlas: Arc<dyn PlatformAtlas>,
223 rem_size: Pixels,
224 viewport_size: Size<Pixels>,
225 layout_engine: Option<TaffyLayoutEngine>,
226 pub(crate) root_view: Option<AnyView>,
227 pub(crate) element_id_stack: GlobalElementId,
228 pub(crate) rendered_frame: Frame,
229 pub(crate) next_frame: Frame,
230 pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
231 pub(crate) focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
232 default_prevented: bool,
233 mouse_position: Point<Pixels>,
234 requested_cursor_style: Option<CursorStyle>,
235 scale_factor: f32,
236 bounds: WindowBounds,
237 bounds_observers: SubscriberSet<(), AnyObserver>,
238 active: bool,
239 pub(crate) dirty: bool,
240 activation_observers: SubscriberSet<(), AnyObserver>,
241 pub(crate) last_blur: Option<Option<FocusId>>,
242 pub(crate) focus: Option<FocusId>,
243}
244
245pub(crate) struct ElementStateBox {
246 inner: Box<dyn Any>,
247 #[cfg(debug_assertions)]
248 type_name: &'static str,
249}
250
251// #[derive(Default)]
252pub(crate) struct Frame {
253 pub(crate) element_states: HashMap<GlobalElementId, ElementStateBox>,
254 mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyMouseListener)>>,
255 pub(crate) dispatch_tree: DispatchTree,
256 pub(crate) focus_listeners: Vec<AnyFocusListener>,
257 pub(crate) scene_builder: SceneBuilder,
258 pub(crate) depth_map: Vec<(StackingOrder, Bounds<Pixels>)>,
259 pub(crate) z_index_stack: StackingOrder,
260 content_mask_stack: Vec<ContentMask<Pixels>>,
261 element_offset_stack: Vec<Point<Pixels>>,
262}
263
264impl Frame {
265 fn new(dispatch_tree: DispatchTree) -> Self {
266 Frame {
267 element_states: HashMap::default(),
268 mouse_listeners: HashMap::default(),
269 dispatch_tree,
270 focus_listeners: Vec::new(),
271 scene_builder: SceneBuilder::default(),
272 z_index_stack: StackingOrder::default(),
273 depth_map: Default::default(),
274 content_mask_stack: Vec::new(),
275 element_offset_stack: Vec::new(),
276 }
277 }
278
279 fn clear(&mut self) {
280 self.element_states.clear();
281 self.mouse_listeners.values_mut().for_each(Vec::clear);
282 self.focus_listeners.clear();
283 self.dispatch_tree.clear();
284 self.depth_map.clear();
285 }
286}
287
288impl Window {
289 pub(crate) fn new(
290 handle: AnyWindowHandle,
291 options: WindowOptions,
292 cx: &mut AppContext,
293 ) -> Self {
294 let platform_window = cx.platform.open_window(
295 handle,
296 options,
297 Box::new({
298 let mut cx = cx.to_async();
299 move || handle.update(&mut cx, |_, cx| cx.draw())
300 }),
301 );
302 let display_id = platform_window.display().id();
303 let sprite_atlas = platform_window.sprite_atlas();
304 let mouse_position = platform_window.mouse_position();
305 let content_size = platform_window.content_size();
306 let scale_factor = platform_window.scale_factor();
307 let bounds = platform_window.bounds();
308
309 platform_window.on_resize(Box::new({
310 let mut cx = cx.to_async();
311 move |_, _| {
312 handle
313 .update(&mut cx, |_, cx| cx.window_bounds_changed())
314 .log_err();
315 }
316 }));
317 platform_window.on_moved(Box::new({
318 let mut cx = cx.to_async();
319 move || {
320 handle
321 .update(&mut cx, |_, cx| cx.window_bounds_changed())
322 .log_err();
323 }
324 }));
325 platform_window.on_active_status_change(Box::new({
326 let mut cx = cx.to_async();
327 move |active| {
328 handle
329 .update(&mut cx, |_, cx| {
330 cx.window.active = active;
331 cx.window
332 .activation_observers
333 .clone()
334 .retain(&(), |callback| callback(cx));
335 })
336 .log_err();
337 }
338 }));
339
340 platform_window.on_input({
341 let mut cx = cx.to_async();
342 Box::new(move |event| {
343 handle
344 .update(&mut cx, |_, cx| cx.dispatch_event(event))
345 .log_err()
346 .unwrap_or(false)
347 })
348 });
349
350 Window {
351 handle,
352 removed: false,
353 platform_window,
354 display_id,
355 sprite_atlas,
356 rem_size: px(16.),
357 viewport_size: content_size,
358 layout_engine: Some(TaffyLayoutEngine::new()),
359 root_view: None,
360 element_id_stack: GlobalElementId::default(),
361 rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
362 next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
363 focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
364 focus_listeners: SubscriberSet::new(),
365 default_prevented: true,
366 mouse_position,
367 requested_cursor_style: None,
368 scale_factor,
369 bounds,
370 bounds_observers: SubscriberSet::new(),
371 active: false,
372 dirty: false,
373 activation_observers: SubscriberSet::new(),
374 last_blur: None,
375 focus: None,
376 }
377 }
378}
379
380/// Indicates which region of the window is visible. Content falling outside of this mask will not be
381/// rendered. Currently, only rectangular content masks are supported, but we give the mask its own type
382/// to leave room to support more complex shapes in the future.
383#[derive(Clone, Debug, Default, PartialEq, Eq)]
384#[repr(C)]
385pub struct ContentMask<P: Clone + Default + Debug> {
386 pub bounds: Bounds<P>,
387}
388
389impl ContentMask<Pixels> {
390 /// Scale the content mask's pixel units by the given scaling factor.
391 pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
392 ContentMask {
393 bounds: self.bounds.scale(factor),
394 }
395 }
396
397 /// Intersect the content mask with the given content mask.
398 pub fn intersect(&self, other: &Self) -> Self {
399 let bounds = self.bounds.intersect(&other.bounds);
400 ContentMask { bounds }
401 }
402}
403
404/// Provides access to application state in the context of a single window. Derefs
405/// to an `AppContext`, so you can also pass a `WindowContext` to any method that takes
406/// an `AppContext` and call any `AppContext` methods.
407pub struct WindowContext<'a> {
408 pub(crate) app: &'a mut AppContext,
409 pub(crate) window: &'a mut Window,
410}
411
412impl<'a> WindowContext<'a> {
413 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window) -> Self {
414 Self { app, window }
415 }
416
417 /// Obtain a handle to the window that belongs to this context.
418 pub fn window_handle(&self) -> AnyWindowHandle {
419 self.window.handle
420 }
421
422 /// Mark the window as dirty, scheduling it to be redrawn on the next frame.
423 pub fn notify(&mut self) {
424 self.window.dirty = true;
425 }
426
427 /// Close this window.
428 pub fn remove_window(&mut self) {
429 self.window.removed = true;
430 }
431
432 /// Obtain a new `FocusHandle`, which allows you to track and manipulate the keyboard focus
433 /// for elements rendered within this window.
434 pub fn focus_handle(&mut self) -> FocusHandle {
435 FocusHandle::new(&self.window.focus_handles)
436 }
437
438 /// Obtain the currently focused `FocusHandle`. If no elements are focused, returns `None`.
439 pub fn focused(&self) -> Option<FocusHandle> {
440 self.window
441 .focus
442 .and_then(|id| FocusHandle::for_id(id, &self.window.focus_handles))
443 }
444
445 /// Move focus to the element associated with the given `FocusHandle`.
446 pub fn focus(&mut self, handle: &FocusHandle) {
447 if self.window.focus == Some(handle.id) {
448 return;
449 }
450
451 let focus_id = handle.id;
452
453 if self.window.last_blur.is_none() {
454 self.window.last_blur = Some(self.window.focus);
455 }
456
457 self.window.focus = Some(focus_id);
458 self.window
459 .rendered_frame
460 .dispatch_tree
461 .clear_pending_keystrokes();
462 self.app.push_effect(Effect::FocusChanged {
463 window_handle: self.window.handle,
464 focused: Some(focus_id),
465 });
466 self.notify();
467 }
468
469 /// Remove focus from all elements within this context's window.
470 pub fn blur(&mut self) {
471 if self.window.last_blur.is_none() {
472 self.window.last_blur = Some(self.window.focus);
473 }
474
475 self.window.focus = None;
476 self.app.push_effect(Effect::FocusChanged {
477 window_handle: self.window.handle,
478 focused: None,
479 });
480 self.notify();
481 }
482
483 pub fn dispatch_action(&mut self, action: Box<dyn Action>) {
484 let focus_handle = self.focused();
485
486 self.defer(move |cx| {
487 let node_id = focus_handle
488 .and_then(|handle| {
489 cx.window
490 .rendered_frame
491 .dispatch_tree
492 .focusable_node_id(handle.id)
493 })
494 .unwrap_or_else(|| cx.window.rendered_frame.dispatch_tree.root_node_id());
495
496 cx.propagate_event = true;
497 cx.dispatch_action_on_node(node_id, action);
498 })
499 }
500
501 pub(crate) fn dispatch_keystroke_observers(
502 &mut self,
503 event: &dyn Any,
504 action: Option<Box<dyn Action>>,
505 ) {
506 let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() else {
507 return;
508 };
509
510 self.keystroke_observers
511 .clone()
512 .retain(&(), move |callback| {
513 (callback)(
514 &KeystrokeEvent {
515 keystroke: key_down_event.keystroke.clone(),
516 action: action.as_ref().map(|action| action.boxed_clone()),
517 },
518 self,
519 );
520 true
521 });
522 }
523
524 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
525 /// that are currently on the stack to be returned to the app.
526 pub fn defer(&mut self, f: impl FnOnce(&mut WindowContext) + 'static) {
527 let handle = self.window.handle;
528 self.app.defer(move |cx| {
529 handle.update(cx, |_, cx| f(cx)).ok();
530 });
531 }
532
533 pub fn subscribe<Emitter, E, Evt>(
534 &mut self,
535 entity: &E,
536 mut on_event: impl FnMut(E, &Evt, &mut WindowContext<'_>) + 'static,
537 ) -> Subscription
538 where
539 Emitter: EventEmitter<Evt>,
540 E: Entity<Emitter>,
541 Evt: 'static,
542 {
543 let entity_id = entity.entity_id();
544 let entity = entity.downgrade();
545 let window_handle = self.window.handle;
546 let (subscription, activate) = self.app.event_listeners.insert(
547 entity_id,
548 (
549 TypeId::of::<Evt>(),
550 Box::new(move |event, cx| {
551 window_handle
552 .update(cx, |_, cx| {
553 if let Some(handle) = E::upgrade_from(&entity) {
554 let event = event.downcast_ref().expect("invalid event type");
555 on_event(handle, event, cx);
556 true
557 } else {
558 false
559 }
560 })
561 .unwrap_or(false)
562 }),
563 ),
564 );
565 self.app.defer(move |_| activate());
566 subscription
567 }
568
569 /// Create an `AsyncWindowContext`, which has a static lifetime and can be held across
570 /// await points in async code.
571 pub fn to_async(&self) -> AsyncWindowContext {
572 AsyncWindowContext::new(self.app.to_async(), self.window.handle)
573 }
574
575 /// Schedule the given closure to be run directly after the current frame is rendered.
576 pub fn on_next_frame(&mut self, callback: impl FnOnce(&mut WindowContext) + 'static) {
577 let handle = self.window.handle;
578 let display_id = self.window.display_id;
579
580 if !self.frame_consumers.contains_key(&display_id) {
581 let (tx, mut rx) = mpsc::unbounded::<()>();
582 self.platform.set_display_link_output_callback(
583 display_id,
584 Box::new(move |_current_time, _output_time| _ = tx.unbounded_send(())),
585 );
586
587 let consumer_task = self.app.spawn(|cx| async move {
588 while rx.next().await.is_some() {
589 cx.update(|cx| {
590 for callback in cx
591 .next_frame_callbacks
592 .get_mut(&display_id)
593 .unwrap()
594 .drain(..)
595 .collect::<SmallVec<[_; 32]>>()
596 {
597 callback(cx);
598 }
599 })
600 .ok();
601
602 // Flush effects, then stop the display link if no new next_frame_callbacks have been added.
603
604 cx.update(|cx| {
605 if cx.next_frame_callbacks.is_empty() {
606 cx.platform.stop_display_link(display_id);
607 }
608 })
609 .ok();
610 }
611 });
612 self.frame_consumers.insert(display_id, consumer_task);
613 }
614
615 if self.next_frame_callbacks.is_empty() {
616 self.platform.start_display_link(display_id);
617 }
618
619 self.next_frame_callbacks
620 .entry(display_id)
621 .or_default()
622 .push(Box::new(move |cx: &mut AppContext| {
623 cx.update_window(handle, |_root_view, cx| callback(cx)).ok();
624 }));
625 }
626
627 /// Spawn the future returned by the given closure on the application thread pool.
628 /// The closure is provided a handle to the current window and an `AsyncWindowContext` for
629 /// use within your future.
630 pub fn spawn<Fut, R>(&mut self, f: impl FnOnce(AsyncWindowContext) -> Fut) -> Task<R>
631 where
632 R: 'static,
633 Fut: Future<Output = R> + 'static,
634 {
635 self.app
636 .spawn(|app| f(AsyncWindowContext::new(app, self.window.handle)))
637 }
638
639 /// Update the global of the given type. The given closure is given simultaneous mutable
640 /// access both to the global and the context.
641 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
642 where
643 G: 'static,
644 {
645 let mut global = self.app.lease_global::<G>();
646 let result = f(&mut global, self);
647 self.app.end_global_lease(global);
648 result
649 }
650
651 #[must_use]
652 /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
653 /// layout is being requested, along with the layout ids of any children. This method is called during
654 /// calls to the `Element::layout` trait method and enables any element to participate in layout.
655 pub fn request_layout(
656 &mut self,
657 style: &Style,
658 children: impl IntoIterator<Item = LayoutId>,
659 ) -> LayoutId {
660 self.app.layout_id_buffer.clear();
661 self.app.layout_id_buffer.extend(children.into_iter());
662 let rem_size = self.rem_size();
663
664 self.window.layout_engine.as_mut().unwrap().request_layout(
665 style,
666 rem_size,
667 &self.app.layout_id_buffer,
668 )
669 }
670
671 /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
672 /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
673 /// determine the element's size. One place this is used internally is when measuring text.
674 ///
675 /// The given closure is invoked at layout time with the known dimensions and available space and
676 /// returns a `Size`.
677 pub fn request_measured_layout<
678 F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
679 + 'static,
680 >(
681 &mut self,
682 style: Style,
683 measure: F,
684 ) -> LayoutId {
685 let rem_size = self.rem_size();
686 self.window
687 .layout_engine
688 .as_mut()
689 .unwrap()
690 .request_measured_layout(style, rem_size, measure)
691 }
692
693 pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
694 let mut layout_engine = self.window.layout_engine.take().unwrap();
695 layout_engine.compute_layout(layout_id, available_space, self);
696 self.window.layout_engine = Some(layout_engine);
697 }
698
699 /// Obtain the bounds computed for the given LayoutId relative to the window. This method should not
700 /// be invoked until the paint phase begins, and will usually be invoked by GPUI itself automatically
701 /// in order to pass your element its `Bounds` automatically.
702 pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
703 let mut bounds = self
704 .window
705 .layout_engine
706 .as_mut()
707 .unwrap()
708 .layout_bounds(layout_id)
709 .map(Into::into);
710 bounds.origin += self.element_offset();
711 bounds
712 }
713
714 fn window_bounds_changed(&mut self) {
715 self.window.scale_factor = self.window.platform_window.scale_factor();
716 self.window.viewport_size = self.window.platform_window.content_size();
717 self.window.bounds = self.window.platform_window.bounds();
718 self.window.display_id = self.window.platform_window.display().id();
719 self.notify();
720
721 self.window
722 .bounds_observers
723 .clone()
724 .retain(&(), |callback| callback(self));
725 }
726
727 pub fn window_bounds(&self) -> WindowBounds {
728 self.window.bounds
729 }
730
731 pub fn viewport_size(&self) -> Size<Pixels> {
732 self.window.viewport_size
733 }
734
735 pub fn is_window_active(&self) -> bool {
736 self.window.active
737 }
738
739 pub fn zoom_window(&self) {
740 self.window.platform_window.zoom();
741 }
742
743 pub fn set_window_title(&mut self, title: &str) {
744 self.window.platform_window.set_title(title);
745 }
746
747 pub fn display(&self) -> Option<Rc<dyn PlatformDisplay>> {
748 self.platform
749 .displays()
750 .into_iter()
751 .find(|display| display.id() == self.window.display_id)
752 }
753
754 pub fn show_character_palette(&self) {
755 self.window.platform_window.show_character_palette();
756 }
757
758 /// The scale factor of the display associated with the window. For example, it could
759 /// return 2.0 for a "retina" display, indicating that each logical pixel should actually
760 /// be rendered as two pixels on screen.
761 pub fn scale_factor(&self) -> f32 {
762 self.window.scale_factor
763 }
764
765 /// The size of an em for the base font of the application. Adjusting this value allows the
766 /// UI to scale, just like zooming a web page.
767 pub fn rem_size(&self) -> Pixels {
768 self.window.rem_size
769 }
770
771 /// Sets the size of an em for the base font of the application. Adjusting this value allows the
772 /// UI to scale, just like zooming a web page.
773 pub fn set_rem_size(&mut self, rem_size: impl Into<Pixels>) {
774 self.window.rem_size = rem_size.into();
775 }
776
777 /// The line height associated with the current text style.
778 pub fn line_height(&self) -> Pixels {
779 let rem_size = self.rem_size();
780 let text_style = self.text_style();
781 text_style
782 .line_height
783 .to_pixels(text_style.font_size.into(), rem_size)
784 }
785
786 /// Call to prevent the default action of an event. Currently only used to prevent
787 /// parent elements from becoming focused on mouse down.
788 pub fn prevent_default(&mut self) {
789 self.window.default_prevented = true;
790 }
791
792 /// Obtain whether default has been prevented for the event currently being dispatched.
793 pub fn default_prevented(&self) -> bool {
794 self.window.default_prevented
795 }
796
797 /// Register a mouse event listener on the window for the next frame. The type of event
798 /// is determined by the first parameter of the given listener. When the next frame is rendered
799 /// the listener will be cleared.
800 ///
801 /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
802 /// a specific need to register a global listener.
803 pub fn on_mouse_event<Event: 'static>(
804 &mut self,
805 handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
806 ) {
807 let order = self.window.next_frame.z_index_stack.clone();
808 self.window
809 .next_frame
810 .mouse_listeners
811 .entry(TypeId::of::<Event>())
812 .or_default()
813 .push((
814 order,
815 Box::new(move |event: &dyn Any, phase, cx| {
816 handler(event.downcast_ref().unwrap(), phase, cx)
817 }),
818 ))
819 }
820
821 /// Register a key event listener on the window for the next frame. The type of event
822 /// is determined by the first parameter of the given listener. When the next frame is rendered
823 /// the listener will be cleared.
824 ///
825 /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
826 /// a specific need to register a global listener.
827 pub fn on_key_event<Event: 'static>(
828 &mut self,
829 handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
830 ) {
831 self.window
832 .next_frame
833 .dispatch_tree
834 .on_key_event(Rc::new(move |event, phase, cx| {
835 if let Some(event) = event.downcast_ref::<Event>() {
836 handler(event, phase, cx)
837 }
838 }));
839 }
840
841 /// Register an action listener on the window for the next frame. The type of action
842 /// is determined by the first parameter of the given listener. When the next frame is rendered
843 /// the listener will be cleared.
844 ///
845 /// This is a fairly low-level method, so prefer using action handlers on elements unless you have
846 /// a specific need to register a global listener.
847 pub fn on_action(
848 &mut self,
849 action_type: TypeId,
850 handler: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static,
851 ) {
852 self.window.next_frame.dispatch_tree.on_action(
853 action_type,
854 Rc::new(move |action, phase, cx| handler(action, phase, cx)),
855 );
856 }
857
858 pub fn is_action_available(&self, action: &dyn Action) -> bool {
859 let target = self
860 .focused()
861 .and_then(|focused_handle| {
862 self.window
863 .rendered_frame
864 .dispatch_tree
865 .focusable_node_id(focused_handle.id)
866 })
867 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
868 self.window
869 .rendered_frame
870 .dispatch_tree
871 .is_action_available(action, target)
872 }
873
874 /// The position of the mouse relative to the window.
875 pub fn mouse_position(&self) -> Point<Pixels> {
876 self.window.mouse_position
877 }
878
879 pub fn set_cursor_style(&mut self, style: CursorStyle) {
880 self.window.requested_cursor_style = Some(style)
881 }
882
883 /// Called during painting to invoke the given closure in a new stacking context. The given
884 /// z-index is interpreted relative to the previous call to `stack`.
885 pub fn with_z_index<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
886 self.window.next_frame.z_index_stack.push(z_index);
887 let result = f(self);
888 self.window.next_frame.z_index_stack.pop();
889 result
890 }
891
892 /// Called during painting to track which z-index is on top at each pixel position
893 pub fn add_opaque_layer(&mut self, bounds: Bounds<Pixels>) {
894 let stacking_order = self.window.next_frame.z_index_stack.clone();
895 let depth_map = &mut self.window.next_frame.depth_map;
896 match depth_map.binary_search_by(|(level, _)| stacking_order.cmp(&level)) {
897 Ok(i) | Err(i) => depth_map.insert(i, (stacking_order, bounds)),
898 }
899 }
900
901 /// Returns true if the top-most opaque layer painted over this point was part of the
902 /// same layer as the given stacking order.
903 pub fn was_top_layer(&self, point: &Point<Pixels>, level: &StackingOrder) -> bool {
904 for (stack, bounds) in self.window.rendered_frame.depth_map.iter() {
905 if bounds.contains(point) {
906 return level.starts_with(stack) || stack.starts_with(level);
907 }
908 }
909
910 false
911 }
912
913 pub fn was_top_layer_under_active_drag(
914 &self,
915 point: &Point<Pixels>,
916 level: &StackingOrder,
917 ) -> bool {
918 for (stack, bounds) in self.window.rendered_frame.depth_map.iter() {
919 if stack.starts_with(&[ACTIVE_DRAG_Z_INDEX]) {
920 continue;
921 }
922 if bounds.contains(point) {
923 return level.starts_with(stack) || stack.starts_with(level);
924 }
925 }
926
927 false
928 }
929
930 /// Called during painting to get the current stacking order.
931 pub fn stacking_order(&self) -> &StackingOrder {
932 &self.window.next_frame.z_index_stack
933 }
934
935 /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
936 pub fn paint_shadows(
937 &mut self,
938 bounds: Bounds<Pixels>,
939 corner_radii: Corners<Pixels>,
940 shadows: &[BoxShadow],
941 ) {
942 let scale_factor = self.scale_factor();
943 let content_mask = self.content_mask();
944 let window = &mut *self.window;
945 for shadow in shadows {
946 let mut shadow_bounds = bounds;
947 shadow_bounds.origin += shadow.offset;
948 shadow_bounds.dilate(shadow.spread_radius);
949 window.next_frame.scene_builder.insert(
950 &window.next_frame.z_index_stack,
951 Shadow {
952 order: 0,
953 bounds: shadow_bounds.scale(scale_factor),
954 content_mask: content_mask.scale(scale_factor),
955 corner_radii: corner_radii.scale(scale_factor),
956 color: shadow.color,
957 blur_radius: shadow.blur_radius.scale(scale_factor),
958 },
959 );
960 }
961 }
962
963 /// Paint one or more quads into the scene for the next frame at the current stacking context.
964 /// Quads are colored rectangular regions with an optional background, border, and corner radius.
965 pub fn paint_quad(
966 &mut self,
967 bounds: Bounds<Pixels>,
968 corner_radii: Corners<Pixels>,
969 background: impl Into<Hsla>,
970 border_widths: Edges<Pixels>,
971 border_color: impl Into<Hsla>,
972 ) {
973 let scale_factor = self.scale_factor();
974 let content_mask = self.content_mask();
975
976 let window = &mut *self.window;
977 window.next_frame.scene_builder.insert(
978 &window.next_frame.z_index_stack,
979 Quad {
980 order: 0,
981 bounds: bounds.scale(scale_factor),
982 content_mask: content_mask.scale(scale_factor),
983 background: background.into(),
984 border_color: border_color.into(),
985 corner_radii: corner_radii.scale(scale_factor),
986 border_widths: border_widths.scale(scale_factor),
987 },
988 );
989 }
990
991 /// Paint the given `Path` into the scene for the next frame at the current z-index.
992 pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
993 let scale_factor = self.scale_factor();
994 let content_mask = self.content_mask();
995 path.content_mask = content_mask;
996 path.color = color.into();
997 let window = &mut *self.window;
998 window
999 .next_frame
1000 .scene_builder
1001 .insert(&window.next_frame.z_index_stack, path.scale(scale_factor));
1002 }
1003
1004 /// Paint an underline into the scene for the next frame at the current z-index.
1005 pub fn paint_underline(
1006 &mut self,
1007 origin: Point<Pixels>,
1008 width: Pixels,
1009 style: &UnderlineStyle,
1010 ) {
1011 let scale_factor = self.scale_factor();
1012 let height = if style.wavy {
1013 style.thickness * 3.
1014 } else {
1015 style.thickness
1016 };
1017 let bounds = Bounds {
1018 origin,
1019 size: size(width, height),
1020 };
1021 let content_mask = self.content_mask();
1022 let window = &mut *self.window;
1023 window.next_frame.scene_builder.insert(
1024 &window.next_frame.z_index_stack,
1025 Underline {
1026 order: 0,
1027 bounds: bounds.scale(scale_factor),
1028 content_mask: content_mask.scale(scale_factor),
1029 thickness: style.thickness.scale(scale_factor),
1030 color: style.color.unwrap_or_default(),
1031 wavy: style.wavy,
1032 },
1033 );
1034 }
1035
1036 /// Paint a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
1037 /// The y component of the origin is the baseline of the glyph.
1038 pub fn paint_glyph(
1039 &mut self,
1040 origin: Point<Pixels>,
1041 font_id: FontId,
1042 glyph_id: GlyphId,
1043 font_size: Pixels,
1044 color: Hsla,
1045 ) -> Result<()> {
1046 let scale_factor = self.scale_factor();
1047 let glyph_origin = origin.scale(scale_factor);
1048 let subpixel_variant = Point {
1049 x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
1050 y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
1051 };
1052 let params = RenderGlyphParams {
1053 font_id,
1054 glyph_id,
1055 font_size,
1056 subpixel_variant,
1057 scale_factor,
1058 is_emoji: false,
1059 };
1060
1061 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
1062 if !raster_bounds.is_zero() {
1063 let tile =
1064 self.window
1065 .sprite_atlas
1066 .get_or_insert_with(¶ms.clone().into(), &mut || {
1067 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
1068 Ok((size, Cow::Owned(bytes)))
1069 })?;
1070 let bounds = Bounds {
1071 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
1072 size: tile.bounds.size.map(Into::into),
1073 };
1074 let content_mask = self.content_mask().scale(scale_factor);
1075 let window = &mut *self.window;
1076 window.next_frame.scene_builder.insert(
1077 &window.next_frame.z_index_stack,
1078 MonochromeSprite {
1079 order: 0,
1080 bounds,
1081 content_mask,
1082 color,
1083 tile,
1084 },
1085 );
1086 }
1087 Ok(())
1088 }
1089
1090 /// Paint an emoji glyph into the scene for the next frame at the current z-index.
1091 /// The y component of the origin is the baseline of the glyph.
1092 pub fn paint_emoji(
1093 &mut self,
1094 origin: Point<Pixels>,
1095 font_id: FontId,
1096 glyph_id: GlyphId,
1097 font_size: Pixels,
1098 ) -> Result<()> {
1099 let scale_factor = self.scale_factor();
1100 let glyph_origin = origin.scale(scale_factor);
1101 let params = RenderGlyphParams {
1102 font_id,
1103 glyph_id,
1104 font_size,
1105 // We don't render emojis with subpixel variants.
1106 subpixel_variant: Default::default(),
1107 scale_factor,
1108 is_emoji: true,
1109 };
1110
1111 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
1112 if !raster_bounds.is_zero() {
1113 let tile =
1114 self.window
1115 .sprite_atlas
1116 .get_or_insert_with(¶ms.clone().into(), &mut || {
1117 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
1118 Ok((size, Cow::Owned(bytes)))
1119 })?;
1120 let bounds = Bounds {
1121 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
1122 size: tile.bounds.size.map(Into::into),
1123 };
1124 let content_mask = self.content_mask().scale(scale_factor);
1125 let window = &mut *self.window;
1126
1127 window.next_frame.scene_builder.insert(
1128 &window.next_frame.z_index_stack,
1129 PolychromeSprite {
1130 order: 0,
1131 bounds,
1132 corner_radii: Default::default(),
1133 content_mask,
1134 tile,
1135 grayscale: false,
1136 },
1137 );
1138 }
1139 Ok(())
1140 }
1141
1142 /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
1143 pub fn paint_svg(
1144 &mut self,
1145 bounds: Bounds<Pixels>,
1146 path: SharedString,
1147 color: Hsla,
1148 ) -> Result<()> {
1149 let scale_factor = self.scale_factor();
1150 let bounds = bounds.scale(scale_factor);
1151 // Render the SVG at twice the size to get a higher quality result.
1152 let params = RenderSvgParams {
1153 path,
1154 size: bounds
1155 .size
1156 .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
1157 };
1158
1159 let tile =
1160 self.window
1161 .sprite_atlas
1162 .get_or_insert_with(¶ms.clone().into(), &mut || {
1163 let bytes = self.svg_renderer.render(¶ms)?;
1164 Ok((params.size, Cow::Owned(bytes)))
1165 })?;
1166 let content_mask = self.content_mask().scale(scale_factor);
1167
1168 let window = &mut *self.window;
1169 window.next_frame.scene_builder.insert(
1170 &window.next_frame.z_index_stack,
1171 MonochromeSprite {
1172 order: 0,
1173 bounds,
1174 content_mask,
1175 color,
1176 tile,
1177 },
1178 );
1179
1180 Ok(())
1181 }
1182
1183 /// Paint an image into the scene for the next frame at the current z-index.
1184 pub fn paint_image(
1185 &mut self,
1186 bounds: Bounds<Pixels>,
1187 corner_radii: Corners<Pixels>,
1188 data: Arc<ImageData>,
1189 grayscale: bool,
1190 ) -> Result<()> {
1191 let scale_factor = self.scale_factor();
1192 let bounds = bounds.scale(scale_factor);
1193 let params = RenderImageParams { image_id: data.id };
1194
1195 let tile = self
1196 .window
1197 .sprite_atlas
1198 .get_or_insert_with(¶ms.clone().into(), &mut || {
1199 Ok((data.size(), Cow::Borrowed(data.as_bytes())))
1200 })?;
1201 let content_mask = self.content_mask().scale(scale_factor);
1202 let corner_radii = corner_radii.scale(scale_factor);
1203
1204 let window = &mut *self.window;
1205 window.next_frame.scene_builder.insert(
1206 &window.next_frame.z_index_stack,
1207 PolychromeSprite {
1208 order: 0,
1209 bounds,
1210 content_mask,
1211 corner_radii,
1212 tile,
1213 grayscale,
1214 },
1215 );
1216 Ok(())
1217 }
1218
1219 /// Paint a surface into the scene for the next frame at the current z-index.
1220 pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
1221 let scale_factor = self.scale_factor();
1222 let bounds = bounds.scale(scale_factor);
1223 let content_mask = self.content_mask().scale(scale_factor);
1224 let window = &mut *self.window;
1225 window.next_frame.scene_builder.insert(
1226 &window.next_frame.z_index_stack,
1227 Surface {
1228 order: 0,
1229 bounds,
1230 content_mask,
1231 image_buffer,
1232 },
1233 );
1234 }
1235
1236 /// Draw pixels to the display for this window based on the contents of its scene.
1237 pub(crate) fn draw(&mut self) -> Scene {
1238 self.text_system().start_frame();
1239 self.window.platform_window.clear_input_handler();
1240 self.window.layout_engine.as_mut().unwrap().clear();
1241 self.window.next_frame.clear();
1242 let root_view = self.window.root_view.take().unwrap();
1243
1244 self.with_z_index(0, |cx| {
1245 cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| {
1246 for (action_type, action_listeners) in &cx.app.global_action_listeners {
1247 for action_listener in action_listeners.iter().cloned() {
1248 cx.window.next_frame.dispatch_tree.on_action(
1249 *action_type,
1250 Rc::new(move |action, phase, cx| action_listener(action, phase, cx)),
1251 )
1252 }
1253 }
1254
1255 let available_space = cx.window.viewport_size.map(Into::into);
1256 root_view.draw(Point::default(), available_space, cx);
1257 })
1258 });
1259
1260 if let Some(active_drag) = self.app.active_drag.take() {
1261 self.with_z_index(ACTIVE_DRAG_Z_INDEX, |cx| {
1262 let offset = cx.mouse_position() - active_drag.cursor_offset;
1263 let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
1264 active_drag.view.draw(offset, available_space, cx);
1265 });
1266 self.active_drag = Some(active_drag);
1267 } else if let Some(active_tooltip) = self.app.active_tooltip.take() {
1268 self.with_z_index(1, |cx| {
1269 let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
1270 active_tooltip
1271 .view
1272 .draw(active_tooltip.cursor_offset, available_space, cx);
1273 });
1274 }
1275
1276 self.window
1277 .next_frame
1278 .dispatch_tree
1279 .preserve_pending_keystrokes(
1280 &mut self.window.rendered_frame.dispatch_tree,
1281 self.window.focus,
1282 );
1283 self.window.root_view = Some(root_view);
1284
1285 let window = &mut self.window;
1286 mem::swap(&mut window.rendered_frame, &mut window.next_frame);
1287
1288 let scene = self.window.rendered_frame.scene_builder.build();
1289 let cursor_style = self
1290 .window
1291 .requested_cursor_style
1292 .take()
1293 .unwrap_or(CursorStyle::Arrow);
1294 self.platform.set_cursor_style(cursor_style);
1295 self.window.dirty = false;
1296
1297 scene
1298 }
1299
1300 /// Dispatch a mouse or keyboard event on the window.
1301 pub fn dispatch_event(&mut self, event: InputEvent) -> bool {
1302 // Handlers may set this to false by calling `stop_propagation`
1303 self.app.propagate_event = true;
1304 self.window.default_prevented = false;
1305
1306 let event = match event {
1307 // Track the mouse position with our own state, since accessing the platform
1308 // API for the mouse position can only occur on the main thread.
1309 InputEvent::MouseMove(mouse_move) => {
1310 self.window.mouse_position = mouse_move.position;
1311 InputEvent::MouseMove(mouse_move)
1312 }
1313 InputEvent::MouseDown(mouse_down) => {
1314 self.window.mouse_position = mouse_down.position;
1315 InputEvent::MouseDown(mouse_down)
1316 }
1317 InputEvent::MouseUp(mouse_up) => {
1318 self.window.mouse_position = mouse_up.position;
1319 InputEvent::MouseUp(mouse_up)
1320 }
1321 // Translate dragging and dropping of external files from the operating system
1322 // to internal drag and drop events.
1323 InputEvent::FileDrop(file_drop) => match file_drop {
1324 FileDropEvent::Entered { position, files } => {
1325 self.window.mouse_position = position;
1326 if self.active_drag.is_none() {
1327 self.active_drag = Some(AnyDrag {
1328 view: self.build_view(|_| files).into(),
1329 cursor_offset: position,
1330 });
1331 }
1332 InputEvent::MouseMove(MouseMoveEvent {
1333 position,
1334 pressed_button: Some(MouseButton::Left),
1335 modifiers: Modifiers::default(),
1336 })
1337 }
1338 FileDropEvent::Pending { position } => {
1339 self.window.mouse_position = position;
1340 InputEvent::MouseMove(MouseMoveEvent {
1341 position,
1342 pressed_button: Some(MouseButton::Left),
1343 modifiers: Modifiers::default(),
1344 })
1345 }
1346 FileDropEvent::Submit { position } => {
1347 self.activate(true);
1348 self.window.mouse_position = position;
1349 InputEvent::MouseUp(MouseUpEvent {
1350 button: MouseButton::Left,
1351 position,
1352 modifiers: Modifiers::default(),
1353 click_count: 1,
1354 })
1355 }
1356 FileDropEvent::Exited => InputEvent::MouseUp(MouseUpEvent {
1357 button: MouseButton::Left,
1358 position: Point::default(),
1359 modifiers: Modifiers::default(),
1360 click_count: 1,
1361 }),
1362 },
1363 _ => event,
1364 };
1365
1366 if let Some(any_mouse_event) = event.mouse_event() {
1367 self.dispatch_mouse_event(any_mouse_event);
1368 } else if let Some(any_key_event) = event.keyboard_event() {
1369 self.dispatch_key_event(any_key_event);
1370 }
1371
1372 !self.app.propagate_event
1373 }
1374
1375 fn dispatch_mouse_event(&mut self, event: &dyn Any) {
1376 if let Some(mut handlers) = self
1377 .window
1378 .rendered_frame
1379 .mouse_listeners
1380 .remove(&event.type_id())
1381 {
1382 // Because handlers may add other handlers, we sort every time.
1383 handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
1384
1385 // Capture phase, events bubble from back to front. Handlers for this phase are used for
1386 // special purposes, such as detecting events outside of a given Bounds.
1387 for (_, handler) in &mut handlers {
1388 handler(event, DispatchPhase::Capture, self);
1389 if !self.app.propagate_event {
1390 break;
1391 }
1392 }
1393
1394 // Bubble phase, where most normal handlers do their work.
1395 if self.app.propagate_event {
1396 for (_, handler) in handlers.iter_mut().rev() {
1397 handler(event, DispatchPhase::Bubble, self);
1398 if !self.app.propagate_event {
1399 break;
1400 }
1401 }
1402 }
1403
1404 if self.app.propagate_event && event.downcast_ref::<MouseUpEvent>().is_some() {
1405 self.active_drag = None;
1406 }
1407
1408 self.window
1409 .rendered_frame
1410 .mouse_listeners
1411 .insert(event.type_id(), handlers);
1412 }
1413 }
1414
1415 fn dispatch_key_event(&mut self, event: &dyn Any) {
1416 let node_id = self
1417 .window
1418 .focus
1419 .and_then(|focus_id| {
1420 self.window
1421 .rendered_frame
1422 .dispatch_tree
1423 .focusable_node_id(focus_id)
1424 })
1425 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1426
1427 let dispatch_path = self
1428 .window
1429 .rendered_frame
1430 .dispatch_tree
1431 .dispatch_path(node_id);
1432
1433 let mut actions: Vec<Box<dyn Action>> = Vec::new();
1434
1435 // Capture phase
1436 let mut context_stack: SmallVec<[KeyContext; 16]> = SmallVec::new();
1437 self.propagate_event = true;
1438
1439 for node_id in &dispatch_path {
1440 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1441
1442 if let Some(context) = node.context.clone() {
1443 context_stack.push(context);
1444 }
1445
1446 for key_listener in node.key_listeners.clone() {
1447 key_listener(event, DispatchPhase::Capture, self);
1448 if !self.propagate_event {
1449 return;
1450 }
1451 }
1452 }
1453
1454 // Bubble phase
1455 for node_id in dispatch_path.iter().rev() {
1456 // Handle low level key events
1457 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1458 for key_listener in node.key_listeners.clone() {
1459 key_listener(event, DispatchPhase::Bubble, self);
1460 if !self.propagate_event {
1461 return;
1462 }
1463 }
1464
1465 // Match keystrokes
1466 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1467 if node.context.is_some() {
1468 if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
1469 let mut new_actions = self
1470 .window
1471 .rendered_frame
1472 .dispatch_tree
1473 .dispatch_key(&key_down_event.keystroke, &context_stack);
1474 actions.append(&mut new_actions);
1475 }
1476
1477 context_stack.pop();
1478 }
1479 }
1480
1481 for action in actions {
1482 self.dispatch_action_on_node(node_id, action.boxed_clone());
1483 if !self.propagate_event {
1484 self.dispatch_keystroke_observers(event, Some(action));
1485 return;
1486 }
1487 }
1488 self.dispatch_keystroke_observers(event, None);
1489 }
1490
1491 pub fn has_pending_keystrokes(&self) -> bool {
1492 self.window
1493 .rendered_frame
1494 .dispatch_tree
1495 .has_pending_keystrokes()
1496 }
1497
1498 fn dispatch_action_on_node(&mut self, node_id: DispatchNodeId, action: Box<dyn Action>) {
1499 let dispatch_path = self
1500 .window
1501 .rendered_frame
1502 .dispatch_tree
1503 .dispatch_path(node_id);
1504
1505 // Capture phase
1506 for node_id in &dispatch_path {
1507 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1508 for DispatchActionListener {
1509 action_type,
1510 listener,
1511 } in node.action_listeners.clone()
1512 {
1513 let any_action = action.as_any();
1514 if action_type == any_action.type_id() {
1515 listener(any_action, DispatchPhase::Capture, self);
1516 if !self.propagate_event {
1517 return;
1518 }
1519 }
1520 }
1521 }
1522 // Bubble phase
1523 for node_id in dispatch_path.iter().rev() {
1524 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1525 for DispatchActionListener {
1526 action_type,
1527 listener,
1528 } in node.action_listeners.clone()
1529 {
1530 let any_action = action.as_any();
1531 if action_type == any_action.type_id() {
1532 self.propagate_event = false; // Actions stop propagation by default during the bubble phase
1533 listener(any_action, DispatchPhase::Bubble, self);
1534 if !self.propagate_event {
1535 return;
1536 }
1537 }
1538 }
1539 }
1540 }
1541
1542 /// Register the given handler to be invoked whenever the global of the given type
1543 /// is updated.
1544 pub fn observe_global<G: 'static>(
1545 &mut self,
1546 f: impl Fn(&mut WindowContext<'_>) + 'static,
1547 ) -> Subscription {
1548 let window_handle = self.window.handle;
1549 let (subscription, activate) = self.global_observers.insert(
1550 TypeId::of::<G>(),
1551 Box::new(move |cx| window_handle.update(cx, |_, cx| f(cx)).is_ok()),
1552 );
1553 self.app.defer(move |_| activate());
1554 subscription
1555 }
1556
1557 pub fn activate_window(&self) {
1558 self.window.platform_window.activate();
1559 }
1560
1561 pub fn minimize_window(&self) {
1562 self.window.platform_window.minimize();
1563 }
1564
1565 pub fn toggle_full_screen(&self) {
1566 self.window.platform_window.toggle_full_screen();
1567 }
1568
1569 pub fn prompt(
1570 &self,
1571 level: PromptLevel,
1572 msg: &str,
1573 answers: &[&str],
1574 ) -> oneshot::Receiver<usize> {
1575 self.window.platform_window.prompt(level, msg, answers)
1576 }
1577
1578 pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
1579 let node_id = self
1580 .window
1581 .focus
1582 .and_then(|focus_id| {
1583 self.window
1584 .rendered_frame
1585 .dispatch_tree
1586 .focusable_node_id(focus_id)
1587 })
1588 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1589
1590 self.window
1591 .rendered_frame
1592 .dispatch_tree
1593 .available_actions(node_id)
1594 }
1595
1596 pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
1597 self.window
1598 .rendered_frame
1599 .dispatch_tree
1600 .bindings_for_action(
1601 action,
1602 &self.window.rendered_frame.dispatch_tree.context_stack,
1603 )
1604 }
1605
1606 pub fn bindings_for_action_in(
1607 &self,
1608 action: &dyn Action,
1609 focus_handle: &FocusHandle,
1610 ) -> Vec<KeyBinding> {
1611 let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
1612
1613 let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) else {
1614 return vec![];
1615 };
1616 let context_stack = dispatch_tree
1617 .dispatch_path(node_id)
1618 .into_iter()
1619 .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
1620 .collect();
1621 dispatch_tree.bindings_for_action(action, &context_stack)
1622 }
1623
1624 pub fn listener_for<V: Render, E>(
1625 &self,
1626 view: &View<V>,
1627 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
1628 ) -> impl Fn(&E, &mut WindowContext) + 'static {
1629 let view = view.downgrade();
1630 move |e: &E, cx: &mut WindowContext| {
1631 view.update(cx, |view, cx| f(view, e, cx)).ok();
1632 }
1633 }
1634
1635 pub fn handler_for<V: Render>(
1636 &self,
1637 view: &View<V>,
1638 f: impl Fn(&mut V, &mut ViewContext<V>) + 'static,
1639 ) -> impl Fn(&mut WindowContext) {
1640 let view = view.downgrade();
1641 move |cx: &mut WindowContext| {
1642 view.update(cx, |view, cx| f(view, cx)).ok();
1643 }
1644 }
1645
1646 //========== ELEMENT RELATED FUNCTIONS ===========
1647 pub fn with_key_dispatch<R>(
1648 &mut self,
1649 context: Option<KeyContext>,
1650 focus_handle: Option<FocusHandle>,
1651 f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
1652 ) -> R {
1653 let window = &mut self.window;
1654 window.next_frame.dispatch_tree.push_node(context.clone());
1655 if let Some(focus_handle) = focus_handle.as_ref() {
1656 window
1657 .next_frame
1658 .dispatch_tree
1659 .make_focusable(focus_handle.id);
1660 }
1661 let result = f(focus_handle, self);
1662
1663 self.window.next_frame.dispatch_tree.pop_node();
1664
1665 result
1666 }
1667
1668 /// Register a focus listener for the next frame only. It will be cleared
1669 /// on the next frame render. You should use this method only from within elements,
1670 /// and we may want to enforce that better via a different context type.
1671 // todo!() Move this to `FrameContext` to emphasize its individuality?
1672 pub fn on_focus_changed(
1673 &mut self,
1674 listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static,
1675 ) {
1676 self.window
1677 .next_frame
1678 .focus_listeners
1679 .push(Box::new(move |event, cx| {
1680 listener(event, cx);
1681 }));
1682 }
1683
1684 /// Set an input handler, such as [ElementInputHandler], which interfaces with the
1685 /// platform to receive textual input with proper integration with concerns such
1686 /// as IME interactions.
1687 pub fn handle_input(
1688 &mut self,
1689 focus_handle: &FocusHandle,
1690 input_handler: impl PlatformInputHandler,
1691 ) {
1692 if focus_handle.is_focused(self) {
1693 self.window
1694 .platform_window
1695 .set_input_handler(Box::new(input_handler));
1696 }
1697 }
1698
1699 pub fn on_window_should_close(&mut self, f: impl Fn(&mut WindowContext) -> bool + 'static) {
1700 let mut this = self.to_async();
1701 self.window
1702 .platform_window
1703 .on_should_close(Box::new(move || this.update(|_, cx| f(cx)).unwrap_or(true)))
1704 }
1705}
1706
1707impl Context for WindowContext<'_> {
1708 type Result<T> = T;
1709
1710 fn build_model<T>(
1711 &mut self,
1712 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
1713 ) -> Model<T>
1714 where
1715 T: 'static,
1716 {
1717 let slot = self.app.entities.reserve();
1718 let model = build_model(&mut ModelContext::new(&mut *self.app, slot.downgrade()));
1719 self.entities.insert(slot, model)
1720 }
1721
1722 fn update_model<T: 'static, R>(
1723 &mut self,
1724 model: &Model<T>,
1725 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
1726 ) -> R {
1727 let mut entity = self.entities.lease(model);
1728 let result = update(
1729 &mut *entity,
1730 &mut ModelContext::new(&mut *self.app, model.downgrade()),
1731 );
1732 self.entities.end_lease(entity);
1733 result
1734 }
1735
1736 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
1737 where
1738 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
1739 {
1740 if window == self.window.handle {
1741 let root_view = self.window.root_view.clone().unwrap();
1742 Ok(update(root_view, self))
1743 } else {
1744 window.update(self.app, update)
1745 }
1746 }
1747
1748 fn read_model<T, R>(
1749 &self,
1750 handle: &Model<T>,
1751 read: impl FnOnce(&T, &AppContext) -> R,
1752 ) -> Self::Result<R>
1753 where
1754 T: 'static,
1755 {
1756 let entity = self.entities.read(handle);
1757 read(&*entity, &*self.app)
1758 }
1759
1760 fn read_window<T, R>(
1761 &self,
1762 window: &WindowHandle<T>,
1763 read: impl FnOnce(View<T>, &AppContext) -> R,
1764 ) -> Result<R>
1765 where
1766 T: 'static,
1767 {
1768 if window.any_handle == self.window.handle {
1769 let root_view = self
1770 .window
1771 .root_view
1772 .clone()
1773 .unwrap()
1774 .downcast::<T>()
1775 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
1776 Ok(read(root_view, self))
1777 } else {
1778 self.app.read_window(window, read)
1779 }
1780 }
1781}
1782
1783impl VisualContext for WindowContext<'_> {
1784 fn build_view<V>(
1785 &mut self,
1786 build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
1787 ) -> Self::Result<View<V>>
1788 where
1789 V: 'static + Render,
1790 {
1791 let slot = self.app.entities.reserve();
1792 let view = View {
1793 model: slot.clone(),
1794 };
1795 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
1796 let entity = build_view_state(&mut cx);
1797 cx.entities.insert(slot, entity);
1798
1799 cx.new_view_observers
1800 .clone()
1801 .retain(&TypeId::of::<V>(), |observer| {
1802 let any_view = AnyView::from(view.clone());
1803 (observer)(any_view, self);
1804 true
1805 });
1806
1807 view
1808 }
1809
1810 /// Update the given view. Prefer calling `View::update` instead, which calls this method.
1811 fn update_view<T: 'static, R>(
1812 &mut self,
1813 view: &View<T>,
1814 update: impl FnOnce(&mut T, &mut ViewContext<'_, T>) -> R,
1815 ) -> Self::Result<R> {
1816 let mut lease = self.app.entities.lease(&view.model);
1817 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
1818 let result = update(&mut *lease, &mut cx);
1819 cx.app.entities.end_lease(lease);
1820 result
1821 }
1822
1823 fn replace_root_view<V>(
1824 &mut self,
1825 build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
1826 ) -> Self::Result<View<V>>
1827 where
1828 V: 'static + Render,
1829 {
1830 let slot = self.app.entities.reserve();
1831 let view = View {
1832 model: slot.clone(),
1833 };
1834 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
1835 let entity = build_view(&mut cx);
1836 self.entities.insert(slot, entity);
1837 self.window.root_view = Some(view.clone().into());
1838 view
1839 }
1840
1841 fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
1842 self.update_view(view, |view, cx| {
1843 view.focus_handle(cx).clone().focus(cx);
1844 })
1845 }
1846
1847 fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
1848 where
1849 V: ManagedView,
1850 {
1851 self.update_view(view, |_, cx| cx.emit(DismissEvent))
1852 }
1853}
1854
1855impl<'a> std::ops::Deref for WindowContext<'a> {
1856 type Target = AppContext;
1857
1858 fn deref(&self) -> &Self::Target {
1859 &self.app
1860 }
1861}
1862
1863impl<'a> std::ops::DerefMut for WindowContext<'a> {
1864 fn deref_mut(&mut self) -> &mut Self::Target {
1865 &mut self.app
1866 }
1867}
1868
1869impl<'a> Borrow<AppContext> for WindowContext<'a> {
1870 fn borrow(&self) -> &AppContext {
1871 &self.app
1872 }
1873}
1874
1875impl<'a> BorrowMut<AppContext> for WindowContext<'a> {
1876 fn borrow_mut(&mut self) -> &mut AppContext {
1877 &mut self.app
1878 }
1879}
1880
1881pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
1882 fn app_mut(&mut self) -> &mut AppContext {
1883 self.borrow_mut()
1884 }
1885
1886 fn app(&self) -> &AppContext {
1887 self.borrow()
1888 }
1889
1890 fn window(&self) -> &Window {
1891 self.borrow()
1892 }
1893
1894 fn window_mut(&mut self) -> &mut Window {
1895 self.borrow_mut()
1896 }
1897
1898 /// Pushes the given element id onto the global stack and invokes the given closure
1899 /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
1900 /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
1901 /// used to associate state with identified elements across separate frames.
1902 fn with_element_id<R>(
1903 &mut self,
1904 id: Option<impl Into<ElementId>>,
1905 f: impl FnOnce(&mut Self) -> R,
1906 ) -> R {
1907 if let Some(id) = id.map(Into::into) {
1908 let window = self.window_mut();
1909 window.element_id_stack.push(id.into());
1910 let result = f(self);
1911 let window: &mut Window = self.borrow_mut();
1912 window.element_id_stack.pop();
1913 result
1914 } else {
1915 f(self)
1916 }
1917 }
1918
1919 /// Invoke the given function with the given content mask after intersecting it
1920 /// with the current mask.
1921 fn with_content_mask<R>(
1922 &mut self,
1923 mask: Option<ContentMask<Pixels>>,
1924 f: impl FnOnce(&mut Self) -> R,
1925 ) -> R {
1926 if let Some(mask) = mask {
1927 let mask = mask.intersect(&self.content_mask());
1928 self.window_mut().next_frame.content_mask_stack.push(mask);
1929 let result = f(self);
1930 self.window_mut().next_frame.content_mask_stack.pop();
1931 result
1932 } else {
1933 f(self)
1934 }
1935 }
1936
1937 /// Invoke the given function with the content mask reset to that
1938 /// of the window.
1939 fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
1940 let mask = ContentMask {
1941 bounds: Bounds {
1942 origin: Point::default(),
1943 size: self.window().viewport_size,
1944 },
1945 };
1946 self.window_mut().next_frame.content_mask_stack.push(mask);
1947 let result = f(self);
1948 self.window_mut().next_frame.content_mask_stack.pop();
1949 result
1950 }
1951
1952 /// Update the global element offset relative to the current offset. This is used to implement
1953 /// scrolling.
1954 fn with_element_offset<R>(
1955 &mut self,
1956 offset: Point<Pixels>,
1957 f: impl FnOnce(&mut Self) -> R,
1958 ) -> R {
1959 if offset.is_zero() {
1960 return f(self);
1961 };
1962
1963 let abs_offset = self.element_offset() + offset;
1964 self.with_absolute_element_offset(abs_offset, f)
1965 }
1966
1967 /// Update the global element offset based on the given offset. This is used to implement
1968 /// drag handles and other manual painting of elements.
1969 fn with_absolute_element_offset<R>(
1970 &mut self,
1971 offset: Point<Pixels>,
1972 f: impl FnOnce(&mut Self) -> R,
1973 ) -> R {
1974 self.window_mut()
1975 .next_frame
1976 .element_offset_stack
1977 .push(offset);
1978 let result = f(self);
1979 self.window_mut().next_frame.element_offset_stack.pop();
1980 result
1981 }
1982
1983 /// Obtain the current element offset.
1984 fn element_offset(&self) -> Point<Pixels> {
1985 self.window()
1986 .next_frame
1987 .element_offset_stack
1988 .last()
1989 .copied()
1990 .unwrap_or_default()
1991 }
1992
1993 /// Update or initialize state for an element with the given id that lives across multiple
1994 /// frames. If an element with this id existed in the rendered frame, its state will be passed
1995 /// to the given closure. The state returned by the closure will be stored so it can be referenced
1996 /// when drawing the next frame.
1997 fn with_element_state<S, R>(
1998 &mut self,
1999 id: ElementId,
2000 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
2001 ) -> R
2002 where
2003 S: 'static,
2004 {
2005 self.with_element_id(Some(id), |cx| {
2006 let global_id = cx.window().element_id_stack.clone();
2007
2008 if let Some(any) = cx
2009 .window_mut()
2010 .next_frame
2011 .element_states
2012 .remove(&global_id)
2013 .or_else(|| {
2014 cx.window_mut()
2015 .rendered_frame
2016 .element_states
2017 .remove(&global_id)
2018 })
2019 {
2020 let ElementStateBox {
2021 inner,
2022
2023 #[cfg(debug_assertions)]
2024 type_name
2025 } = any;
2026 // Using the extra inner option to avoid needing to reallocate a new box.
2027 let mut state_box = inner
2028 .downcast::<Option<S>>()
2029 .map_err(|_| {
2030 #[cfg(debug_assertions)]
2031 {
2032 anyhow!(
2033 "invalid element state type for id, requested_type {:?}, actual type: {:?}",
2034 std::any::type_name::<S>(),
2035 type_name
2036 )
2037 }
2038
2039 #[cfg(not(debug_assertions))]
2040 {
2041 anyhow!(
2042 "invalid element state type for id, requested_type {:?}",
2043 std::any::type_name::<S>(),
2044 )
2045 }
2046 })
2047 .unwrap();
2048
2049 // Actual: Option<AnyElement> <- View
2050 // Requested: () <- AnyElemet
2051 let state = state_box
2052 .take()
2053 .expect("element state is already on the stack");
2054 let (result, state) = f(Some(state), cx);
2055 state_box.replace(state);
2056 cx.window_mut()
2057 .next_frame
2058 .element_states
2059 .insert(global_id, ElementStateBox {
2060 inner: state_box,
2061
2062 #[cfg(debug_assertions)]
2063 type_name
2064 });
2065 result
2066 } else {
2067 let (result, state) = f(None, cx);
2068 cx.window_mut()
2069 .next_frame
2070 .element_states
2071 .insert(global_id,
2072 ElementStateBox {
2073 inner: Box::new(Some(state)),
2074
2075 #[cfg(debug_assertions)]
2076 type_name: std::any::type_name::<S>()
2077 }
2078
2079 );
2080 result
2081 }
2082 })
2083 }
2084
2085 /// Obtain the current content mask.
2086 fn content_mask(&self) -> ContentMask<Pixels> {
2087 self.window()
2088 .next_frame
2089 .content_mask_stack
2090 .last()
2091 .cloned()
2092 .unwrap_or_else(|| ContentMask {
2093 bounds: Bounds {
2094 origin: Point::default(),
2095 size: self.window().viewport_size,
2096 },
2097 })
2098 }
2099
2100 /// The size of an em for the base font of the application. Adjusting this value allows the
2101 /// UI to scale, just like zooming a web page.
2102 fn rem_size(&self) -> Pixels {
2103 self.window().rem_size
2104 }
2105}
2106
2107impl Borrow<Window> for WindowContext<'_> {
2108 fn borrow(&self) -> &Window {
2109 &self.window
2110 }
2111}
2112
2113impl BorrowMut<Window> for WindowContext<'_> {
2114 fn borrow_mut(&mut self) -> &mut Window {
2115 &mut self.window
2116 }
2117}
2118
2119impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
2120
2121pub struct ViewContext<'a, V> {
2122 window_cx: WindowContext<'a>,
2123 view: &'a View<V>,
2124}
2125
2126impl<V> Borrow<AppContext> for ViewContext<'_, V> {
2127 fn borrow(&self) -> &AppContext {
2128 &*self.window_cx.app
2129 }
2130}
2131
2132impl<V> BorrowMut<AppContext> for ViewContext<'_, V> {
2133 fn borrow_mut(&mut self) -> &mut AppContext {
2134 &mut *self.window_cx.app
2135 }
2136}
2137
2138impl<V> Borrow<Window> for ViewContext<'_, V> {
2139 fn borrow(&self) -> &Window {
2140 &*self.window_cx.window
2141 }
2142}
2143
2144impl<V> BorrowMut<Window> for ViewContext<'_, V> {
2145 fn borrow_mut(&mut self) -> &mut Window {
2146 &mut *self.window_cx.window
2147 }
2148}
2149
2150impl<'a, V: 'static> ViewContext<'a, V> {
2151 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window, view: &'a View<V>) -> Self {
2152 Self {
2153 window_cx: WindowContext::new(app, window),
2154 view,
2155 }
2156 }
2157
2158 pub fn entity_id(&self) -> EntityId {
2159 self.view.entity_id()
2160 }
2161
2162 pub fn view(&self) -> &View<V> {
2163 self.view
2164 }
2165
2166 pub fn model(&self) -> &Model<V> {
2167 &self.view.model
2168 }
2169
2170 /// Access the underlying window context.
2171 pub fn window_context(&mut self) -> &mut WindowContext<'a> {
2172 &mut self.window_cx
2173 }
2174
2175 pub fn with_z_index<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
2176 self.window.next_frame.z_index_stack.push(z_index);
2177 let result = f(self);
2178 self.window.next_frame.z_index_stack.pop();
2179 result
2180 }
2181
2182 pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static)
2183 where
2184 V: 'static,
2185 {
2186 let view = self.view().clone();
2187 self.window_cx.on_next_frame(move |cx| view.update(cx, f));
2188 }
2189
2190 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
2191 /// that are currently on the stack to be returned to the app.
2192 pub fn defer(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static) {
2193 let view = self.view().downgrade();
2194 self.window_cx.defer(move |cx| {
2195 view.update(cx, f).ok();
2196 });
2197 }
2198
2199 pub fn observe<V2, E>(
2200 &mut self,
2201 entity: &E,
2202 mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, V>) + 'static,
2203 ) -> Subscription
2204 where
2205 V2: 'static,
2206 V: 'static,
2207 E: Entity<V2>,
2208 {
2209 let view = self.view().downgrade();
2210 let entity_id = entity.entity_id();
2211 let entity = entity.downgrade();
2212 let window_handle = self.window.handle;
2213 let (subscription, activate) = self.app.observers.insert(
2214 entity_id,
2215 Box::new(move |cx| {
2216 window_handle
2217 .update(cx, |_, cx| {
2218 if let Some(handle) = E::upgrade_from(&entity) {
2219 view.update(cx, |this, cx| on_notify(this, handle, cx))
2220 .is_ok()
2221 } else {
2222 false
2223 }
2224 })
2225 .unwrap_or(false)
2226 }),
2227 );
2228 self.app.defer(move |_| activate());
2229 subscription
2230 }
2231
2232 pub fn subscribe<V2, E, Evt>(
2233 &mut self,
2234 entity: &E,
2235 mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, V>) + 'static,
2236 ) -> Subscription
2237 where
2238 V2: EventEmitter<Evt>,
2239 E: Entity<V2>,
2240 Evt: 'static,
2241 {
2242 let view = self.view().downgrade();
2243 let entity_id = entity.entity_id();
2244 let handle = entity.downgrade();
2245 let window_handle = self.window.handle;
2246 let (subscription, activate) = self.app.event_listeners.insert(
2247 entity_id,
2248 (
2249 TypeId::of::<Evt>(),
2250 Box::new(move |event, cx| {
2251 window_handle
2252 .update(cx, |_, cx| {
2253 if let Some(handle) = E::upgrade_from(&handle) {
2254 let event = event.downcast_ref().expect("invalid event type");
2255 view.update(cx, |this, cx| on_event(this, handle, event, cx))
2256 .is_ok()
2257 } else {
2258 false
2259 }
2260 })
2261 .unwrap_or(false)
2262 }),
2263 ),
2264 );
2265 self.app.defer(move |_| activate());
2266 subscription
2267 }
2268
2269 pub fn on_release(
2270 &mut self,
2271 on_release: impl FnOnce(&mut V, &mut WindowContext) + 'static,
2272 ) -> Subscription {
2273 let window_handle = self.window.handle;
2274 let (subscription, activate) = self.app.release_listeners.insert(
2275 self.view.model.entity_id,
2276 Box::new(move |this, cx| {
2277 let this = this.downcast_mut().expect("invalid entity type");
2278 let _ = window_handle.update(cx, |_, cx| on_release(this, cx));
2279 }),
2280 );
2281 activate();
2282 subscription
2283 }
2284
2285 pub fn observe_release<V2, E>(
2286 &mut self,
2287 entity: &E,
2288 mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, V>) + 'static,
2289 ) -> Subscription
2290 where
2291 V: 'static,
2292 V2: 'static,
2293 E: Entity<V2>,
2294 {
2295 let view = self.view().downgrade();
2296 let entity_id = entity.entity_id();
2297 let window_handle = self.window.handle;
2298 let (subscription, activate) = self.app.release_listeners.insert(
2299 entity_id,
2300 Box::new(move |entity, cx| {
2301 let entity = entity.downcast_mut().expect("invalid entity type");
2302 let _ = window_handle.update(cx, |_, cx| {
2303 view.update(cx, |this, cx| on_release(this, entity, cx))
2304 });
2305 }),
2306 );
2307 activate();
2308 subscription
2309 }
2310
2311 pub fn notify(&mut self) {
2312 self.window_cx.notify();
2313 self.window_cx.app.push_effect(Effect::Notify {
2314 emitter: self.view.model.entity_id,
2315 });
2316 }
2317
2318 pub fn observe_window_bounds(
2319 &mut self,
2320 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2321 ) -> Subscription {
2322 let view = self.view.downgrade();
2323 let (subscription, activate) = self.window.bounds_observers.insert(
2324 (),
2325 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2326 );
2327 activate();
2328 subscription
2329 }
2330
2331 pub fn observe_window_activation(
2332 &mut self,
2333 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2334 ) -> Subscription {
2335 let view = self.view.downgrade();
2336 let (subscription, activate) = self.window.activation_observers.insert(
2337 (),
2338 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2339 );
2340 activate();
2341 subscription
2342 }
2343
2344 /// Register a listener to be called when the given focus handle receives focus.
2345 /// Unlike [on_focus_changed], returns a subscription and persists until the subscription
2346 /// is dropped.
2347 pub fn on_focus(
2348 &mut self,
2349 handle: &FocusHandle,
2350 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2351 ) -> Subscription {
2352 let view = self.view.downgrade();
2353 let focus_id = handle.id;
2354 let (subscription, activate) = self.window.focus_listeners.insert(
2355 (),
2356 Box::new(move |event, cx| {
2357 view.update(cx, |view, cx| {
2358 if event.focused.as_ref().map(|focused| focused.id) == Some(focus_id) {
2359 listener(view, cx)
2360 }
2361 })
2362 .is_ok()
2363 }),
2364 );
2365 self.app.defer(move |_| activate());
2366 subscription
2367 }
2368
2369 /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
2370 /// Unlike [on_focus_changed], returns a subscription and persists until the subscription
2371 /// is dropped.
2372 pub fn on_focus_in(
2373 &mut self,
2374 handle: &FocusHandle,
2375 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2376 ) -> Subscription {
2377 let view = self.view.downgrade();
2378 let focus_id = handle.id;
2379 let (subscription, activate) = self.window.focus_listeners.insert(
2380 (),
2381 Box::new(move |event, cx| {
2382 view.update(cx, |view, cx| {
2383 if event
2384 .focused
2385 .as_ref()
2386 .map_or(false, |focused| focus_id.contains(focused.id, cx))
2387 {
2388 listener(view, cx)
2389 }
2390 })
2391 .is_ok()
2392 }),
2393 );
2394 self.app.defer(move |_| activate());
2395 subscription
2396 }
2397
2398 /// Register a listener to be called when the given focus handle loses focus.
2399 /// Unlike [on_focus_changed], returns a subscription and persists until the subscription
2400 /// is dropped.
2401 pub fn on_blur(
2402 &mut self,
2403 handle: &FocusHandle,
2404 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2405 ) -> Subscription {
2406 let view = self.view.downgrade();
2407 let focus_id = handle.id;
2408 let (subscription, activate) = self.window.focus_listeners.insert(
2409 (),
2410 Box::new(move |event, cx| {
2411 view.update(cx, |view, cx| {
2412 if event.blurred.as_ref().map(|blurred| blurred.id) == Some(focus_id) {
2413 listener(view, cx)
2414 }
2415 })
2416 .is_ok()
2417 }),
2418 );
2419 self.app.defer(move |_| activate());
2420 subscription
2421 }
2422
2423 /// Register a listener to be called when the window loses focus.
2424 /// Unlike [on_focus_changed], returns a subscription and persists until the subscription
2425 /// is dropped.
2426 pub fn on_window_focus_lost(
2427 &mut self,
2428 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2429 ) -> Subscription {
2430 let view = self.view.downgrade();
2431 let (subscription, activate) = self.window.focus_listeners.insert(
2432 (),
2433 Box::new(move |event, cx| {
2434 view.update(cx, |view, cx| {
2435 if event.blurred.is_none() && event.focused.is_none() {
2436 listener(view, cx)
2437 }
2438 })
2439 .is_ok()
2440 }),
2441 );
2442 self.app.defer(move |_| activate());
2443 subscription
2444 }
2445
2446 /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
2447 /// Unlike [on_focus_changed], returns a subscription and persists until the subscription
2448 /// is dropped.
2449 pub fn on_focus_out(
2450 &mut self,
2451 handle: &FocusHandle,
2452 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2453 ) -> Subscription {
2454 let view = self.view.downgrade();
2455 let focus_id = handle.id;
2456 let (subscription, activate) = self.window.focus_listeners.insert(
2457 (),
2458 Box::new(move |event, cx| {
2459 view.update(cx, |view, cx| {
2460 if event
2461 .blurred
2462 .as_ref()
2463 .map_or(false, |blurred| focus_id.contains(blurred.id, cx))
2464 {
2465 listener(view, cx)
2466 }
2467 })
2468 .is_ok()
2469 }),
2470 );
2471 self.app.defer(move |_| activate());
2472 subscription
2473 }
2474
2475 pub fn spawn<Fut, R>(
2476 &mut self,
2477 f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
2478 ) -> Task<R>
2479 where
2480 R: 'static,
2481 Fut: Future<Output = R> + 'static,
2482 {
2483 let view = self.view().downgrade();
2484 self.window_cx.spawn(|cx| f(view, cx))
2485 }
2486
2487 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
2488 where
2489 G: 'static,
2490 {
2491 let mut global = self.app.lease_global::<G>();
2492 let result = f(&mut global, self);
2493 self.app.end_global_lease(global);
2494 result
2495 }
2496
2497 pub fn observe_global<G: 'static>(
2498 &mut self,
2499 mut f: impl FnMut(&mut V, &mut ViewContext<'_, V>) + 'static,
2500 ) -> Subscription {
2501 let window_handle = self.window.handle;
2502 let view = self.view().downgrade();
2503 let (subscription, activate) = self.global_observers.insert(
2504 TypeId::of::<G>(),
2505 Box::new(move |cx| {
2506 window_handle
2507 .update(cx, |_, cx| view.update(cx, |view, cx| f(view, cx)).is_ok())
2508 .unwrap_or(false)
2509 }),
2510 );
2511 self.app.defer(move |_| activate());
2512 subscription
2513 }
2514
2515 pub fn on_mouse_event<Event: 'static>(
2516 &mut self,
2517 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
2518 ) {
2519 let handle = self.view().clone();
2520 self.window_cx.on_mouse_event(move |event, phase, cx| {
2521 handle.update(cx, |view, cx| {
2522 handler(view, event, phase, cx);
2523 })
2524 });
2525 }
2526
2527 pub fn on_key_event<Event: 'static>(
2528 &mut self,
2529 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
2530 ) {
2531 let handle = self.view().clone();
2532 self.window_cx.on_key_event(move |event, phase, cx| {
2533 handle.update(cx, |view, cx| {
2534 handler(view, event, phase, cx);
2535 })
2536 });
2537 }
2538
2539 pub fn on_action(
2540 &mut self,
2541 action_type: TypeId,
2542 handler: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static,
2543 ) {
2544 let handle = self.view().clone();
2545 self.window_cx
2546 .on_action(action_type, move |action, phase, cx| {
2547 handle.update(cx, |view, cx| {
2548 handler(view, action, phase, cx);
2549 })
2550 });
2551 }
2552
2553 pub fn emit<Evt>(&mut self, event: Evt)
2554 where
2555 Evt: 'static,
2556 V: EventEmitter<Evt>,
2557 {
2558 let emitter = self.view.model.entity_id;
2559 self.app.push_effect(Effect::Emit {
2560 emitter,
2561 event_type: TypeId::of::<Evt>(),
2562 event: Box::new(event),
2563 });
2564 }
2565
2566 pub fn focus_self(&mut self)
2567 where
2568 V: FocusableView,
2569 {
2570 self.defer(|view, cx| view.focus_handle(cx).focus(cx))
2571 }
2572
2573 pub fn dismiss_self(&mut self)
2574 where
2575 V: ManagedView,
2576 {
2577 self.defer(|_, cx| cx.emit(DismissEvent))
2578 }
2579
2580 pub fn listener<E>(
2581 &self,
2582 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
2583 ) -> impl Fn(&E, &mut WindowContext) + 'static {
2584 let view = self.view().downgrade();
2585 move |e: &E, cx: &mut WindowContext| {
2586 view.update(cx, |view, cx| f(view, e, cx)).ok();
2587 }
2588 }
2589}
2590
2591impl<V> Context for ViewContext<'_, V> {
2592 type Result<U> = U;
2593
2594 fn build_model<T: 'static>(
2595 &mut self,
2596 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
2597 ) -> Model<T> {
2598 self.window_cx.build_model(build_model)
2599 }
2600
2601 fn update_model<T: 'static, R>(
2602 &mut self,
2603 model: &Model<T>,
2604 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
2605 ) -> R {
2606 self.window_cx.update_model(model, update)
2607 }
2608
2609 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
2610 where
2611 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
2612 {
2613 self.window_cx.update_window(window, update)
2614 }
2615
2616 fn read_model<T, R>(
2617 &self,
2618 handle: &Model<T>,
2619 read: impl FnOnce(&T, &AppContext) -> R,
2620 ) -> Self::Result<R>
2621 where
2622 T: 'static,
2623 {
2624 self.window_cx.read_model(handle, read)
2625 }
2626
2627 fn read_window<T, R>(
2628 &self,
2629 window: &WindowHandle<T>,
2630 read: impl FnOnce(View<T>, &AppContext) -> R,
2631 ) -> Result<R>
2632 where
2633 T: 'static,
2634 {
2635 self.window_cx.read_window(window, read)
2636 }
2637}
2638
2639impl<V: 'static> VisualContext for ViewContext<'_, V> {
2640 fn build_view<W: Render + 'static>(
2641 &mut self,
2642 build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
2643 ) -> Self::Result<View<W>> {
2644 self.window_cx.build_view(build_view_state)
2645 }
2646
2647 fn update_view<V2: 'static, R>(
2648 &mut self,
2649 view: &View<V2>,
2650 update: impl FnOnce(&mut V2, &mut ViewContext<'_, V2>) -> R,
2651 ) -> Self::Result<R> {
2652 self.window_cx.update_view(view, update)
2653 }
2654
2655 fn replace_root_view<W>(
2656 &mut self,
2657 build_view: impl FnOnce(&mut ViewContext<'_, W>) -> W,
2658 ) -> Self::Result<View<W>>
2659 where
2660 W: 'static + Render,
2661 {
2662 self.window_cx.replace_root_view(build_view)
2663 }
2664
2665 fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
2666 self.window_cx.focus_view(view)
2667 }
2668
2669 fn dismiss_view<W: ManagedView>(&mut self, view: &View<W>) -> Self::Result<()> {
2670 self.window_cx.dismiss_view(view)
2671 }
2672}
2673
2674impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
2675 type Target = WindowContext<'a>;
2676
2677 fn deref(&self) -> &Self::Target {
2678 &self.window_cx
2679 }
2680}
2681
2682impl<'a, V> std::ops::DerefMut for ViewContext<'a, V> {
2683 fn deref_mut(&mut self) -> &mut Self::Target {
2684 &mut self.window_cx
2685 }
2686}
2687
2688// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
2689slotmap::new_key_type! { pub struct WindowId; }
2690
2691impl WindowId {
2692 pub fn as_u64(&self) -> u64 {
2693 self.0.as_ffi()
2694 }
2695}
2696
2697#[derive(Deref, DerefMut)]
2698pub struct WindowHandle<V> {
2699 #[deref]
2700 #[deref_mut]
2701 pub(crate) any_handle: AnyWindowHandle,
2702 state_type: PhantomData<V>,
2703}
2704
2705impl<V: 'static + Render> WindowHandle<V> {
2706 pub fn new(id: WindowId) -> Self {
2707 WindowHandle {
2708 any_handle: AnyWindowHandle {
2709 id,
2710 state_type: TypeId::of::<V>(),
2711 },
2712 state_type: PhantomData,
2713 }
2714 }
2715
2716 pub fn root<C>(&self, cx: &mut C) -> Result<View<V>>
2717 where
2718 C: Context,
2719 {
2720 Flatten::flatten(cx.update_window(self.any_handle, |root_view, _| {
2721 root_view
2722 .downcast::<V>()
2723 .map_err(|_| anyhow!("the type of the window's root view has changed"))
2724 }))
2725 }
2726
2727 pub fn update<C, R>(
2728 &self,
2729 cx: &mut C,
2730 update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R,
2731 ) -> Result<R>
2732 where
2733 C: Context,
2734 {
2735 cx.update_window(self.any_handle, |root_view, cx| {
2736 let view = root_view
2737 .downcast::<V>()
2738 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
2739 Ok(cx.update_view(&view, update))
2740 })?
2741 }
2742
2743 pub fn read<'a>(&self, cx: &'a AppContext) -> Result<&'a V> {
2744 let x = cx
2745 .windows
2746 .get(self.id)
2747 .and_then(|window| {
2748 window
2749 .as_ref()
2750 .and_then(|window| window.root_view.clone())
2751 .map(|root_view| root_view.downcast::<V>())
2752 })
2753 .ok_or_else(|| anyhow!("window not found"))?
2754 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
2755
2756 Ok(x.read(cx))
2757 }
2758
2759 pub fn read_with<C, R>(&self, cx: &C, read_with: impl FnOnce(&V, &AppContext) -> R) -> Result<R>
2760 where
2761 C: Context,
2762 {
2763 cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
2764 }
2765
2766 pub fn root_view<C>(&self, cx: &C) -> Result<View<V>>
2767 where
2768 C: Context,
2769 {
2770 cx.read_window(self, |root_view, _cx| root_view.clone())
2771 }
2772
2773 pub fn is_active(&self, cx: &AppContext) -> Option<bool> {
2774 cx.windows
2775 .get(self.id)
2776 .and_then(|window| window.as_ref().map(|window| window.active))
2777 }
2778}
2779
2780impl<V> Copy for WindowHandle<V> {}
2781
2782impl<V> Clone for WindowHandle<V> {
2783 fn clone(&self) -> Self {
2784 WindowHandle {
2785 any_handle: self.any_handle,
2786 state_type: PhantomData,
2787 }
2788 }
2789}
2790
2791impl<V> PartialEq for WindowHandle<V> {
2792 fn eq(&self, other: &Self) -> bool {
2793 self.any_handle == other.any_handle
2794 }
2795}
2796
2797impl<V> Eq for WindowHandle<V> {}
2798
2799impl<V> Hash for WindowHandle<V> {
2800 fn hash<H: Hasher>(&self, state: &mut H) {
2801 self.any_handle.hash(state);
2802 }
2803}
2804
2805impl<V: 'static> Into<AnyWindowHandle> for WindowHandle<V> {
2806 fn into(self) -> AnyWindowHandle {
2807 self.any_handle
2808 }
2809}
2810
2811#[derive(Copy, Clone, PartialEq, Eq, Hash)]
2812pub struct AnyWindowHandle {
2813 pub(crate) id: WindowId,
2814 state_type: TypeId,
2815}
2816
2817impl AnyWindowHandle {
2818 pub fn window_id(&self) -> WindowId {
2819 self.id
2820 }
2821
2822 pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>> {
2823 if TypeId::of::<T>() == self.state_type {
2824 Some(WindowHandle {
2825 any_handle: *self,
2826 state_type: PhantomData,
2827 })
2828 } else {
2829 None
2830 }
2831 }
2832
2833 pub fn update<C, R>(
2834 self,
2835 cx: &mut C,
2836 update: impl FnOnce(AnyView, &mut WindowContext<'_>) -> R,
2837 ) -> Result<R>
2838 where
2839 C: Context,
2840 {
2841 cx.update_window(self, update)
2842 }
2843
2844 pub fn read<T, C, R>(self, cx: &C, read: impl FnOnce(View<T>, &AppContext) -> R) -> Result<R>
2845 where
2846 C: Context,
2847 T: 'static,
2848 {
2849 let view = self
2850 .downcast::<T>()
2851 .context("the type of the window's root view has changed")?;
2852
2853 cx.read_window(&view, read)
2854 }
2855}
2856
2857#[cfg(any(test, feature = "test-support"))]
2858impl From<SmallVec<[u32; 16]>> for StackingOrder {
2859 fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
2860 StackingOrder(small_vec)
2861 }
2862}
2863
2864#[derive(Clone, Debug, Eq, PartialEq, Hash)]
2865pub enum ElementId {
2866 View(EntityId),
2867 Integer(usize),
2868 Name(SharedString),
2869 FocusHandle(FocusId),
2870 NamedInteger(SharedString, usize),
2871}
2872
2873impl ElementId {
2874 pub(crate) fn from_entity_id(entity_id: EntityId) -> Self {
2875 ElementId::View(entity_id)
2876 }
2877}
2878
2879impl TryInto<SharedString> for ElementId {
2880 type Error = anyhow::Error;
2881
2882 fn try_into(self) -> anyhow::Result<SharedString> {
2883 if let ElementId::Name(name) = self {
2884 Ok(name)
2885 } else {
2886 Err(anyhow!("element id is not string"))
2887 }
2888 }
2889}
2890
2891impl From<usize> for ElementId {
2892 fn from(id: usize) -> Self {
2893 ElementId::Integer(id)
2894 }
2895}
2896
2897impl From<i32> for ElementId {
2898 fn from(id: i32) -> Self {
2899 Self::Integer(id as usize)
2900 }
2901}
2902
2903impl From<SharedString> for ElementId {
2904 fn from(name: SharedString) -> Self {
2905 ElementId::Name(name)
2906 }
2907}
2908
2909impl From<&'static str> for ElementId {
2910 fn from(name: &'static str) -> Self {
2911 ElementId::Name(name.into())
2912 }
2913}
2914
2915impl<'a> From<&'a FocusHandle> for ElementId {
2916 fn from(handle: &'a FocusHandle) -> Self {
2917 ElementId::FocusHandle(handle.id)
2918 }
2919}
2920
2921impl From<(&'static str, EntityId)> for ElementId {
2922 fn from((name, id): (&'static str, EntityId)) -> Self {
2923 ElementId::NamedInteger(name.into(), id.as_u64() as usize)
2924 }
2925}
2926
2927impl From<(&'static str, usize)> for ElementId {
2928 fn from((name, id): (&'static str, usize)) -> Self {
2929 ElementId::NamedInteger(name.into(), id)
2930 }
2931}
2932
2933impl From<(&'static str, u64)> for ElementId {
2934 fn from((name, id): (&'static str, u64)) -> Self {
2935 ElementId::NamedInteger(name.into(), id as usize)
2936 }
2937}