diff --git a/Cargo.lock b/Cargo.lock index 260ecb630a60fd158b3c645972480862699d8b90..fcbf5a0f958537cd5f1318474e913c8c14ac8800 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4987,8 +4987,8 @@ dependencies = [ name = "menu2" version = "0.1.0" dependencies = [ + "gpui2", "serde", - "serde_derive", ] [[package]] diff --git a/crates/go_to_line2/src/go_to_line.rs b/crates/go_to_line2/src/go_to_line.rs index b8b91b16468c0e97e25946c3e24be5a9e062dd21..3c9cd5e31eb38c80b771d677877c6bc557d6a9a4 100644 --- a/crates/go_to_line2/src/go_to_line.rs +++ b/crates/go_to_line2/src/go_to_line.rs @@ -27,7 +27,6 @@ impl Render for GoToLine { type Element = Div; fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { - dbg!("rendering GoToLine"); div().bg(red()).w(px(100.0)).h(px(100.0)) } } diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 9b8c9dbf855d79ad0c36843250ded199e7b02c6b..d88a4119b7232838042ebe53f984b9468e1309c0 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -37,7 +37,7 @@ where { pub fn id(self, id: impl Into) -> Div, F> { Div { - interactivity: id.into().into(), + interactivity: StatefulInteractivity::new(id.into(), self.interactivity), focus: self.focus, children: self.children, group: self.group, diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index d43c6b59926de499959304d5af754bc8a97aec07..e1160227637c8374fa47e922a0fabb509308ec1e 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -30,7 +30,7 @@ where .map(|component| component.render()) .collect() }), - interactivity: id.into(), + interactivity: StatefulInteractivity::new(id, StatelessInteractivity::default()), scroll_handle: None, } } diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index 308c39fe7ffe912456fc6ec677d98ecb8fb3982b..a546c1b40b9cbb073f3539133c29b1714fffd951 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -189,10 +189,10 @@ pub trait StatelessInteractive: Element { { self.stateless_interactivity().key_listeners.push(( TypeId::of::(), - Box::new(move |view, event, _, phase, cx| { - let event = event.downcast_ref().unwrap(); + Box::new(move |view, action, _dipatch_context, phase, cx| { + let action = action.downcast_ref().unwrap(); if phase == DispatchPhase::Capture { - listener(view, event, cx) + listener(view, action, cx) } None }), @@ -210,10 +210,10 @@ pub trait StatelessInteractive: Element { { self.stateless_interactivity().key_listeners.push(( TypeId::of::(), - Box::new(move |view, event, _, phase, cx| { - let event = event.downcast_ref().unwrap(); + Box::new(move |view, action, _dispatch_context, phase, cx| { + let action = action.downcast_ref().unwrap(); if phase == DispatchPhase::Bubble { - listener(view, event, cx) + listener(view, action, cx) } None @@ -407,6 +407,8 @@ pub trait ElementInteractivity: 'static { ) -> R { if let Some(stateful) = self.as_stateful_mut() { 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(( TypeId::of::(), Box::new(move |_, key_down, context, phase, cx| { @@ -774,6 +776,21 @@ pub struct StatefulInteractivity { tooltip_builder: Option>, } +impl StatefulInteractivity { + pub fn new(id: ElementId, stateless: StatelessInteractivity) -> 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 ElementInteractivity for StatefulInteractivity { fn as_stateful(&self) -> Option<&StatefulInteractivity> { Some(self) @@ -792,21 +809,6 @@ impl ElementInteractivity for StatefulInteractivity { } } -impl From for StatefulInteractivity { - 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 = dyn Fn(&mut V, AnyView, &mut ViewContext) + 'static; pub struct StatelessInteractivity { @@ -1284,14 +1286,8 @@ mod test { fn render(&mut self, _: &mut gpui::ViewContext) -> Self::Element { div().id("testview").child( div() - .on_key_down(|this: &mut TestView, _, _, _| { - dbg!("ola!"); - this.saw_key_down = true - }) - .on_action(|this: &mut TestView, _: &TestAction, _| { - dbg!("ola!"); - this.saw_action = true - }) + .on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true) + .on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true) .track_focus(&self.focus_handle), ) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 0dae6171d9d79f266cefcaec18b4806c1101a92f..1474165742627ced402bb81d6fab5c15f0caa887 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1154,7 +1154,6 @@ impl<'a> WindowContext<'a> { .insert(any_mouse_event.type_id(), handlers); } } 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.current_frame.key_dispatch_stack); let key_event_type = any_key_event.type_id(); let mut context_stack = SmallVec::<[&DispatchContext; 16]>::new(); @@ -1175,7 +1174,6 @@ impl<'a> WindowContext<'a> { self.dispatch_action(action, &key_dispatch_stack[..ix]); } if !self.app.propagate_event { - did_handle_action = true; break; } } @@ -1204,7 +1202,6 @@ impl<'a> WindowContext<'a> { } if !self.app.propagate_event { - did_handle_action = true; break; } } @@ -1218,10 +1215,9 @@ impl<'a> WindowContext<'a> { drop(context_stack); self.window.current_frame.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. diff --git a/crates/menu2/Cargo.toml b/crates/menu2/Cargo.toml index 5fc33ddb11d41416c4b64aa15d7e3d1564952f94..0585f988858279552ce09a6abde7addd99c387fb 100644 --- a/crates/menu2/Cargo.toml +++ b/crates/menu2/Cargo.toml @@ -9,5 +9,5 @@ path = "src/menu2.rs" doctest = false [dependencies] -serde.workspace = true -serde_derive.workspace = true +gpui = { package = "gpui2", path = "../gpui2" } +serde = { workspace = true } diff --git a/crates/menu2/src/menu2.rs b/crates/menu2/src/menu2.rs index da21bdcd2282cd4834f42eb67839553ea5c6ae91..e5e8242f37ecc92090c08718f55763a94426a0f9 100644 --- a/crates/menu2/src/menu2.rs +++ b/crates/menu2/src/menu2.rs @@ -1,25 +1,12 @@ -use serde_derive::Deserialize; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct Cancel; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct Confirm; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct SecondaryConfirm; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct SelectPrev; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct SelectNext; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct SelectFirst; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct SelectLast; - -#[derive(Clone, Debug, Default, Deserialize, PartialEq)] -pub struct ShowContextMenu; +use gpui::actions; + +actions!( + Cancel, + Confirm, + SecondaryConfirm, + SelectPrev, + SelectNext, + SelectFirst, + SelectLast, + ShowContextMenu +);