WIP
This commit is contained in:
@@ -32,7 +32,9 @@ pub struct CommandPalette {
|
||||
|
||||
impl CommandPalette {
|
||||
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -2446,7 +2446,7 @@ impl Element<Editor> for EditorElement {
|
||||
type ElementState = ();
|
||||
|
||||
fn element_id(&self) -> Option<gpui::ElementId> {
|
||||
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<Editor> for EditorElement {
|
||||
cx: &mut gpui::ViewContext<Editor>,
|
||||
) -> 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<Editor>,
|
||||
) -> 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<gpui::Pixels>,
|
||||
editor: &mut Editor,
|
||||
element_state: &mut Self::ElementState,
|
||||
cx: &mut gpui::ViewContext<Editor>,
|
||||
) {
|
||||
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<Editor> for EditorElement {
|
||||
register_action(cx, Editor::context_menu_prev);
|
||||
register_action(cx, Editor::context_menu_next);
|
||||
register_action(cx, Editor::context_menu_last);
|
||||
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
},
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
editor: &mut Editor,
|
||||
element_state: &mut Self::ElementState,
|
||||
cx: &mut gpui::ViewContext<Editor>,
|
||||
) -> 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<gpui::Pixels>,
|
||||
editor: &mut Editor,
|
||||
element_state: &mut Self::ElementState,
|
||||
cx: &mut gpui::ViewContext<Editor>,
|
||||
) {
|
||||
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);
|
||||
});
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,6 +612,7 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||
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<V>) -> 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)
|
||||
}
|
||||
|
||||
@@ -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>) -> 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<Self>| {
|
||||
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
|
||||
|
||||
@@ -97,6 +97,7 @@ impl KeystrokeMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum KeyMatch {
|
||||
None,
|
||||
Pending,
|
||||
|
||||
@@ -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<FocusHandle>, &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
|
||||
|
||||
Reference in New Issue
Block a user