From fc8218d7288243ec0a339854d6c981c02877163e Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:14:09 -0300 Subject: [PATCH] project panel: Change marked entries behavior and improve state colors (#25457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow up to @0xtimsb's PR https://github.com/zed-industries/zed/pull/22658. - We're now changing the marked entry as we change the active buffer via the pane tabs. If all tabs are closed, we clear all marked entries, too. That means: if we have no open buffer, we don't have any highlighted entry (i.e., background color) in the project panel. - Also, now only marked entries have a different, more distinct background color. The `is_active` state doesn't change an item's background color anymore. - This improves an edge case where you could have multiple entries marked—where all of them would have a background color—and upon unmarking one of them, that entry would continue to have a bg color. Now, once you click or move your focus to unmark that entry, the bg color goes away. We discovered some new problems by doing these changes that we want to fix: 1. If you open a project without any open buffer, focus on the project panel, navigate with arrows to a given entry, and hit space, you will mark and open the file in the buffer. This is all correct. If you then hit `escape` to clear the marked entries, nothing happens to the open buffer, and the marked styled in the project panel entry go away. This is all correct. The wrong behavior happens if you now hit space _again_ on the active entry. That should mark it, and thus change its styles, but it doesn't happen. You just see it upon moving to a different entry with arrow up/down. 2. If you mark multiple entries on the project panel and then click on an open buffer, we still see all the multiple entries marked. This feels incorrect. We should only allow one marked entry at a time. These fixes should happen in follow up PRs, though. Release Notes: - Improved the scenario where there'd be a project panel entry highlighted/marked even if there is no open buffer. --------- Co-authored-by: smit <0xtimsb@gmail.com> --- crates/project_panel/src/project_panel.rs | 54 +++++++++++------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 078ae81b86..bbac6deca2 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -265,7 +265,7 @@ struct ItemColors { default: Hsla, hover: Hsla, drag_over: Hsla, - marked_active: Hsla, + marked: Hsla, focused: Hsla, } @@ -274,10 +274,10 @@ fn get_item_color(cx: &App) -> ItemColors { ItemColors { default: colors.panel_background, - hover: colors.ghost_element_hover, - drag_over: colors.drop_target_background, - marked_active: colors.element_selected, + hover: colors.element_hover, + marked: colors.element_selected, focused: colors.panel_focused_border, + drag_over: colors.drop_target_background, } } @@ -302,6 +302,9 @@ impl ProjectPanel { this.reveal_entry(project.clone(), *entry_id, true, cx); } } + project::Event::ActiveEntryChanged(None) => { + this.marked_entries.clear(); + } project::Event::RevealInProjectPanel(entry_id) => { this.reveal_entry(project.clone(), *entry_id, false, cx); cx.emit(PanelEvent::Activate); @@ -3546,18 +3549,16 @@ impl ProjectPanel { marked_selections: selections, }; - let bg_color = if is_marked || is_active { - item_colors.marked_active + let bg_color = if is_marked { + item_colors.marked } else { item_colors.default }; - let bg_hover_color = if self.mouse_down || is_marked || is_active { - item_colors.marked_active - } else if !is_active { - item_colors.hover + let bg_hover_color = if is_marked { + item_colors.marked } else { - item_colors.default + item_colors.hover }; let border_color = @@ -4235,16 +4236,11 @@ impl ProjectPanel { let worktree_id = worktree.id(); self.expand_entry(worktree_id, entry_id, cx); self.update_visible_entries(Some((worktree_id, entry_id)), cx); - - if self.marked_entries.len() == 1 - && self - .marked_entries - .first() - .filter(|entry| entry.entry_id == entry_id) - .is_none() - { - self.marked_entries.clear(); - } + self.marked_entries.clear(); + self.marked_entries.insert(SelectedEntry { + worktree_id, + entry_id, + }); self.autoscroll(cx); cx.notify(); } @@ -7333,7 +7329,7 @@ mod tests { select_path(&panel, "root/new", cx); assert_eq!( visible_entries_as_strings(&panel, 0..10, cx), - &["v root", " new <== selected"] + &["v root", " new <== selected <== marked"] ); panel.update_in(cx, |panel, window, cx| panel.rename(&Rename, window, cx)); panel.update_in(cx, |panel, window, cx| { @@ -7767,7 +7763,7 @@ mod tests { " > .git", " v dir_1", " > gitignored_dir", - " file_1.py <== selected", + " file_1.py <== selected <== marked", " file_2.py", " file_3.py", " > dir_2", @@ -7793,7 +7789,7 @@ mod tests { " file_2.py", " file_3.py", " v dir_2", - " file_1.py <== selected", + " file_1.py <== selected <== marked", " file_2.py", " file_3.py", " .gitignore", @@ -7820,7 +7816,7 @@ mod tests { " file_2.py", " file_3.py", " v dir_2", - " file_1.py <== selected", + " file_1.py <== selected <== marked", " file_2.py", " file_3.py", " .gitignore", @@ -7841,7 +7837,7 @@ mod tests { " > .git", " v dir_1", " v gitignored_dir", - " file_a.py <== selected", + " file_a.py <== selected <== marked", " file_b.py", " file_c.py", " file_1.py", @@ -7996,7 +7992,7 @@ mod tests { " > .git", " v dir_1", " > gitignored_dir", - " file_1.py <== selected", + " file_1.py <== selected <== marked", " file_2.py", " file_3.py", " > dir_2", @@ -8022,7 +8018,7 @@ mod tests { " file_2.py", " file_3.py", " v dir_2", - " file_1.py <== selected", + " file_1.py <== selected <== marked", " file_2.py", " file_3.py", " .gitignore", @@ -8043,7 +8039,7 @@ mod tests { " > .git", " v dir_1", " v gitignored_dir", - " file_a.py <== selected", + " file_a.py <== selected <== marked", " file_b.py", " file_c.py", " file_1.py",