Refine split diff icons (#53022)

Danilo Leal created

Follow-up to https://github.com/zed-industries/zed/pull/52781, adding
some different icons to better express the state in which the split diff
_is selected_ but _isn't active_, which happens when the editor is
smaller than a given amount of defined columns.


https://github.com/user-attachments/assets/2e7aaf6c-077f-4be5-9439-ce6c2050e63d

Release Notes:

- N/A

Change summary

assets/icons/diff_split.svg        |   5 
assets/icons/diff_split_auto.svg   |   7 +
assets/icons/diff_unified.svg      |   4 
crates/icons/src/icons.rs          |   1 
crates/search/src/buffer_search.rs | 144 ++++++++++++++++---------------
5 files changed, 87 insertions(+), 74 deletions(-)

Detailed changes

assets/icons/diff_split.svg 🔗

@@ -1,5 +1,4 @@
 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M5.25 3H3.75C3.33579 3 3 3.33579 3 3.75V12.25C3 12.6642 3.33579 13 3.75 13H5.25C5.66421 13 6 12.6642 6 12.25V3.75C6 3.33579 5.66421 3 5.25 3Z" fill="#C6CAD0"/>
-<path opacity="0.7" d="M8.5 2.5C8.5 2.22386 8.27614 2 8 2C7.72386 2 7.5 2.22386 7.5 2.5V13.5C7.5 13.7761 7.72386 14 8 14C8.27614 14 8.5 13.7761 8.5 13.5V2.5Z" fill="#C6CAD0"/>
-<path d="M12.25 3H10.75C10.3358 3 10 3.33579 10 3.75V12.25C10 12.6642 10.3358 13 10.75 13H12.25C12.6642 13 13 12.6642 13 12.25V3.75C13 3.33579 12.6642 3 12.25 3Z" fill="#C6CAD0"/>
+<rect x="6.4" y="2.6" width="10.8" height="3.8" rx="0.9" transform="rotate(90 6.4 2.6)" fill="#C6CAD0" fill-opacity="0.5" stroke="#C6CAD0" stroke-width="1.2"/>
+<rect x="13.4" y="2.6" width="10.8" height="3.8" rx="0.9" transform="rotate(90 13.4 2.6)" fill="#C6CAD0" stroke="#C6CAD0" stroke-width="1.2"/>
 </svg>

assets/icons/diff_split_auto.svg 🔗

@@ -0,0 +1,7 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect opacity="0.5" x="14" y="2" width="12" height="5" rx="1.5" transform="rotate(90 14 2)" fill="#C6CAD0" fill-opacity="0.2"/>
+<rect opacity="0.5" x="7" y="2" width="12" height="5" rx="1.5" transform="rotate(90 7 2)" fill="#C6CAD0" fill-opacity="0.2"/>
+<path d="M10.2002 12.5C10.2002 12.6657 10.3343 12.7998 10.5 12.7998H12.3125L13.4951 13.4824C13.5254 13.4999 13.557 13.5142 13.5879 13.5293C13.3145 13.8182 12.9291 14 12.5 14H10.5L10.3467 13.9922C9.59028 13.9154 9 13.2767 9 12.5V10.8867L10.2002 11.5791V12.5ZM10.2002 6.95996L9 6.26758V3.5C9 2.72334 9.59028 2.08461 10.3467 2.00781L10.5 2H12.5C13.3284 2 14 2.67157 14 3.5V9.1543L12.7998 8.46094V3.5C12.7998 3.33431 12.6657 3.2002 12.5 3.2002H10.5C10.3343 3.2002 10.2002 3.33431 10.2002 3.5V6.95996Z" fill="#C6CAD0"/>
+<path d="M7 9.73242V12.5C7 13.3284 6.32843 14 5.5 14H3.5L3.34668 13.9922C2.59028 13.9154 2 13.2767 2 12.5V6.84473L3.2002 7.53809V12.5C3.2002 12.6657 3.33431 12.7998 3.5 12.7998H5.5C5.66569 12.7998 5.7998 12.6657 5.7998 12.5V9.03906L7 9.73242ZM5.5 2C6.32843 2 7 2.67157 7 3.5V5.1123L5.7998 4.41992V3.5C5.7998 3.33431 5.66569 3.2002 5.5 3.2002H3.6875L2.50488 2.51758C2.47399 2.49975 2.44173 2.48513 2.41016 2.46973C2.65063 2.21547 2.97893 2.04515 3.34668 2.00781L3.5 2H5.5Z" fill="#C6CAD0"/>
+<rect x="0.427673" y="4.78281" width="2" height="16.3329" rx="0.5" transform="rotate(-60 0.427673 4.78281)" fill="#C6CAD0"/>
+</svg>

assets/icons/diff_unified.svg 🔗

@@ -1,4 +1,4 @@
 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M12 3H4C3.44772 3 3 3.44772 3 4V6C3 6.55228 3.44772 7 4 7H12C12.5523 7 13 6.55228 13 6V4C13 3.44772 12.5523 3 12 3Z" fill="#C6CAD0"/>
-<path d="M12 9.5H4C3.72386 9.5 3.5 9.72386 3.5 10V12C3.5 12.2761 3.72386 12.5 4 12.5H12C12.2761 12.5 12.5 12.2761 12.5 12V10C12.5 9.72386 12.2761 9.5 12 9.5Z" fill="#C6CAD0" fill-opacity="0.12" stroke="#C6CAD0" stroke-width="1.2"/>
+<rect x="2.6" y="9.6" width="10.8" height="3.8" rx="0.9" fill="#C6CAD0" fill-opacity="0.5" stroke="#C6CAD0" stroke-width="1.2"/>
+<rect x="2" y="2" width="12" height="5" rx="1.5" fill="#C6CAD0"/>
 </svg>

crates/icons/src/icons.rs 🔗

@@ -95,6 +95,7 @@ pub enum IconName {
     DebugStepOver,
     Diff,
     DiffSplit,
+    DiffSplitAuto,
     DiffUnified,
     Disconnected,
     Download,

crates/search/src/buffer_search.rs 🔗

@@ -114,81 +114,23 @@ impl Render for BufferSearchBar {
                 .map(|splittable_editor| {
                     let editor_ref = splittable_editor.read(cx);
                     let diff_view_style = editor_ref.diff_view_style();
-                    let is_split = editor_ref.is_split();
+
+                    let is_split_set = diff_view_style == DiffViewStyle::Split;
+                    let is_split_active = editor_ref.is_split();
                     let min_columns =
                         EditorSettings::get_global(cx).minimum_split_diff_width as u32;
 
-                    let mut split_button = IconButton::new("diff-split", IconName::DiffSplit)
-                        .shape(IconButtonShape::Square)
-                        .tooltip(Tooltip::element(move |_, cx| {
-                            let message = if min_columns == 0 {
-                                SharedString::from("Split")
-                            } else {
-                                format!("Split when wider than {} columns", min_columns).into()
-                            };
-
-                            v_flex()
-                                .child(message)
-                                .child(
-                                    h_flex()
-                                        .gap_0p5()
-                                        .text_ui_sm(cx)
-                                        .text_color(Color::Muted.color(cx))
-                                        .children(render_modifiers(
-                                            &gpui::Modifiers::secondary_key(),
-                                            PlatformStyle::platform(),
-                                            None,
-                                            Some(TextSize::Small.rems(cx).into()),
-                                            false,
-                                        ))
-                                        .child("click to change min width"),
-                                )
-                                .into_any()
-                        }))
-                        .on_click({
-                            let splittable_editor = splittable_editor.downgrade();
-                            move |_, window, cx| {
-                                if window.modifiers().secondary() {
-                                    window.dispatch_action(
-                                        OpenSettingsAt {
-                                            path: "minimum_split_diff_width".to_string(),
-                                        }
-                                        .boxed_clone(),
-                                        cx,
-                                    );
-                                } else {
-                                    update_settings_file(
-                                        <dyn Fs>::global(cx),
-                                        cx,
-                                        |settings, _| {
-                                            settings.editor.diff_view_style =
-                                                Some(DiffViewStyle::Split);
-                                        },
-                                    );
-                                    if diff_view_style == DiffViewStyle::Unified {
-                                        splittable_editor
-                                            .update(cx, |editor, cx| {
-                                                editor.toggle_split(&ToggleSplitDiff, window, cx);
-                                            })
-                                            .ok();
-                                    }
-                                }
-                            }
-                        });
-
-                    if diff_view_style == DiffViewStyle::Split {
-                        if !is_split {
-                            split_button = split_button.icon_color(Color::Disabled)
-                        } else {
-                            split_button = split_button.toggle_state(true)
-                        }
-                    }
+                    let split_icon = if is_split_set && !is_split_active {
+                        IconName::DiffSplitAuto
+                    } else {
+                        IconName::DiffSplit
+                    };
 
                     h_flex()
                         .gap_1()
                         .child(
                             IconButton::new("diff-unified", IconName::DiffUnified)
-                                .shape(IconButtonShape::Square)
+                                .icon_size(IconSize::Small)
                                 .toggle_state(diff_view_style == DiffViewStyle::Unified)
                                 .tooltip(Tooltip::text("Unified"))
                                 .on_click({
@@ -216,7 +158,71 @@ impl Render for BufferSearchBar {
                                     }
                                 }),
                         )
-                        .child(split_button)
+                        .child(
+                            IconButton::new("diff-split", split_icon)
+                                .toggle_state(diff_view_style == DiffViewStyle::Split)
+                                .icon_size(IconSize::Small)
+                                .tooltip(Tooltip::element(move |_, cx| {
+                                    let message = if is_split_set && !is_split_active {
+                                        format!("Split when wider than {} columns", min_columns)
+                                            .into()
+                                    } else {
+                                        SharedString::from("Split")
+                                    };
+
+                                    v_flex()
+                                        .child(message)
+                                        .child(
+                                            h_flex()
+                                                .gap_0p5()
+                                                .text_ui_sm(cx)
+                                                .text_color(Color::Muted.color(cx))
+                                                .children(render_modifiers(
+                                                    &gpui::Modifiers::secondary_key(),
+                                                    PlatformStyle::platform(),
+                                                    None,
+                                                    Some(TextSize::Small.rems(cx).into()),
+                                                    false,
+                                                ))
+                                                .child("click to change min width"),
+                                        )
+                                        .into_any()
+                                }))
+                                .on_click({
+                                    let splittable_editor = splittable_editor.downgrade();
+                                    move |_, window, cx| {
+                                        if window.modifiers().secondary() {
+                                            window.dispatch_action(
+                                                OpenSettingsAt {
+                                                    path: "minimum_split_diff_width".to_string(),
+                                                }
+                                                .boxed_clone(),
+                                                cx,
+                                            );
+                                        } else {
+                                            update_settings_file(
+                                                <dyn Fs>::global(cx),
+                                                cx,
+                                                |settings, _| {
+                                                    settings.editor.diff_view_style =
+                                                        Some(DiffViewStyle::Split);
+                                                },
+                                            );
+                                            if diff_view_style == DiffViewStyle::Unified {
+                                                splittable_editor
+                                                    .update(cx, |editor, cx| {
+                                                        editor.toggle_split(
+                                                            &ToggleSplitDiff,
+                                                            window,
+                                                            cx,
+                                                        );
+                                                    })
+                                                    .ok();
+                                            }
+                                        }
+                                    }
+                                }),
+                        )
                 })
         } else {
             None
@@ -240,7 +246,7 @@ impl Render for BufferSearchBar {
 
             let collapse_expand_icon_button = |id| {
                 IconButton::new(id, icon)
-                    .shape(IconButtonShape::Square)
+                    .icon_size(IconSize::Small)
                     .tooltip(move |_, cx| {
                         Tooltip::for_action_in(
                             tooltip_label,