Render fold indicators in the gutter

This commit is contained in:
Antonio Scandurra 2023-11-15 14:07:37 +01:00
parent c0f43d964c
commit 851a60a68e
2 changed files with 98 additions and 146 deletions

View file

@ -4372,69 +4372,42 @@ impl Editor {
} }
} }
// pub fn render_fold_indicators( pub fn render_fold_indicators(
// &self, &self,
// fold_data: Vec<Option<(FoldStatus, u32, bool)>>, fold_data: Vec<Option<(FoldStatus, u32, bool)>>,
// style: &EditorStyle, style: &EditorStyle,
// gutter_hovered: bool, gutter_hovered: bool,
// line_height: f32, line_height: Pixels,
// gutter_margin: f32, gutter_margin: Pixels,
// cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
// ) -> Vec<Option<AnyElement<Self>>> { ) -> Vec<Option<AnyElement<Self>>> {
// enum FoldIndicators {} fold_data
.iter()
// let style = style.folds.clone(); .enumerate()
.map(|(ix, fold_data)| {
// fold_data fold_data
// .iter() .map(|(fold_status, buffer_row, active)| {
// .enumerate() (active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| {
// .map(|(ix, fold_data)| { let icon = match fold_status {
// fold_data FoldStatus::Folded => ui::Icon::ChevronRight,
// .map(|(fold_status, buffer_row, active)| { FoldStatus::Foldable => ui::Icon::ChevronDown,
// (active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| { };
// MouseEventHandler::new::<FoldIndicators, _>( IconButton::new(ix as usize, icon)
// ix as usize, .on_click(move |editor: &mut Editor, cx| match fold_status {
// cx, FoldStatus::Folded => {
// |mouse_state, _| { editor.unfold_at(&UnfoldAt { buffer_row }, cx);
// Svg::new(match fold_status { }
// FoldStatus::Folded => style.folded_icon.clone(), FoldStatus::Foldable => {
// FoldStatus::Foldable => style.foldable_icon.clone(), editor.fold_at(&FoldAt { buffer_row }, cx);
// }) }
// .with_color( })
// style .render()
// .indicator })
// .in_state(fold_status == FoldStatus::Folded) })
// .style_for(mouse_state) .flatten()
// .color, })
// ) .collect()
// .constrained() }
// .with_width(gutter_margin * style.icon_margin_scale)
// .aligned()
// .constrained()
// .with_height(line_height)
// .with_width(gutter_margin)
// .aligned()
// },
// )
// .with_cursor_style(CursorStyle::PointingHand)
// .with_padding(Padding::uniform(3.))
// .on_click(MouseButton::Left, {
// move |_, editor, cx| match fold_status {
// FoldStatus::Folded => {
// editor.unfold_at(&UnfoldAt { buffer_row }, cx);
// }
// FoldStatus::Foldable => {
// editor.fold_at(&FoldAt { buffer_row }, cx);
// }
// }
// })
// .into_any()
// })
// })
// .flatten()
// })
// .collect()
// }
pub fn context_menu_visible(&self) -> bool { pub fn context_menu_visible(&self) -> bool {
self.context_menu self.context_menu

View file

@ -487,23 +487,26 @@ impl EditorElement {
} }
} }
// todo!("fold indicators") for (ix, fold_indicator) in layout.fold_indicators.iter_mut().enumerate() {
// for (ix, fold_indicator) in layout.fold_indicators.iter_mut().enumerate() { if let Some(fold_indicator) = fold_indicator.as_mut() {
// if let Some(indicator) = fold_indicator.as_mut() { let available_space = size(
// let position = point( AvailableSpace::MinContent,
// bounds.width() - layout.gutter_padding, AvailableSpace::Definite(line_height * 0.55),
// ix as f32 * line_height - (scroll_top % line_height), );
// ); let fold_indicator_size = fold_indicator.measure(available_space, editor, cx);
// let centering_offset = point(
// (layout.gutter_padding + layout.gutter_margin - indicator.size().x) / 2.,
// (line_height - indicator.size().y) / 2.,
// );
// let indicator_origin = bounds.origin + position + centering_offset; let position = point(
bounds.size.width - layout.gutter_padding,
// indicator.paint(indicator_origin, visible_bounds, editor, cx); ix as f32 * line_height - (scroll_top % line_height),
// } );
// } let centering_offset = point(
(layout.gutter_padding + layout.gutter_margin - fold_indicator_size.width) / 2.,
(line_height - fold_indicator_size.height) / 2.,
);
let origin = bounds.origin + position + centering_offset;
fold_indicator.draw(origin, available_space, editor, cx);
}
}
if let Some(indicator) = layout.code_actions_indicator.as_mut() { if let Some(indicator) = layout.code_actions_indicator.as_mut() {
let available_space = size( let available_space = size(
@ -1684,35 +1687,25 @@ impl EditorElement {
ShowScrollbar::Auto => { ShowScrollbar::Auto => {
// Git // Git
(is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot.has_git_diffs()) (is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot.has_git_diffs())
|| ||
// Selections // Selections
(is_singleton && scrollbar_settings.selections && !highlighted_ranges.is_empty()) (is_singleton && scrollbar_settings.selections && !highlighted_ranges.is_empty())
// Scrollmanager // Scrollmanager
|| editor.scroll_manager.scrollbars_visible() || editor.scroll_manager.scrollbars_visible()
} }
ShowScrollbar::System => editor.scroll_manager.scrollbars_visible(), ShowScrollbar::System => editor.scroll_manager.scrollbars_visible(),
ShowScrollbar::Always => true, ShowScrollbar::Always => true,
ShowScrollbar::Never => false, ShowScrollbar::Never => false,
}; };
let fold_ranges: Vec<(BufferRow, Range<DisplayPoint>, Hsla)> = Vec::new(); let fold_ranges: Vec<(BufferRow, Range<DisplayPoint>, Hsla)> = fold_ranges
// todo!() .into_iter()
.map(|(id, fold)| {
// fold_ranges // todo!("change color based on mouse state")
// .into_iter() let color = gpui::red();
// .map(|(id, fold)| { (id, fold, color)
// // todo!("folds!") })
// // let color = self .collect();
// // .style
// // .folds
// // .ellipses
// // .background
// // .style_for(&mut cx.mouse_state::<FoldMarkers>(id as usize))
// // .color;
// // (id, fold, color)
// })
// .collect();
let head_for_relative = newest_selection_head.unwrap_or_else(|| { let head_for_relative = newest_selection_head.unwrap_or_else(|| {
let newest = editor.selections.newest::<Point>(cx); let newest = editor.selections.newest::<Point>(cx);
@ -1754,21 +1747,23 @@ impl EditorElement {
.width; .width;
let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.width; let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.width;
let (scroll_width, blocks) = self.layout_blocks( let (scroll_width, blocks) = cx.with_element_id(Some("editor_blocks"), |cx| {
start_row..end_row, self.layout_blocks(
&snapshot, start_row..end_row,
bounds.size.width, &snapshot,
scroll_width, bounds.size.width,
gutter_padding, scroll_width,
gutter_width, gutter_padding,
em_width, gutter_width,
gutter_width + gutter_margin, em_width,
line_height, gutter_width + gutter_margin,
&style, line_height,
&line_layouts, &style,
editor, &line_layouts,
cx, editor,
); cx,
)
});
let scroll_max = point( let scroll_max = point(
f32::from((scroll_width - text_size.width) / em_width).max(0.0), f32::from((scroll_width - text_size.width) / em_width).max(0.0),
@ -1828,15 +1823,16 @@ impl EditorElement {
// ); // );
// let mode = editor.mode; // let mode = editor.mode;
// todo!("fold_indicators") let mut fold_indicators = cx.with_element_id(Some("gutter_fold_indicators"), |cx| {
// let mut fold_indicators = editor.render_fold_indicators( editor.render_fold_indicators(
// fold_statuses, fold_statuses,
// &style, &style,
// editor.gutter_hovered, editor.gutter_hovered,
// line_height, line_height,
// gutter_margin, gutter_margin,
// cx, cx,
// ); )
});
// todo!("context_menu") // todo!("context_menu")
// if let Some((_, context_menu)) = context_menu.as_mut() { // if let Some((_, context_menu)) = context_menu.as_mut() {
@ -1853,20 +1849,6 @@ impl EditorElement {
// ); // );
// } // }
// todo!("fold indicators")
// for fold_indicator in fold_indicators.iter_mut() {
// if let Some(indicator) = fold_indicator.as_mut() {
// indicator.layout(
// SizeConstraint::strict_along(
// Axis::Vertical,
// line_height * style.code_actions.vertical_scale,
// ),
// editor,
// cx,
// );
// }
// }
// todo!("hover popovers") // todo!("hover popovers")
// if let Some((_, hover_popovers)) = hover.as_mut() { // if let Some((_, hover_popovers)) = hover.as_mut() {
// for hover_popover in hover_popovers.iter_mut() { // for hover_popover in hover_popovers.iter_mut() {
@ -1953,7 +1935,7 @@ impl EditorElement {
selections, selections,
context_menu, context_menu,
code_actions_indicator, code_actions_indicator,
// fold_indicators, fold_indicators,
tab_invisible, tab_invisible,
space_invisible, space_invisible,
// hover_popovers: hover, // hover_popovers: hover,
@ -2019,7 +2001,6 @@ impl EditorElement {
}) })
} }
TransformBlock::ExcerptHeader { TransformBlock::ExcerptHeader {
id,
buffer, buffer,
range, range,
starts_new_buffer, starts_new_buffer,
@ -2041,9 +2022,7 @@ impl EditorElement {
.map_or(range.context.start, |primary| primary.start); .map_or(range.context.start, |primary| primary.start);
let jump_position = language::ToPoint::to_point(&jump_anchor, buffer); let jump_position = language::ToPoint::to_point(&jump_anchor, buffer);
// todo!("avoid ElementId collision risk here") IconButton::new(block_id, ui::Icon::ArrowUpRight)
let icon_button_id: usize = id.clone().into();
IconButton::new(icon_button_id, ui::Icon::ArrowUpRight)
.on_click(move |editor: &mut Editor, cx| { .on_click(move |editor: &mut Editor, cx| {
editor.jump(jump_path.clone(), jump_position, jump_anchor, cx); editor.jump(jump_path.clone(), jump_position, jump_anchor, cx);
}) })
@ -3117,7 +3096,7 @@ pub struct LayoutState {
context_menu: Option<(DisplayPoint, AnyElement<Editor>)>, context_menu: Option<(DisplayPoint, AnyElement<Editor>)>,
code_actions_indicator: Option<CodeActionsIndicator>, code_actions_indicator: Option<CodeActionsIndicator>,
// hover_popovers: Option<(DisplayPoint, Vec<AnyElement<Editor>>)>, // hover_popovers: Option<(DisplayPoint, Vec<AnyElement<Editor>>)>,
// fold_indicators: Vec<Option<AnyElement<Editor>>>, fold_indicators: Vec<Option<AnyElement<Editor>>>,
tab_invisible: Line, tab_invisible: Line,
space_invisible: Line, space_invisible: Line,
} }