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