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