Checkpoint

This commit is contained in:
Nathan Sobo 2023-11-13 23:03:14 -07:00
parent 1668330764
commit 9382a304c4
2 changed files with 41 additions and 55 deletions

View file

@ -1,9 +1,9 @@
use crate::{ use crate::{
point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext, point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext,
BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusHandle, KeyContext, BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusEvent, FocusHandle,
KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, MouseMoveEvent,
Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, Style, StyleRefinement, Styled, MouseUpEvent, Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, Style,
Task, View, ViewContext, Visibility, StyleRefinement, Styled, Task, View, ViewContext, Visibility,
}; };
use collections::HashMap; use collections::HashMap;
use parking_lot::Mutex; use parking_lot::Mutex;
@ -371,14 +371,12 @@ pub trait StatefulInteractiveComponent<V: 'static, E: Element<V>>: InteractiveCo
} }
} }
pub trait FocusableComponent<V> { pub trait FocusableComponent<V: 'static>: InteractiveComponent<V> {
fn focusability(&mut self) -> &mut Focusability<V>;
fn focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self fn focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
where where
Self: Sized, Self: Sized,
{ {
self.focusability().focus_style = f(StyleRefinement::default()); self.interactivity().focus_style = f(StyleRefinement::default());
self self
} }
@ -386,7 +384,7 @@ pub trait FocusableComponent<V> {
where where
Self: Sized, Self: Sized,
{ {
self.focusability().focus_in_style = f(StyleRefinement::default()); self.interactivity().focus_in_style = f(StyleRefinement::default());
self self
} }
@ -394,7 +392,7 @@ pub trait FocusableComponent<V> {
where where
Self: Sized, Self: Sized,
{ {
self.focusability().in_focus_style = f(StyleRefinement::default()); self.interactivity().in_focus_style = f(StyleRefinement::default());
self self
} }
@ -405,13 +403,13 @@ pub trait FocusableComponent<V> {
where where
Self: Sized, Self: Sized,
{ {
self.focusability() self.interactivity().focus_listeners.push(Box::new(
.focus_listeners move |view, focus_handle, event, cx| {
.push(Box::new(move |view, focus_handle, event, cx| {
if event.focused.as_ref() == Some(focus_handle) { if event.focused.as_ref() == Some(focus_handle) {
listener(view, event, cx) listener(view, event, cx)
} }
})); },
));
self self
} }
@ -422,13 +420,13 @@ pub trait FocusableComponent<V> {
where where
Self: Sized, Self: Sized,
{ {
self.focusability() self.interactivity().focus_listeners.push(Box::new(
.focus_listeners move |view, focus_handle, event, cx| {
.push(Box::new(move |view, focus_handle, event, cx| {
if event.blurred.as_ref() == Some(focus_handle) { if event.blurred.as_ref() == Some(focus_handle) {
listener(view, event, cx) listener(view, event, cx)
} }
})); },
));
self self
} }
@ -439,9 +437,8 @@ pub trait FocusableComponent<V> {
where where
Self: Sized, Self: Sized,
{ {
self.focusability() self.interactivity().focus_listeners.push(Box::new(
.focus_listeners move |view, focus_handle, event, cx| {
.push(Box::new(move |view, focus_handle, event, cx| {
let descendant_blurred = event let descendant_blurred = event
.blurred .blurred
.as_ref() .as_ref()
@ -454,7 +451,8 @@ pub trait FocusableComponent<V> {
if !descendant_blurred && descendant_focused { if !descendant_blurred && descendant_focused {
listener(view, event, cx) listener(view, event, cx)
} }
})); },
));
self self
} }
@ -465,9 +463,8 @@ pub trait FocusableComponent<V> {
where where
Self: Sized, Self: Sized,
{ {
self.focusability() self.interactivity().focus_listeners.push(Box::new(
.focus_listeners move |view, focus_handle, event, cx| {
.push(Box::new(move |view, focus_handle, event, cx| {
let descendant_blurred = event let descendant_blurred = event
.blurred .blurred
.as_ref() .as_ref()
@ -479,7 +476,8 @@ pub trait FocusableComponent<V> {
if descendant_blurred && !descendant_focused { if descendant_blurred && !descendant_focused {
listener(view, event, cx) listener(view, event, cx)
} }
})); },
));
self self
} }
} }
@ -525,11 +523,6 @@ pub type KeyUpListener<V> =
pub type ActionListener<V> = pub type ActionListener<V> =
Box<dyn Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static>; Box<dyn Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static>;
pub struct FocusEvent {
pub blurred: Option<FocusHandle>,
pub focused: Option<FocusHandle>,
}
pub struct Node<V> { pub struct Node<V> {
interactivity: Interactivity<V>, interactivity: Interactivity<V>,
children: Vec<AnyElement<V>>, children: Vec<AnyElement<V>>,
@ -658,8 +651,9 @@ pub struct NodeState {
pub struct Interactivity<V> { pub struct Interactivity<V> {
element_id: Option<ElementId>, element_id: Option<ElementId>,
key_context: KeyContext, key_context: KeyContext,
tracked_focus_handle: Option<FocusHandle>,
focusable: bool, focusable: bool,
tracked_focus_handle: Option<FocusHandle>,
focus_listeners: FocusListeners<V>,
scroll_offset: Point<Pixels>, scroll_offset: Point<Pixels>,
group: Option<SharedString>, group: Option<SharedString>,
base_style: StyleRefinement, base_style: StyleRefinement,
@ -1007,7 +1001,7 @@ where
cx.with_element_id(self.element_id.clone(), |cx| { cx.with_element_id(self.element_id.clone(), |cx| {
cx.with_key_dispatch( cx.with_key_dispatch(
self.key_context.clone(), self.key_context.clone(),
self.tracked_focus_handle.clone(), element_state.focus_handle.clone(),
|_, cx| { |_, cx| {
for listener in self.key_down_listeners.drain(..) { for listener in self.key_down_listeners.drain(..) {
cx.on_key_event(move |state, event: &KeyDownEvent, phase, cx| { cx.on_key_event(move |state, event: &KeyDownEvent, phase, cx| {
@ -1025,6 +1019,15 @@ where
cx.on_action(action_type, listener) cx.on_action(action_type, listener)
} }
if let Some(focus_handle) = element_state.focus_handle.as_ref() {
for listener in self.focus_listeners.drain(..) {
let focus_handle = focus_handle.clone();
cx.on_focus_changed(move |view, event, cx| {
listener(view, &focus_handle, event, cx)
});
}
}
f(style, self.scroll_offset, cx) f(style, self.scroll_offset, cx)
}, },
); );
@ -1114,7 +1117,9 @@ impl<V: 'static> Default for Interactivity<V> {
Self { Self {
element_id: None, element_id: None,
key_context: KeyContext::default(), key_context: KeyContext::default(),
focusable: false,
tracked_focus_handle: None, tracked_focus_handle: None,
focus_listeners: SmallVec::default(),
scroll_offset: Point::default(), scroll_offset: Point::default(),
group: None, group: None,
base_style: StyleRefinement::default(), base_style: StyleRefinement::default(),
@ -1139,7 +1144,6 @@ impl<V: 'static> Default for Interactivity<V> {
drag_listener: None, drag_listener: None,
hover_listener: None, hover_listener: None,
tooltip_builder: None, tooltip_builder: None,
focusable: false,
} }
} }
} }
@ -1199,24 +1203,11 @@ impl GroupBounds {
} }
pub struct Focusable<V, E> { pub struct Focusable<V, E> {
focusability: Focusability<V>,
view_type: PhantomData<V>, view_type: PhantomData<V>,
element: E, element: E,
} }
pub struct Focusability<V> { impl<V: 'static, E: InteractiveComponent<V>> FocusableComponent<V> for Focusable<V, E> {}
focus_handle: Option<FocusHandle>,
focus_listeners: FocusListeners<V>,
focus_style: StyleRefinement,
focus_in_style: StyleRefinement,
in_focus_style: StyleRefinement,
}
impl<V, E> FocusableComponent<V> for Focusable<V, E> {
fn focusability(&mut self) -> &mut Focusability<V> {
&mut self.focusability
}
}
impl<V, E> InteractiveComponent<V> for Focusable<V, E> impl<V, E> InteractiveComponent<V> for Focusable<V, E>
where where
@ -1274,7 +1265,6 @@ where
} }
pub struct Stateful<V, E> { pub struct Stateful<V, E> {
id: SharedString,
view_type: PhantomData<V>, view_type: PhantomData<V>,
element: E, element: E,
} }
@ -1297,11 +1287,7 @@ where
} }
} }
impl<V, E: FocusableComponent<V>> FocusableComponent<V> for Stateful<V, E> { impl<V: 'static, E: FocusableComponent<V>> FocusableComponent<V> for Stateful<V, E> {}
fn focusability(&mut self) -> &mut Focusability<V> {
self.element.focusability()
}
}
impl<V, E> Element<V> for Stateful<V, E> impl<V, E> Element<V> for Stateful<V, E>
where where

View file

@ -1,4 +1,4 @@
use gpui::{AnyElement, Pixels}; use gpui::AnyElement;
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::{h_stack, prelude::*, v_stack, Button, Icon, IconButton, Label}; use crate::{h_stack, prelude::*, v_stack, Button, Icon, IconButton, Label};