From bb584cc7c4e52a2864fc1a0e00891872c011abbe Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Nov 2023 11:00:52 -0700 Subject: [PATCH] WIP --- .../command_palette2/src/command_palette.rs | 2 + crates/editor2/src/element.rs | 114 +++++++++--------- crates/gpui2/src/elements/div.rs | 11 +- crates/gpui2/src/interactive.rs | 17 ++- crates/gpui2/src/keymap/matcher.rs | 1 + crates/gpui2/src/window.rs | 7 +- 6 files changed, 82 insertions(+), 70 deletions(-) diff --git a/crates/command_palette2/src/command_palette.rs b/crates/command_palette2/src/command_palette.rs index 435a6446693e590f2af9c678df445c0f53b18428..5d428fba8e97ac306d2fe7ff54dea6e1ac0fdd37 100644 --- a/crates/command_palette2/src/command_palette.rs +++ b/crates/command_palette2/src/command_palette.rs @@ -32,7 +32,9 @@ pub struct CommandPalette { impl CommandPalette { fn register(workspace: &mut Workspace, _: &mut ViewContext) { + dbg!("registering command palette toggle"); workspace.register_action(|workspace, _: &Toggle, cx| { + dbg!("got cmd-shift-p"); let Some(previous_focus_handle) = cx.focused() else { return; }; diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index dd834b4cd89998211b7290b98db8d5323fe55878..3efd399a518875de852df7c55d14f099ecdd6d61 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2446,7 +2446,7 @@ impl Element for EditorElement { type ElementState = (); fn element_id(&self) -> Option { - None + None // todo! can we change the element trait to return an id here from the view context? } fn initialize( @@ -2456,6 +2456,41 @@ impl Element for EditorElement { cx: &mut gpui::ViewContext, ) -> Self::ElementState { editor.style = Some(self.style.clone()); // Long-term, we'd like to eliminate this. + } + + fn layout( + &mut self, + editor: &mut Editor, + element_state: &mut Self::ElementState, + cx: &mut gpui::ViewContext, + ) -> gpui::LayoutId { + let rem_size = cx.rem_size(); + let mut style = Style::default(); + style.size.width = relative(1.).into(); + style.size.height = match editor.mode { + EditorMode::SingleLine => self.style.text.line_height_in_pixels(cx.rem_size()).into(), + EditorMode::AutoHeight { .. } => todo!(), + EditorMode::Full => relative(1.).into(), + }; + cx.request_layout(&style, None) + } + + fn paint( + &mut self, + bounds: Bounds, + editor: &mut Editor, + element_state: &mut Self::ElementState, + cx: &mut gpui::ViewContext, + ) { + let mut layout = self.compute_layout(editor, cx, bounds); + let gutter_bounds = Bounds { + origin: bounds.origin, + size: layout.gutter_size, + }; + let text_bounds = Bounds { + origin: gutter_bounds.upper_right(), + size: layout.text_size, + }; let dispatch_context = editor.dispatch_context(cx); cx.with_element_id(Some(cx.view().entity_id()), |cx| { @@ -2621,63 +2656,28 @@ impl Element for EditorElement { register_action(cx, Editor::context_menu_prev); register_action(cx, Editor::context_menu_next); register_action(cx, Editor::context_menu_last); - }, - ) - }); - } - - fn layout( - &mut self, - editor: &mut Editor, - element_state: &mut Self::ElementState, - cx: &mut gpui::ViewContext, - ) -> gpui::LayoutId { - let rem_size = cx.rem_size(); - let mut style = Style::default(); - style.size.width = relative(1.).into(); - style.size.height = match editor.mode { - EditorMode::SingleLine => self.style.text.line_height_in_pixels(cx.rem_size()).into(), - EditorMode::AutoHeight { .. } => todo!(), - EditorMode::Full => relative(1.).into(), - }; - cx.request_layout(&style, None) - } - fn paint( - &mut self, - bounds: Bounds, - editor: &mut Editor, - element_state: &mut Self::ElementState, - cx: &mut gpui::ViewContext, - ) { - let mut layout = self.compute_layout(editor, cx, bounds); - let gutter_bounds = Bounds { - origin: bounds.origin, - size: layout.gutter_size, - }; - let text_bounds = Bounds { - origin: gutter_bounds.upper_right(), - size: layout.text_size, - }; - - // We call with_z_index to establish a new stacking context. - cx.with_z_index(0, |cx| { - cx.with_content_mask(Some(ContentMask { bounds }), |cx| { - self.paint_mouse_listeners( - bounds, - gutter_bounds, - text_bounds, - &layout.position_map, - cx, - ); - self.paint_background(gutter_bounds, text_bounds, &layout, cx); - if layout.gutter_size.width > Pixels::ZERO { - self.paint_gutter(gutter_bounds, &mut layout, editor, cx); - } - self.paint_text(text_bounds, &mut layout, editor, cx); - let input_handler = ElementInputHandler::new(bounds, cx); - cx.handle_input(&editor.focus_handle, input_handler); - }); + // We call with_z_index to establish a new stacking context. + cx.with_z_index(0, |cx| { + cx.with_content_mask(Some(ContentMask { bounds }), |cx| { + self.paint_mouse_listeners( + bounds, + gutter_bounds, + text_bounds, + &layout.position_map, + cx, + ); + self.paint_background(gutter_bounds, text_bounds, &layout, cx); + if layout.gutter_size.width > Pixels::ZERO { + self.paint_gutter(gutter_bounds, &mut layout, editor, cx); + } + self.paint_text(text_bounds, &mut layout, editor, cx); + let input_handler = ElementInputHandler::new(bounds, cx); + cx.handle_input(&editor.focus_handle, input_handler); + }); + }); + }, + ); }); } } diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index aa4ef9bd36eb8160868f5dcdc2520e3137cb00ef..94f94241b219b74ac38c3322dfbccf63f6a77443 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -612,6 +612,7 @@ impl Element for Div { let interactive_state = self .interactivity .initialize(element_state.map(|s| s.interactive_state), cx); + for child in &mut self.children { child.initialize(view_state, cx); } @@ -763,6 +764,7 @@ where .unwrap_or_else(|| cx.focus_handle()) }); } + element_state } @@ -773,11 +775,7 @@ where f: impl FnOnce(Style, &mut ViewContext) -> LayoutId, ) -> LayoutId { let style = self.compute_style(None, element_state, cx); - cx.with_key_dispatch( - self.key_context.clone(), - self.tracked_focus_handle.clone(), - |_, cx| f(style, cx), - ) + f(style, cx) } pub fn paint( @@ -1078,6 +1076,9 @@ where }) } + if !self.key_context.is_empty() { + dbg!(&self.key_context, self.action_listeners.len()); + } for (action_type, listener) in self.action_listeners.drain(..) { cx.on_action(action_type, listener) } diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index 1896957ac80e799e1b72a8957ae56ac36dbabf1e..013ed2ea482a49cdf26f2411b09d8398d01dc506 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -286,8 +286,8 @@ pub struct FocusEvent { #[cfg(test)] mod test { use crate::{ - self as gpui, div, Div, FocusHandle, InteractiveComponent, KeyBinding, Keystroke, - ParentComponent, Render, Stateful, TestAppContext, VisualContext, + self as gpui, div, Component, Div, FocusHandle, InteractiveComponent, KeyBinding, + Keystroke, ParentComponent, Render, Stateful, TestAppContext, ViewContext, VisualContext, }; struct TestView { @@ -304,10 +304,15 @@ mod test { fn render(&mut self, _: &mut gpui::ViewContext) -> Self::Element { div().id("testview").child( div() - .key_context("test") - .track_focus(&self.focus_handle) + .key_context("parent") .on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true) - .on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true), + .on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true) + .child(|this: &mut Self, _cx: &mut ViewContext| { + div() + .key_context("nested") + .track_focus(&this.focus_handle) + .render() + }), ) } } @@ -325,7 +330,7 @@ mod test { }); cx.update(|cx| { - cx.bind_keys(vec![KeyBinding::new("ctrl-g", TestAction, None)]); + cx.bind_keys(vec![KeyBinding::new("ctrl-g", TestAction, Some("parent"))]); }); window diff --git a/crates/gpui2/src/keymap/matcher.rs b/crates/gpui2/src/keymap/matcher.rs index bab9c0f5757354b933849ca7b324061df4812cec..a842913aef5969cf291b92c776fe866378a478b7 100644 --- a/crates/gpui2/src/keymap/matcher.rs +++ b/crates/gpui2/src/keymap/matcher.rs @@ -97,6 +97,7 @@ impl KeystrokeMatcher { } } +#[derive(Debug)] pub enum KeyMatch { None, Pending, diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 4ed7f89c7807665601f8bfe915eef56e412f6f74..3832605c3dd02c97d4f8e5b8c2895aafb2837ea3 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1309,6 +1309,7 @@ impl<'a> WindowContext<'a> { .current_frame .dispatch_tree .dispatch_path(node_id); + dbg!(node_id, &dispatch_path, self.propagate_event); // Capture phase for node_id in &dispatch_path { @@ -1328,6 +1329,8 @@ impl<'a> WindowContext<'a> { } } + dbg!(node_id, &dispatch_path, self.propagate_event); + // Bubble phase for node_id in dispatch_path.iter().rev() { let node = self.window.current_frame.dispatch_tree.node(*node_id); @@ -1337,6 +1340,7 @@ impl<'a> WindowContext<'a> { } in node.action_listeners.clone() { let any_action = action.as_any(); + dbg!(action_type, any_action.type_id()); if action_type == any_action.type_id() { self.propagate_event = false; // Actions stop propagation by default during the bubble phase listener(any_action, DispatchPhase::Bubble, self); @@ -2082,11 +2086,10 @@ impl<'a, V: 'static> ViewContext<'a, V> { f: impl FnOnce(Option, &mut Self) -> R, ) -> R { let window = &mut self.window; - window .current_frame .dispatch_tree - .push_node(context, &mut window.previous_frame.dispatch_tree); + .push_node(context.clone(), &mut window.previous_frame.dispatch_tree); if let Some(focus_handle) = focus_handle.as_ref() { window .current_frame