Detailed changes
@@ -920,15 +920,14 @@ impl ContextMenu {
fn render(
&self,
cursor_position: DisplayPoint,
- style: EditorStyle,
+ style: &EditorStyle,
workspace: Option<WeakView<Workspace>>,
cx: &mut ViewContext<Editor>,
) -> (DisplayPoint, AnyElement<Editor>) {
- todo!()
- // match self {
- // ContextMenu::Completions(menu) => (cursor_position, menu.render(style, workspace, cx)),
- // ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, cx),
- // }
+ match self {
+ ContextMenu::Completions(menu) => (cursor_position, menu.render(style, workspace, cx)),
+ ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, cx),
+ }
}
}
@@ -1253,13 +1252,13 @@ impl CompletionsMenu {
fn render(
&self,
- style: EditorStyle,
+ style: &EditorStyle,
workspace: Option<WeakView<Workspace>>,
cx: &mut ViewContext<Editor>,
- ) {
+ ) -> AnyElement<Editor> {
todo!("old implementation below")
}
- // ) -> AnyElement<Editor> {
+
// enum CompletionTag {}
// let settings = EditorSettings>(cx);
@@ -1572,7 +1571,7 @@ impl CodeActionsMenu {
fn render(
&self,
mut cursor_position: DisplayPoint,
- style: EditorStyle,
+ style: &EditorStyle,
cx: &mut ViewContext<Editor>,
) -> (DisplayPoint, AnyElement<Editor>) {
todo!("old version below")
@@ -4480,29 +4479,27 @@ impl Editor {
// }
pub fn context_menu_visible(&self) -> bool {
- false
- // todo!("context menu")
- // self.context_menu
- // .read()
- // .as_ref()
- // .map_or(false, |menu| menu.visible())
+ self.context_menu
+ .read()
+ .as_ref()
+ .map_or(false, |menu| menu.visible())
}
- // pub fn render_context_menu(
- // &self,
- // cursor_position: DisplayPoint,
- // style: EditorStyle,
- // cx: &mut ViewContext<Editor>,
- // ) -> Option<(DisplayPoint, AnyElement<Editor>)> {
- // self.context_menu.read().as_ref().map(|menu| {
- // menu.render(
- // cursor_position,
- // style,
- // self.workspace.as_ref().map(|(w, _)| w.clone()),
- // cx,
- // )
- // })
- // }
+ pub fn render_context_menu(
+ &self,
+ cursor_position: DisplayPoint,
+ style: &EditorStyle,
+ cx: &mut ViewContext<Editor>,
+ ) -> Option<(DisplayPoint, AnyElement<Editor>)> {
+ self.context_menu.read().as_ref().map(|menu| {
+ menu.render(
+ cursor_position,
+ style,
+ self.workspace.as_ref().map(|(w, _)| w.clone()),
+ cx,
+ )
+ })
+ }
fn hide_context_menu(&mut self, cx: &mut ViewContext<Self>) -> Option<ContextMenu> {
cx.notify();
@@ -603,7 +603,7 @@ impl EditorElement {
fn paint_text(
&mut self,
bounds: Bounds<Pixels>,
- layout: &LayoutState,
+ layout: &mut LayoutState,
editor: &mut Editor,
cx: &mut ViewContext<Editor>,
) {
@@ -794,48 +794,46 @@ impl EditorElement {
)
}
- cx.stack(0, |cx| {
+ cx.with_z_index(0, |cx| {
for cursor in cursors {
cursor.paint(content_origin, cx);
}
});
- // cx.scene().push_layer(Some(bounds));
-
- // cx.scene().pop_layer();
-
- // if let Some((position, context_menu)) = layout.context_menu.as_mut() {
- // cx.scene().push_stacking_context(None, None);
- // let cursor_row_layout =
- // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
- // let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
- // let y = (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top;
- // let mut list_origin = content_origin + point(x, y);
- // let list_width = context_menu.size().x;
- // let list_height = context_menu.size().y;
-
- // // Snap the right edge of the list to the right edge of the window if
- // // its horizontal bounds overflow.
- // if list_origin.x + list_width > cx.window_size().x {
- // list_origin.set_x((cx.window_size().x - list_width).max(0.));
- // }
- // if list_origin.y + list_height > bounds.max_y {
- // list_origin
- // .set_y(list_origin.y - layout.position_map.line_height - list_height);
- // }
+ if let Some((position, context_menu)) = layout.context_menu.as_mut() {
+ cx.with_z_index(1, |cx| {
+ let line_height = self.style.text.line_height_in_pixels(cx.rem_size());
+ let available_space = size(
+ AvailableSpace::Definite(cx.viewport_size().width * 0.7),
+ AvailableSpace::Definite(
+ (12. * line_height).min((bounds.size.height - line_height) / 2.),
+ ),
+ );
+ let context_menu_size = context_menu.measure(available_space, editor, cx);
+
+ let cursor_row_layout = &layout.position_map.line_layouts
+ [(position.row() - start_row) as usize]
+ .line;
+ let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
+ let y =
+ (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top;
+ let mut list_origin = content_origin + point(x, y);
+ let list_width = context_menu_size.width;
+ let list_height = context_menu_size.height;
+
+ // Snap the right edge of the list to the right edge of the window if
+ // its horizontal bounds overflow.
+ if list_origin.x + list_width > cx.viewport_size().width {
+ list_origin.x = (cx.viewport_size().width - list_width).max(Pixels::ZERO);
+ }
- // context_menu.paint(
- // list_origin,
- // Bounds::<Pixels>::from_points(
- // gpui::Point::<Pixels>::zero(),
- // point(f32::MAX, f32::MAX),
- // ), // Let content bleed outside of editor
- // editor,
- // cx,
- // );
+ if list_origin.y + list_height > bounds.lower_right().y {
+ list_origin.y -= layout.position_map.line_height - list_height;
+ }
- // cx.scene().pop_stacking_context();
- // }
+ context_menu.draw(list_origin, available_space, editor, cx);
+ })
+ }
// if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() {
// cx.scene().push_stacking_context(None, None);
@@ -1781,15 +1779,14 @@ impl EditorElement {
snapshot = editor.snapshot(cx);
}
- // todo!("context menu")
- // let mut context_menu = None;
+ let mut context_menu = None;
let mut code_actions_indicator = None;
if let Some(newest_selection_head) = newest_selection_head {
if (start_row..end_row).contains(&newest_selection_head.row()) {
- // if editor.context_menu_visible() {
- // context_menu =
- // editor.render_context_menu(newest_selection_head, style.clone(), cx);
- // }
+ if editor.context_menu_visible() {
+ context_menu =
+ editor.render_context_menu(newest_selection_head, &self.style, cx);
+ }
let active = matches!(
editor.context_menu.read().as_ref(),
@@ -1939,7 +1936,7 @@ impl EditorElement {
display_hunks,
// blocks,
selections,
- // context_menu,
+ context_menu,
code_actions_indicator,
// fold_indicators,
tab_invisible,
@@ -2501,21 +2498,24 @@ impl Element<Editor> for EditorElement {
size: layout.text_size,
};
- cx.with_content_mask(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, &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(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);
+ });
});
}
}
@@ -3141,7 +3141,7 @@ pub struct LayoutState {
show_scrollbars: bool,
is_singleton: bool,
max_row: u32,
- // context_menu: Option<(DisplayPoint, AnyElement<Editor>)>,
+ context_menu: Option<(DisplayPoint, AnyElement<Editor>)>,
code_actions_indicator: Option<CodeActionsIndicator>,
// hover_popovers: Option<(DisplayPoint, Vec<AnyElement<Editor>>)>,
// fold_indicators: Vec<Option<AnyElement<Editor>>>,
@@ -200,7 +200,7 @@ pub struct Window {
display_id: DisplayId,
sprite_atlas: Arc<dyn PlatformAtlas>,
rem_size: Pixels,
- content_size: Size<Pixels>,
+ viewport_size: Size<Pixels>,
pub(crate) layout_engine: TaffyLayoutEngine,
pub(crate) root_view: Option<AnyView>,
pub(crate) element_id_stack: GlobalElementId,
@@ -299,7 +299,7 @@ impl Window {
display_id,
sprite_atlas,
rem_size: px(16.),
- content_size,
+ viewport_size: content_size,
layout_engine: TaffyLayoutEngine::new(),
root_view: None,
element_id_stack: GlobalElementId::default(),
@@ -609,7 +609,7 @@ impl<'a> WindowContext<'a> {
fn window_bounds_changed(&mut self) {
self.window.scale_factor = self.window.platform_window.scale_factor();
- self.window.content_size = self.window.platform_window.content_size();
+ self.window.viewport_size = self.window.platform_window.content_size();
self.window.bounds = self.window.platform_window.bounds();
self.window.display_id = self.window.platform_window.display().id();
self.window.dirty = true;
@@ -624,6 +624,10 @@ impl<'a> WindowContext<'a> {
self.window.bounds
}
+ pub fn viewport_size(&self) -> Size<Pixels> {
+ self.window.viewport_size
+ }
+
pub fn is_window_active(&self) -> bool {
self.window.active
}
@@ -717,7 +721,7 @@ impl<'a> WindowContext<'a> {
/// Called during painting to invoke the given closure in a new stacking context. The given
/// z-index is interpreted relative to the previous call to `stack`.
- pub fn stack<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
+ pub fn with_z_index<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
self.window.current_frame.z_index_stack.push(z_index);
let result = f(self);
self.window.current_frame.z_index_stack.pop();
@@ -1015,13 +1019,13 @@ impl<'a> WindowContext<'a> {
self.start_frame();
- self.stack(0, |cx| {
- let available_space = cx.window.content_size.map(Into::into);
+ self.with_z_index(0, |cx| {
+ let available_space = cx.window.viewport_size.map(Into::into);
root_view.draw(available_space, cx);
});
if let Some(active_drag) = self.app.active_drag.take() {
- self.stack(1, |cx| {
+ self.with_z_index(1, |cx| {
let offset = cx.mouse_position() - active_drag.cursor_offset;
cx.with_element_offset(Some(offset), |cx| {
let available_space =
@@ -1031,7 +1035,7 @@ impl<'a> WindowContext<'a> {
});
});
} else if let Some(active_tooltip) = self.app.active_tooltip.take() {
- self.stack(1, |cx| {
+ self.with_z_index(1, |cx| {
cx.with_element_offset(Some(active_tooltip.cursor_offset), |cx| {
let available_space =
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
@@ -1686,7 +1690,7 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
.unwrap_or_else(|| ContentMask {
bounds: Bounds {
origin: Point::default(),
- size: self.window().content_size,
+ size: self.window().viewport_size,
},
})
}