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