use crate::{ Action, AnyDrag, AnyElement, AnyImageCache, AnyTooltip, AnyView, App, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Background, BorderStyle, Bounds, BoxShadow, Context, Corners, CursorStyle, Decorations, DevicePixels, DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, FontId, Global, GlobalElementId, GlyphId, GpuSpecs, Hsla, InputHandler, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, KeystrokeEvent, LayoutId, LineLayoutIndex, Modifiers, ModifiersChangedEvent, MonochromeSprite, MouseButton, MouseEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, Replay, ResizeEdge, SMOOTH_SVG_SCALE_FACTOR, SUBPIXEL_VARIANTS, ScaledPixels, Scene, Shadow, SharedString, Size, StrikethroughStyle, Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, TextStyle, TextStyleRefinement, TransformationMatrix, Underline, UnderlineStyle, WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowControls, WindowDecorations, WindowOptions, WindowParams, WindowTextSystem, point, prelude::*, px, size, transparent_black,};use anyhow::{Context as _, Result, anyhow};use collections::{FxHashMap, FxHashSet};#[cfg(target_os = "macos")]use core_video::pixel_buffer::CVPixelBuffer;use derive_more::{Deref, DerefMut};use futures::FutureExt;use futures::channel::oneshot;use parking_lot::RwLock;use raw_window_handle::{HandleError, HasWindowHandle};use refineable::Refineable;use slotmap::SlotMap;use smallvec::SmallVec;use std::{ any::{Any, TypeId}, borrow::Cow, cell::{Cell, RefCell}, cmp, fmt::{Debug, Display}, hash::{Hash, Hasher}, marker::PhantomData, mem, ops::{DerefMut, Range}, rc::Rc, sync::{ Arc, Weak, atomic::{AtomicUsize, Ordering::SeqCst}, }, time::{Duration, Instant},};use util::post_inc;use util::{ResultExt, measure};use uuid::Uuid; mod prompts; pub use prompts::*; pub(crate) const DEFAULT_WINDOW_SIZE: Size<Pixels> = size(px(1024.), px(700.)); /// Represents the two different phases when dispatching events.#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]pub enum DispatchPhase { /// After the capture phase comes the bubble phase, in which mouse event listeners are /// invoked front to back and keyboard event listeners are invoked from the focused element /// to the root of the element tree. This is the phase you'll most commonly want to use when /// registering event listeners. #[default] Bubble, /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard /// listeners are invoked from the root of the tree downward toward the focused element. This phase /// is used for special purposes such as clearing the "pressed" state for click events. If /// you stop event propagation during this phase, you need to know what you're doing. Handlers /// outside of the immediate region may rely on detecting non-local events during this phase. Capture,} impl DispatchPhase { /// Returns true if this represents the "bubble" phase. pub fn bubble(self) -> bool { self == DispatchPhase::Bubble } /// Returns true if this represents the "capture" phase. pub fn capture(self) -> bool { self == DispatchPhase::Capture }} struct WindowInvalidatorInner { pub dirty: bool, pub draw_phase: DrawPhase, pub dirty_views: FxHashSet<EntityId>,} #[derive(Clone)]pub(crate) struct WindowInvalidator { inner: Rc<RefCell<WindowInvalidatorInner>>,} impl WindowInvalidator { pub fn new() -> Self { WindowInvalidator { inner: Rc::new(RefCell::new(WindowInvalidatorInner { dirty: true, draw_phase: DrawPhase::None, dirty_views: FxHashSet::default(), })), } } pub fn invalidate_view(&self, entity: EntityId, cx: &mut App) -> bool { let mut inner = self.inner.borrow_mut(); inner.dirty_views.insert(entity); if inner.draw_phase == DrawPhase::None { inner.dirty = true; cx.push_effect(Effect::Notify { emitter: entity }); true } else { false } } pub fn is_dirty(&self) -> bool { self.inner.borrow().dirty } pub fn set_dirty(&self, dirty: bool) { self.inner.borrow_mut().dirty = dirty } pub fn set_phase(&self, phase: DrawPhase) { self.inner.borrow_mut().draw_phase = phase } pub fn take_views(&self) -> FxHashSet<EntityId> { mem::take(&mut self.inner.borrow_mut().dirty_views) } pub fn replace_views(&self, views: FxHashSet<EntityId>) { self.inner.borrow_mut().dirty_views = views; } pub fn not_drawing(&self) -> bool { self.inner.borrow().draw_phase == DrawPhase::None } #[track_caller] pub fn debug_assert_paint(&self) { debug_assert!( matches!(self.inner.borrow().draw_phase, DrawPhase::Paint), "this method can only be called during paint" ); } #[track_caller] pub fn debug_assert_prepaint(&self) { debug_assert!( matches!(self.inner.borrow().draw_phase, DrawPhase::Prepaint), "this method can only be called during request_layout, or prepaint" ); } #[track_caller] pub fn debug_assert_paint_or_prepaint(&self) { debug_assert!( matches!( self.inner.borrow().draw_phase, DrawPhase::Paint | DrawPhase::Prepaint ), "this method can only be called during request_layout, prepaint, or paint" ); }} type AnyObserver = Box<dyn FnMut(&mut Window, &mut App) -> bool + 'static>; pub(crate) type AnyWindowFocusListener = Box<dyn FnMut(&WindowFocusEvent, &mut Window, &mut App) -> bool + 'static>; pub(crate) struct WindowFocusEvent { pub(crate) previous_focus_path: SmallVec<[FocusId; 8]>, pub(crate) current_focus_path: SmallVec<[FocusId; 8]>,} impl WindowFocusEvent { pub fn is_focus_in(&self, focus_id: FocusId) -> bool { !self.previous_focus_path.contains(&focus_id) && self.current_focus_path.contains(&focus_id) } pub fn is_focus_out(&self, focus_id: FocusId) -> bool { self.previous_focus_path.contains(&focus_id) && !self.current_focus_path.contains(&focus_id) }} /// This is provided when subscribing for `Context::on_focus_out` events.pub struct FocusOutEvent { /// A weak focus handle representing what was blurred. pub blurred: WeakFocusHandle,} slotmap::new_key_type! { /// A globally unique identifier for a focusable element. pub struct FocusId;} thread_local! { /// 8MB wasn't quite enough... pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(32 * 1024 * 1024));} pub(crate) type FocusMap = RwLock<SlotMap<FocusId, AtomicUsize>>; impl FocusId { /// Obtains whether the element associated with this handle is currently focused. pub fn is_focused(&self, window: &Window) -> bool { window.focus == Some(*self) } /// Obtains whether the element associated with this handle contains the focused /// element or is itself focused. pub fn contains_focused(&self, window: &Window, cx: &App) -> bool { window .focused(cx) .map_or(false, |focused| self.contains(focused.id, window)) } /// Obtains whether the element associated with this handle is contained within the /// focused element or is itself focused. pub fn within_focused(&self, window: &Window, cx: &App) -> bool { let focused = window.focused(cx); focused.map_or(false, |focused| focused.id.contains(*self, window)) } /// Obtains whether this handle contains the given handle in the most recently rendered frame. pub(crate) fn contains(&self, other: Self, window: &Window) -> bool { window .rendered_frame .dispatch_tree .focus_contains(*self, other) }} /// A handle which can be used to track and manipulate the focused element in a window.pub struct FocusHandle { pub(crate) id: FocusId, handles: Arc<FocusMap>,} impl std::fmt::Debug for FocusHandle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("FocusHandle({:?})", self.id)) }} impl FocusHandle { pub(crate) fn new(handles: &Arc<FocusMap>) -> Self { let id = handles.write().insert(AtomicUsize::new(1)); Self { id, handles: handles.clone(), } } pub(crate) fn for_id(id: FocusId, handles: &Arc<FocusMap>) -> Option<Self> { let lock = handles.read(); let ref_count = lock.get(id)?; if ref_count.load(SeqCst) == 0 { None } else { ref_count.fetch_add(1, SeqCst); Some(Self { id, handles: handles.clone(), }) } } /// Converts this focus handle into a weak variant, which does not prevent it from being released. pub fn downgrade(&self) -> WeakFocusHandle { WeakFocusHandle { id: self.id, handles: Arc::downgrade(&self.handles), } } /// Moves the focus to the element associated with this handle. pub fn focus(&self, window: &mut Window) { window.focus(self) } /// Obtains whether the element associated with this handle is currently focused. pub fn is_focused(&self, window: &Window) -> bool { self.id.is_focused(window) } /// Obtains whether the element associated with this handle contains the focused /// element or is itself focused. pub fn contains_focused(&self, window: &Window, cx: &App) -> bool { self.id.contains_focused(window, cx) } /// Obtains whether the element associated with this handle is contained within the /// focused element or is itself focused. pub fn within_focused(&self, window: &Window, cx: &mut App) -> bool { self.id.within_focused(window, cx) } /// Obtains whether this handle contains the given handle in the most recently rendered frame. pub fn contains(&self, other: &Self, window: &Window) -> bool { self.id.contains(other.id, window) } /// Dispatch an action on the element that rendered this focus handle pub fn dispatch_action(&self, action: &dyn Action, window: &mut Window, cx: &mut App) { if let Some(node_id) = window .rendered_frame .dispatch_tree .focusable_node_id(self.id) { window.dispatch_action_on_node(node_id, action, cx) } }} impl Clone for FocusHandle { fn clone(&self) -> Self { Self::for_id(self.id, &self.handles).unwrap() }} impl PartialEq for FocusHandle { fn eq(&self, other: &Self) -> bool { self.id == other.id }} impl Eq for FocusHandle {} impl Drop for FocusHandle { fn drop(&mut self) { self.handles .read() .get(self.id) .unwrap() .fetch_sub(1, SeqCst); }} /// A weak reference to a focus handle.#[derive(Clone, Debug)]pub struct WeakFocusHandle { pub(crate) id: FocusId, pub(crate) handles: Weak<FocusMap>,} impl WeakFocusHandle { /// Attempts to upgrade the [WeakFocusHandle] to a [FocusHandle]. pub fn upgrade(&self) -> Option<FocusHandle> { let handles = self.handles.upgrade()?; FocusHandle::for_id(self.id, &handles) }} impl PartialEq for WeakFocusHandle { fn eq(&self, other: &WeakFocusHandle) -> bool { self.id == other.id }} impl Eq for WeakFocusHandle {} impl PartialEq<FocusHandle> for WeakFocusHandle { fn eq(&self, other: &FocusHandle) -> bool { self.id == other.id }} impl PartialEq<WeakFocusHandle> for FocusHandle { fn eq(&self, other: &WeakFocusHandle) -> bool { self.id == other.id }} /// Focusable allows users of your view to easily/// focus it (using window.focus_view(cx, view))pub trait Focusable: 'static { /// Returns the focus handle associated with this view. fn focus_handle(&self, cx: &App) -> FocusHandle;} impl<V: Focusable> Focusable for Entity<V> { fn focus_handle(&self, cx: &App) -> FocusHandle { self.read(cx).focus_handle(cx) }} /// ManagedView is a view (like a Modal, Popover, Menu, etc.)/// where the lifecycle of the view is handled by another view.pub trait ManagedView: Focusable + EventEmitter<DismissEvent> + Render {} impl<M: Focusable + EventEmitter<DismissEvent> + Render> ManagedView for M {} /// Emitted by implementers of [`ManagedView`] to indicate the view should be dismissed, such as when a view is presented as a modal.pub struct DismissEvent; type FrameCallback = Box<dyn FnOnce(&mut Window, &mut App)>; pub(crate) type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut Window, &mut App) + 'static>; #[derive(Clone)]pub(crate) struct CursorStyleRequest { pub(crate) hitbox_id: Option<HitboxId>, // None represents whole window pub(crate) style: CursorStyle,} /// An identifier for a [Hitbox].#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]pub struct HitboxId(usize); impl HitboxId { /// Checks if the hitbox with this id is currently hovered. pub fn is_hovered(&self, window: &Window) -> bool { window.mouse_hit_test.0.contains(self) }} /// A rectangular region that potentially blocks hitboxes inserted prior./// See [Window::insert_hitbox] for more details.#[derive(Clone, Debug, Deref)]pub struct Hitbox { /// A unique identifier for the hitbox. pub id: HitboxId, /// The bounds of the hitbox. #[deref] pub bounds: Bounds<Pixels>, /// The content mask when the hitbox was inserted. pub content_mask: ContentMask<Pixels>, /// Whether the hitbox occludes other hitboxes inserted prior. pub opaque: bool,} impl Hitbox { /// Checks if the hitbox is currently hovered. pub fn is_hovered(&self, window: &Window) -> bool { self.id.is_hovered(window) }} #[derive(Default, Eq, PartialEq)]pub(crate) struct HitTest(SmallVec<[HitboxId; 8]>); /// An identifier for a tooltip.#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]pub struct TooltipId(usize); impl TooltipId { /// Checks if the tooltip is currently hovered. pub fn is_hovered(&self, window: &Window) -> bool { window .tooltip_bounds .as_ref() .map_or(false, |tooltip_bounds| { tooltip_bounds.id == *self && tooltip_bounds.bounds.contains(&window.mouse_position()) }) }} pub(crate) struct TooltipBounds { id: TooltipId, bounds: Bounds<Pixels>,} #[derive(Clone)]pub(crate) struct TooltipRequest { id: TooltipId, tooltip: AnyTooltip,} pub(crate) struct DeferredDraw { current_view: EntityId, priority: usize, parent_node: DispatchNodeId, element_id_stack: SmallVec<[ElementId; 32]>, text_style_stack: Vec<TextStyleRefinement>, element: Option<AnyElement>, absolute_offset: Point<Pixels>, prepaint_range: Range<PrepaintStateIndex>, paint_range: Range<PaintIndex>,} pub(crate) struct Frame { pub(crate) focus: Option<FocusId>, pub(crate) window_active: bool, pub(crate) element_states: FxHashMap<(GlobalElementId, TypeId), ElementStateBox>, accessed_element_states: Vec<(GlobalElementId, TypeId)>, pub(crate) mouse_listeners: Vec<Option<AnyMouseListener>>, pub(crate) dispatch_tree: DispatchTree, pub(crate) scene: Scene, pub(crate) hitboxes: Vec<Hitbox>, pub(crate) deferred_draws: Vec<DeferredDraw>, pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,Lines 1–500 of 4246. Load more
use crate::{ Action, AnyDrag, AnyElement, AnyImageCache, AnyTooltip, AnyView, App, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Background, BorderStyle, Bounds, BoxShadow, Context, Corners, CursorStyle, Decorations, DevicePixels, DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, FontId, Global, GlobalElementId, GlyphId, GpuSpecs, Hsla, InputHandler, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, KeystrokeEvent, LayoutId, LineLayoutIndex, Modifiers, ModifiersChangedEvent, MonochromeSprite, MouseButton, MouseEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, Replay, ResizeEdge, SMOOTH_SVG_SCALE_FACTOR, SUBPIXEL_VARIANTS, ScaledPixels, Scene, Shadow, SharedString, Size, StrikethroughStyle, Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, TextStyle, TextStyleRefinement, TransformationMatrix, Underline, UnderlineStyle, WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowControls, WindowDecorations, WindowOptions, WindowParams, WindowTextSystem, point, prelude::*, px, size, transparent_black, }; use anyhow::{Context as _, Result, anyhow}; use collections::{FxHashMap, FxHashSet}; #[cfg(target_os = "macos")] use core_video::pixel_buffer::CVPixelBuffer; use derive_more::{Deref, DerefMut}; use futures::FutureExt; use futures::channel::oneshot; use parking_lot::RwLock; use raw_window_handle::{HandleError, HasWindowHandle}; use refineable::Refineable; use slotmap::SlotMap; use smallvec::SmallVec; use std::{ any::{Any, TypeId}, borrow::Cow, cell::{Cell, RefCell}, cmp, fmt::{Debug, Display}, hash::{Hash, Hasher}, marker::PhantomData, mem, ops::{DerefMut, Range}, rc::Rc, sync::{ Arc, Weak, atomic::{AtomicUsize, Ordering::SeqCst}, }, time::{Duration, Instant}, }; use util::post_inc; use util::{ResultExt, measure}; use uuid::Uuid; mod prompts; pub use prompts::*; pub(crate) const DEFAULT_WINDOW_SIZE: Size<Pixels> = size(px(1024.), px(700.)); /// Represents the two different phases when dispatching events. #[derive(Default, Copy, Clone, Debug, Eq, PartialEq)] pub enum DispatchPhase { /// After the capture phase comes the bubble phase, in which mouse event listeners are /// invoked front to back and keyboard event listeners are invoked from the focused element /// to the root of the element tree. This is the phase you'll most commonly want to use when /// registering event listeners. #[default] Bubble, /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard /// listeners are invoked from the root of the tree downward toward the focused element. This phase /// is used for special purposes such as clearing the "pressed" state for click events. If /// you stop event propagation during this phase, you need to know what you're doing. Handlers /// outside of the immediate region may rely on detecting non-local events during this phase. Capture, } impl DispatchPhase { /// Returns true if this represents the "bubble" phase. pub fn bubble(self) -> bool { self == DispatchPhase::Bubble } /// Returns true if this represents the "capture" phase. pub fn capture(self) -> bool { self == DispatchPhase::Capture } } struct WindowInvalidatorInner { pub dirty: bool, pub draw_phase: DrawPhase, pub dirty_views: FxHashSet<EntityId>, } #[derive(Clone)] pub(crate) struct WindowInvalidator { inner: Rc<RefCell<WindowInvalidatorInner>>, } impl WindowInvalidator { pub fn new() -> Self { WindowInvalidator { inner: Rc::new(RefCell::new(WindowInvalidatorInner { dirty: true, draw_phase: DrawPhase::None, dirty_views: FxHashSet::default(), })), } } pub fn invalidate_view(&self, entity: EntityId, cx: &mut App) -> bool { let mut inner = self.inner.borrow_mut(); inner.dirty_views.insert(entity); if inner.draw_phase == DrawPhase::None { inner.dirty = true; cx.push_effect(Effect::Notify { emitter: entity }); true } else { false } } pub fn is_dirty(&self) -> bool { self.inner.borrow().dirty } pub fn set_dirty(&self, dirty: bool) { self.inner.borrow_mut().dirty = dirty } pub fn set_phase(&self, phase: DrawPhase) { self.inner.borrow_mut().draw_phase = phase } pub fn take_views(&self) -> FxHashSet<EntityId> { mem::take(&mut self.inner.borrow_mut().dirty_views) } pub fn replace_views(&self, views: FxHashSet<EntityId>) { self.inner.borrow_mut().dirty_views = views; } pub fn not_drawing(&self) -> bool { self.inner.borrow().draw_phase == DrawPhase::None } #[track_caller] pub fn debug_assert_paint(&self) { debug_assert!( matches!(self.inner.borrow().draw_phase, DrawPhase::Paint), "this method can only be called during paint" ); } #[track_caller] pub fn debug_assert_prepaint(&self) { debug_assert!( matches!(self.inner.borrow().draw_phase, DrawPhase::Prepaint), "this method can only be called during request_layout, or prepaint" ); } #[track_caller] pub fn debug_assert_paint_or_prepaint(&self) { debug_assert!( matches!( self.inner.borrow().draw_phase, DrawPhase::Paint | DrawPhase::Prepaint ), "this method can only be called during request_layout, prepaint, or paint" ); } } type AnyObserver = Box<dyn FnMut(&mut Window, &mut App) -> bool + 'static>; pub(crate) type AnyWindowFocusListener = Box<dyn FnMut(&WindowFocusEvent, &mut Window, &mut App) -> bool + 'static>; pub(crate) struct WindowFocusEvent { pub(crate) previous_focus_path: SmallVec<[FocusId; 8]>, pub(crate) current_focus_path: SmallVec<[FocusId; 8]>, } impl WindowFocusEvent { pub fn is_focus_in(&self, focus_id: FocusId) -> bool { !self.previous_focus_path.contains(&focus_id) && self.current_focus_path.contains(&focus_id) } pub fn is_focus_out(&self, focus_id: FocusId) -> bool { self.previous_focus_path.contains(&focus_id) && !self.current_focus_path.contains(&focus_id) } } /// This is provided when subscribing for `Context::on_focus_out` events. pub struct FocusOutEvent { /// A weak focus handle representing what was blurred. pub blurred: WeakFocusHandle, } slotmap::new_key_type! { /// A globally unique identifier for a focusable element. pub struct FocusId; } thread_local! { /// 8MB wasn't quite enough... pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(32 * 1024 * 1024)); } pub(crate) type FocusMap = RwLock<SlotMap<FocusId, AtomicUsize>>; impl FocusId { /// Obtains whether the element associated with this handle is currently focused. pub fn is_focused(&self, window: &Window) -> bool { window.focus == Some(*self) } /// Obtains whether the element associated with this handle contains the focused /// element or is itself focused. pub fn contains_focused(&self, window: &Window, cx: &App) -> bool { window .focused(cx) .map_or(false, |focused| self.contains(focused.id, window)) } /// Obtains whether the element associated with this handle is contained within the /// focused element or is itself focused. pub fn within_focused(&self, window: &Window, cx: &App) -> bool { let focused = window.focused(cx); focused.map_or(false, |focused| focused.id.contains(*self, window)) } /// Obtains whether this handle contains the given handle in the most recently rendered frame. pub(crate) fn contains(&self, other: Self, window: &Window) -> bool { window .rendered_frame .dispatch_tree .focus_contains(*self, other) } } /// A handle which can be used to track and manipulate the focused element in a window. pub struct FocusHandle { pub(crate) id: FocusId, handles: Arc<FocusMap>, } impl std::fmt::Debug for FocusHandle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("FocusHandle({:?})", self.id)) } } impl FocusHandle { pub(crate) fn new(handles: &Arc<FocusMap>) -> Self { let id = handles.write().insert(AtomicUsize::new(1)); Self { id, handles: handles.clone(), } } pub(crate) fn for_id(id: FocusId, handles: &Arc<FocusMap>) -> Option<Self> { let lock = handles.read(); let ref_count = lock.get(id)?; if ref_count.load(SeqCst) == 0 { None } else { ref_count.fetch_add(1, SeqCst); Some(Self { id, handles: handles.clone(), }) } } /// Converts this focus handle into a weak variant, which does not prevent it from being released. pub fn downgrade(&self) -> WeakFocusHandle { WeakFocusHandle { id: self.id, handles: Arc::downgrade(&self.handles), } } /// Moves the focus to the element associated with this handle. pub fn focus(&self, window: &mut Window) { window.focus(self) } /// Obtains whether the element associated with this handle is currently focused. pub fn is_focused(&self, window: &Window) -> bool { self.id.is_focused(window) } /// Obtains whether the element associated with this handle contains the focused /// element or is itself focused. pub fn contains_focused(&self, window: &Window, cx: &App) -> bool { self.id.contains_focused(window, cx) } /// Obtains whether the element associated with this handle is contained within the /// focused element or is itself focused. pub fn within_focused(&self, window: &Window, cx: &mut App) -> bool { self.id.within_focused(window, cx) } /// Obtains whether this handle contains the given handle in the most recently rendered frame. pub fn contains(&self, other: &Self, window: &Window) -> bool { self.id.contains(other.id, window) } /// Dispatch an action on the element that rendered this focus handle pub fn dispatch_action(&self, action: &dyn Action, window: &mut Window, cx: &mut App) { if let Some(node_id) = window .rendered_frame .dispatch_tree .focusable_node_id(self.id) { window.dispatch_action_on_node(node_id, action, cx) } } } impl Clone for FocusHandle { fn clone(&self) -> Self { Self::for_id(self.id, &self.handles).unwrap() } } impl PartialEq for FocusHandle { fn eq(&self, other: &Self) -> bool { self.id == other.id } } impl Eq for FocusHandle {} impl Drop for FocusHandle { fn drop(&mut self) { self.handles .read() .get(self.id) .unwrap() .fetch_sub(1, SeqCst); } } /// A weak reference to a focus handle. #[derive(Clone, Debug)] pub struct WeakFocusHandle { pub(crate) id: FocusId, pub(crate) handles: Weak<FocusMap>, } impl WeakFocusHandle { /// Attempts to upgrade the [WeakFocusHandle] to a [FocusHandle]. pub fn upgrade(&self) -> Option<FocusHandle> { let handles = self.handles.upgrade()?; FocusHandle::for_id(self.id, &handles) } } impl PartialEq for WeakFocusHandle { fn eq(&self, other: &WeakFocusHandle) -> bool { self.id == other.id } } impl Eq for WeakFocusHandle {} impl PartialEq<FocusHandle> for WeakFocusHandle { fn eq(&self, other: &FocusHandle) -> bool { self.id == other.id } } impl PartialEq<WeakFocusHandle> for FocusHandle { fn eq(&self, other: &WeakFocusHandle) -> bool { self.id == other.id } } /// Focusable allows users of your view to easily /// focus it (using window.focus_view(cx, view)) pub trait Focusable: 'static { /// Returns the focus handle associated with this view. fn focus_handle(&self, cx: &App) -> FocusHandle; } impl<V: Focusable> Focusable for Entity<V> { fn focus_handle(&self, cx: &App) -> FocusHandle { self.read(cx).focus_handle(cx) } } /// ManagedView is a view (like a Modal, Popover, Menu, etc.) /// where the lifecycle of the view is handled by another view. pub trait ManagedView: Focusable + EventEmitter<DismissEvent> + Render {} impl<M: Focusable + EventEmitter<DismissEvent> + Render> ManagedView for M {} /// Emitted by implementers of [`ManagedView`] to indicate the view should be dismissed, such as when a view is presented as a modal. pub struct DismissEvent; type FrameCallback = Box<dyn FnOnce(&mut Window, &mut App)>; pub(crate) type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut Window, &mut App) + 'static>; #[derive(Clone)] pub(crate) struct CursorStyleRequest { pub(crate) hitbox_id: Option<HitboxId>, // None represents whole window pub(crate) style: CursorStyle, } /// An identifier for a [Hitbox]. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct HitboxId(usize); impl HitboxId { /// Checks if the hitbox with this id is currently hovered. pub fn is_hovered(&self, window: &Window) -> bool { window.mouse_hit_test.0.contains(self) } } /// A rectangular region that potentially blocks hitboxes inserted prior. /// See [Window::insert_hitbox] for more details. #[derive(Clone, Debug, Deref)] pub struct Hitbox { /// A unique identifier for the hitbox. pub id: HitboxId, /// The bounds of the hitbox. #[deref] pub bounds: Bounds<Pixels>, /// The content mask when the hitbox was inserted. pub content_mask: ContentMask<Pixels>, /// Whether the hitbox occludes other hitboxes inserted prior. pub opaque: bool, } impl Hitbox { /// Checks if the hitbox is currently hovered. pub fn is_hovered(&self, window: &Window) -> bool { self.id.is_hovered(window) } } #[derive(Default, Eq, PartialEq)] pub(crate) struct HitTest(SmallVec<[HitboxId; 8]>); /// An identifier for a tooltip. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct TooltipId(usize); impl TooltipId { /// Checks if the tooltip is currently hovered. pub fn is_hovered(&self, window: &Window) -> bool { window .tooltip_bounds .as_ref() .map_or(false, |tooltip_bounds| { tooltip_bounds.id == *self && tooltip_bounds.bounds.contains(&window.mouse_position()) }) } } pub(crate) struct TooltipBounds { id: TooltipId, bounds: Bounds<Pixels>, } #[derive(Clone)] pub(crate) struct TooltipRequest { id: TooltipId, tooltip: AnyTooltip, } pub(crate) struct DeferredDraw { current_view: EntityId, priority: usize, parent_node: DispatchNodeId, element_id_stack: SmallVec<[ElementId; 32]>, text_style_stack: Vec<TextStyleRefinement>, element: Option<AnyElement>, absolute_offset: Point<Pixels>, prepaint_range: Range<PrepaintStateIndex>, paint_range: Range<PaintIndex>, } pub(crate) struct Frame { pub(crate) focus: Option<FocusId>, pub(crate) window_active: bool, pub(crate) element_states: FxHashMap<(GlobalElementId, TypeId), ElementStateBox>, accessed_element_states: Vec<(GlobalElementId, TypeId)>, pub(crate) mouse_listeners: Vec<Option<AnyMouseListener>>, pub(crate) dispatch_tree: DispatchTree, pub(crate) scene: Scene, pub(crate) hitboxes: Vec<Hitbox>, pub(crate) deferred_draws: Vec<DeferredDraw>, pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,