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