Update rendering of gutter diff hunks to show whether a hunk is staged or not (#26809)

Jakub Charvat created

In the gutter, it seems more intuitive to me for the unstaged hunks to
be hollow, indicating an action left to complete, and the staged hunks
to be filled. I therefore flipped the style of expanded hunks to match
the gutter icons. Is that acceptable? And would it be a breaking change?
If it is not acceptable, then 058dc216d5a284033eebd38d28853f69aa336a55
contains the opposite behaviour, it is not a problem to revert to it.

In the following images, the first hunk is always ~unstaged~ staged and
the second is ~staged~ unstaged.

<img width="138" alt="image"
src="https://github.com/user-attachments/assets/35927069-da90-424a-8988-a4eb984d865f"
/>
<img width="133" alt="image"
src="https://github.com/user-attachments/assets/4edd0e0d-a2b5-453a-8172-47684e065c82"
/>

<br />
<img width="143" alt="image"
src="https://github.com/user-attachments/assets/2f295944-81aa-45f3-a103-c13b92bc2aba"
/>
<img width="133" alt="image"
src="https://github.com/user-attachments/assets/35248218-7104-4059-8742-ae0e54da6c6b"
/>


Release Notes:

- Improved gutter diff hunks to show whether a hunk is staged

Change summary

crates/editor/src/element.rs | 34 ++++++++++++++++++++++++++--------
1 file changed, 26 insertions(+), 8 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -4376,7 +4376,9 @@ impl EditorElement {
                     }),
                 };
 
-                if let Some((hunk_bounds, background_color, corner_radii, _)) = hunk_to_paint {
+                if let Some((hunk_bounds, background_color, corner_radii, status)) = hunk_to_paint {
+                    let unstaged = status.has_secondary_hunk();
+
                     // Flatten the background color with the editor color to prevent
                     // elements below transparent hunks from showing through
                     let flattened_background_color = cx
@@ -4385,13 +4387,29 @@ impl EditorElement {
                         .editor_background
                         .blend(background_color);
 
-                    window.paint_quad(quad(
-                        hunk_bounds,
-                        corner_radii,
-                        flattened_background_color,
-                        Edges::default(),
-                        transparent_black(),
-                    ));
+                    if unstaged {
+                        window.paint_quad(quad(
+                            hunk_bounds,
+                            corner_radii,
+                            flattened_background_color,
+                            Edges::default(),
+                            transparent_black(),
+                        ));
+                    } else {
+                        let flattened_unstaged_background_color = cx
+                            .theme()
+                            .colors()
+                            .editor_background
+                            .blend(background_color.opacity(0.3));
+
+                        window.paint_quad(quad(
+                            hunk_bounds,
+                            corner_radii,
+                            flattened_unstaged_background_color,
+                            Edges::all(Pixels(1.0)),
+                            flattened_background_color,
+                        ));
+                    }
                 }
             }
         });