Adjusted code-folding behavior

Mikayla Maki created

Change summary

crates/editor/src/editor.rs    | 89 +++++++++++++++++++++--------------
crates/editor/src/element.rs   |  9 +++
crates/theme/src/theme.rs      |  3 +
styles/src/styleTree/editor.ts |  3 +
4 files changed, 66 insertions(+), 38 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -2698,52 +2698,67 @@ impl Editor {
         &self,
         fold_data: Option<Vec<(u32, FoldStatus)>>,
         style: &EditorStyle,
-        _gutter_hovered: bool,
+        gutter_hovered: bool,
+        line_height: f32,
+        gutter_margin: f32,
         cx: &mut RenderContext<Self>,
     ) -> Option<Vec<(u32, ElementBox)>> {
         enum FoldIndicators {}
 
+        let style = style.folds.clone();
+
         fold_data.map(|fold_data| {
             fold_data
                 .iter()
                 .copied()
-                .map(|(fold_location, fold_status)| {
-                    (
-                        fold_location,
-                        MouseEventHandler::<FoldIndicators>::new(
-                            fold_location as usize,
-                            cx,
-                            |mouse_state, _| -> ElementBox {
-                                Svg::new(match fold_status {
-                                    FoldStatus::Folded => "icons/chevron_right_8.svg",
-                                    FoldStatus::Foldable => "icons/chevron_down_8.svg",
-                                })
-                                .with_color(
-                                    style
-                                        .folds
-                                        .indicator
-                                        .style_for(mouse_state, fold_status == FoldStatus::Folded)
-                                        .color,
-                                )
-                                .boxed()
-                            },
+                .filter_map(|(fold_location, fold_status)| {
+                    (gutter_hovered || fold_status == FoldStatus::Folded).then(|| {
+                        (
+                            fold_location,
+                            MouseEventHandler::<FoldIndicators>::new(
+                                fold_location as usize,
+                                cx,
+                                |mouse_state, _| -> ElementBox {
+                                    Svg::new(match fold_status {
+                                        FoldStatus::Folded => style.folded_icon.clone(),
+                                        FoldStatus::Foldable => style.foldable_icon.clone(),
+                                    })
+                                    .with_color(
+                                        style
+                                            .indicator
+                                            .style_for(
+                                                mouse_state,
+                                                fold_status == FoldStatus::Folded,
+                                            )
+                                            .color,
+                                    )
+                                    .constrained()
+                                    .with_width(style.icon_width)
+                                    .aligned()
+                                    .constrained()
+                                    .with_height(line_height)
+                                    .with_width(gutter_margin)
+                                    .aligned()
+                                    .boxed()
+                                },
+                            )
+                            .with_cursor_style(CursorStyle::PointingHand)
+                            .with_padding(Padding::uniform(3.))
+                            .on_click(MouseButton::Left, {
+                                move |_, cx| {
+                                    cx.dispatch_any_action(match fold_status {
+                                        FoldStatus::Folded => Box::new(UnfoldAt {
+                                            display_row: DisplayRow::new(fold_location),
+                                        }),
+                                        FoldStatus::Foldable => Box::new(FoldAt {
+                                            display_row: DisplayRow::new(fold_location),
+                                        }),
+                                    });
+                                }
+                            })
+                            .boxed(),
                         )
-                        .with_cursor_style(CursorStyle::PointingHand)
-                        .with_padding(Padding::uniform(3.))
-                        .on_click(MouseButton::Left, {
-                            move |_, cx| {
-                                cx.dispatch_any_action(match fold_status {
-                                    FoldStatus::Folded => Box::new(UnfoldAt {
-                                        display_row: DisplayRow::new(fold_location),
-                                    }),
-                                    FoldStatus::Foldable => Box::new(FoldAt {
-                                        display_row: DisplayRow::new(fold_location),
-                                    }),
-                                });
-                            }
-                        })
-                        .boxed(),
-                    )
+                    })
                 })
                 .collect()
         })

crates/editor/src/element.rs 🔗

@@ -1829,7 +1829,14 @@ impl Element for EditorElement {
             hover = view.hover_state.render(&snapshot, &style, visible_rows, cx);
             mode = view.mode;
 
-            view.render_fold_indicators(folds, &style, view.gutter_hovered, cx)
+            view.render_fold_indicators(
+                folds,
+                &style,
+                view.gutter_hovered,
+                line_height,
+                gutter_margin,
+                cx,
+            )
         });
 
         if let Some((_, context_menu)) = context_menu.as_mut() {

crates/theme/src/theme.rs 🔗

@@ -643,6 +643,9 @@ pub struct CodeActions {
 pub struct Folds {
     pub indicator: Interactive<Indicator>,
     pub fold_background: Color,
+    pub icon_width: f32,
+    pub folded_icon: String,
+    pub foldable_icon: String,
 }
 
 #[derive(Clone, Deserialize, Default)]

styles/src/styleTree/editor.ts 🔗

@@ -60,6 +60,9 @@ export default function editor(colorScheme: ColorScheme) {
             verticalScale: 0.55,
         },
         folds: {
+            iconWidth: 8,
+            foldedIcon: "icons/chevron_right_8.svg",
+            foldableIcon: "icons/chevron_down_8.svg",
             indicator: {
                 color: foreground(layer, "variant"),