Preserve stateless interactivity when assigning elements an id
Co-authored-by: Nathan <nathan@zed.dev> Co-authored-by: Piotr <piotr@zed.dev>
This commit is contained in:
parent
d25f48ed6b
commit
4c31a0c989
5 changed files with 28 additions and 37 deletions
|
@ -27,7 +27,6 @@ impl Render for GoToLine {
|
||||||
type Element = Div<Self>;
|
type Element = Div<Self>;
|
||||||
|
|
||||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
dbg!("rendering GoToLine");
|
|
||||||
div().bg(red()).w(px(100.0)).h(px(100.0))
|
div().bg(red()).w(px(100.0)).h(px(100.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ where
|
||||||
{
|
{
|
||||||
pub fn id(self, id: impl Into<ElementId>) -> Div<V, StatefulInteractivity<V>, F> {
|
pub fn id(self, id: impl Into<ElementId>) -> Div<V, StatefulInteractivity<V>, F> {
|
||||||
Div {
|
Div {
|
||||||
interactivity: id.into().into(),
|
interactivity: StatefulInteractivity::new(id.into(), self.interactivity),
|
||||||
focus: self.focus,
|
focus: self.focus,
|
||||||
children: self.children,
|
children: self.children,
|
||||||
group: self.group,
|
group: self.group,
|
||||||
|
|
|
@ -30,7 +30,7 @@ where
|
||||||
.map(|component| component.render())
|
.map(|component| component.render())
|
||||||
.collect()
|
.collect()
|
||||||
}),
|
}),
|
||||||
interactivity: id.into(),
|
interactivity: StatefulInteractivity::new(id, StatelessInteractivity::default()),
|
||||||
scroll_handle: None,
|
scroll_handle: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,10 +189,10 @@ pub trait StatelessInteractive<V: 'static>: Element<V> {
|
||||||
{
|
{
|
||||||
self.stateless_interactivity().key_listeners.push((
|
self.stateless_interactivity().key_listeners.push((
|
||||||
TypeId::of::<A>(),
|
TypeId::of::<A>(),
|
||||||
Box::new(move |view, event, _, phase, cx| {
|
Box::new(move |view, action, _dipatch_context, phase, cx| {
|
||||||
let event = event.downcast_ref().unwrap();
|
let action = action.downcast_ref().unwrap();
|
||||||
if phase == DispatchPhase::Capture {
|
if phase == DispatchPhase::Capture {
|
||||||
listener(view, event, cx)
|
listener(view, action, cx)
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}),
|
}),
|
||||||
|
@ -210,10 +210,10 @@ pub trait StatelessInteractive<V: 'static>: Element<V> {
|
||||||
{
|
{
|
||||||
self.stateless_interactivity().key_listeners.push((
|
self.stateless_interactivity().key_listeners.push((
|
||||||
TypeId::of::<A>(),
|
TypeId::of::<A>(),
|
||||||
Box::new(move |view, event, _, phase, cx| {
|
Box::new(move |view, action, _dispatch_context, phase, cx| {
|
||||||
let event = event.downcast_ref().unwrap();
|
let action = action.downcast_ref().unwrap();
|
||||||
if phase == DispatchPhase::Bubble {
|
if phase == DispatchPhase::Bubble {
|
||||||
listener(view, event, cx)
|
listener(view, action, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -407,6 +407,8 @@ pub trait ElementInteractivity<V: 'static>: 'static {
|
||||||
) -> R {
|
) -> R {
|
||||||
if let Some(stateful) = self.as_stateful_mut() {
|
if let Some(stateful) = self.as_stateful_mut() {
|
||||||
cx.with_element_id(stateful.id.clone(), |global_id, cx| {
|
cx.with_element_id(stateful.id.clone(), |global_id, cx| {
|
||||||
|
// In addition to any key down/up listeners registered directly on the element,
|
||||||
|
// we also add a key listener to match actions from the keymap.
|
||||||
stateful.key_listeners.push((
|
stateful.key_listeners.push((
|
||||||
TypeId::of::<KeyDownEvent>(),
|
TypeId::of::<KeyDownEvent>(),
|
||||||
Box::new(move |_, key_down, context, phase, cx| {
|
Box::new(move |_, key_down, context, phase, cx| {
|
||||||
|
@ -774,6 +776,21 @@ pub struct StatefulInteractivity<V> {
|
||||||
tooltip_builder: Option<TooltipBuilder<V>>,
|
tooltip_builder: Option<TooltipBuilder<V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<V: 'static> StatefulInteractivity<V> {
|
||||||
|
pub fn new(id: ElementId, stateless: StatelessInteractivity<V>) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
stateless,
|
||||||
|
click_listeners: SmallVec::new(),
|
||||||
|
active_style: StyleRefinement::default(),
|
||||||
|
group_active_style: None,
|
||||||
|
drag_listener: None,
|
||||||
|
hover_listener: None,
|
||||||
|
tooltip_builder: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<V: 'static> ElementInteractivity<V> for StatefulInteractivity<V> {
|
impl<V: 'static> ElementInteractivity<V> for StatefulInteractivity<V> {
|
||||||
fn as_stateful(&self) -> Option<&StatefulInteractivity<V>> {
|
fn as_stateful(&self) -> Option<&StatefulInteractivity<V>> {
|
||||||
Some(self)
|
Some(self)
|
||||||
|
@ -792,21 +809,6 @@ impl<V: 'static> ElementInteractivity<V> for StatefulInteractivity<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V> From<ElementId> for StatefulInteractivity<V> {
|
|
||||||
fn from(id: ElementId) -> Self {
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
stateless: StatelessInteractivity::default(),
|
|
||||||
click_listeners: SmallVec::new(),
|
|
||||||
drag_listener: None,
|
|
||||||
hover_listener: None,
|
|
||||||
tooltip_builder: None,
|
|
||||||
active_style: StyleRefinement::default(),
|
|
||||||
group_active_style: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type DropListener<V> = dyn Fn(&mut V, AnyView, &mut ViewContext<V>) + 'static;
|
type DropListener<V> = dyn Fn(&mut V, AnyView, &mut ViewContext<V>) + 'static;
|
||||||
|
|
||||||
pub struct StatelessInteractivity<V> {
|
pub struct StatelessInteractivity<V> {
|
||||||
|
@ -1284,14 +1286,8 @@ mod test {
|
||||||
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||||
div().id("testview").child(
|
div().id("testview").child(
|
||||||
div()
|
div()
|
||||||
.on_key_down(|this: &mut TestView, _, _, _| {
|
.on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true)
|
||||||
dbg!("ola!");
|
.on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true)
|
||||||
this.saw_key_down = true
|
|
||||||
})
|
|
||||||
.on_action(|this: &mut TestView, _: &TestAction, _| {
|
|
||||||
dbg!("ola!");
|
|
||||||
this.saw_action = true
|
|
||||||
})
|
|
||||||
.track_focus(&self.focus_handle),
|
.track_focus(&self.focus_handle),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1170,7 +1170,6 @@ impl<'a> WindowContext<'a> {
|
||||||
.insert(any_mouse_event.type_id(), handlers);
|
.insert(any_mouse_event.type_id(), handlers);
|
||||||
}
|
}
|
||||||
} else if let Some(any_key_event) = event.keyboard_event() {
|
} else if let Some(any_key_event) = event.keyboard_event() {
|
||||||
let mut did_handle_action = false;
|
|
||||||
let key_dispatch_stack = mem::take(&mut self.window.key_dispatch_stack);
|
let key_dispatch_stack = mem::take(&mut self.window.key_dispatch_stack);
|
||||||
let key_event_type = any_key_event.type_id();
|
let key_event_type = any_key_event.type_id();
|
||||||
let mut context_stack = SmallVec::<[&DispatchContext; 16]>::new();
|
let mut context_stack = SmallVec::<[&DispatchContext; 16]>::new();
|
||||||
|
@ -1191,7 +1190,6 @@ impl<'a> WindowContext<'a> {
|
||||||
self.dispatch_action(action, &key_dispatch_stack[..ix]);
|
self.dispatch_action(action, &key_dispatch_stack[..ix]);
|
||||||
}
|
}
|
||||||
if !self.app.propagate_event {
|
if !self.app.propagate_event {
|
||||||
did_handle_action = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1218,6 @@ impl<'a> WindowContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.app.propagate_event {
|
if !self.app.propagate_event {
|
||||||
did_handle_action = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1234,10 +1231,9 @@ impl<'a> WindowContext<'a> {
|
||||||
|
|
||||||
drop(context_stack);
|
drop(context_stack);
|
||||||
self.window.key_dispatch_stack = key_dispatch_stack;
|
self.window.key_dispatch_stack = key_dispatch_stack;
|
||||||
return did_handle_action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
!self.app.propagate_event
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to map a keystroke to an action based on the keymap.
|
/// Attempt to map a keystroke to an action based on the keymap.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue