tab_switcher: Use git-aware colors for file icons (#18733)
Release Notes: - Fixed tab switcher icons not respecting the `tabs.git_status` setting. Fixes an issue mentioned in https://github.com/zed-industries/zed/pull/17115#issuecomment-2378966170 - file icons in the tab switcher weren't colored according to git status, even if `tabs.git_status` was set to true. I used a similar approach I saw in other places of the project to get the project entry and its git status, but maybe we could move the coloring logic entirely to `tab_icon()`? Wouldn't this break anything? --------- Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
parent
9702310737
commit
d695de4504
3 changed files with 39 additions and 8 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -11412,6 +11412,7 @@ dependencies = [
|
||||||
"project",
|
"project",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"settings",
|
||||||
"theme",
|
"theme",
|
||||||
"ui",
|
"ui",
|
||||||
"util",
|
"util",
|
||||||
|
|
|
@ -14,10 +14,13 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
collections.workspace = true
|
collections.workspace = true
|
||||||
|
editor.workspace = true
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
menu.workspace = true
|
menu.workspace = true
|
||||||
picker.workspace = true
|
picker.workspace = true
|
||||||
|
project.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
settings.workspace = true
|
||||||
ui.workspace = true
|
ui.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
workspace.workspace = true
|
workspace.workspace = true
|
||||||
|
@ -25,11 +28,9 @@ workspace.workspace = true
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
ctor.workspace = true
|
ctor.workspace = true
|
||||||
editor.workspace = true
|
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
gpui = { workspace = true, features = ["test-support"] }
|
gpui = { workspace = true, features = ["test-support"] }
|
||||||
language = { workspace = true, features = ["test-support"] }
|
language = { workspace = true, features = ["test-support"] }
|
||||||
project.workspace = true
|
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
theme = { workspace = true, features = ["test-support"] }
|
theme = { workspace = true, features = ["test-support"] }
|
||||||
workspace = { workspace = true, features = ["test-support"] }
|
workspace = { workspace = true, features = ["test-support"] }
|
||||||
|
|
|
@ -2,18 +2,21 @@
|
||||||
mod tab_switcher_tests;
|
mod tab_switcher_tests;
|
||||||
|
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
use editor::items::entry_git_aware_label_color;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, impl_actions, rems, Action, AnyElement, AppContext, DismissEvent, EntityId,
|
actions, impl_actions, rems, Action, AnyElement, AppContext, DismissEvent, EntityId,
|
||||||
EventEmitter, FocusHandle, FocusableView, Modifiers, ModifiersChangedEvent, MouseButton,
|
EventEmitter, FocusHandle, FocusableView, Model, Modifiers, ModifiersChangedEvent, MouseButton,
|
||||||
MouseUpEvent, ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, WeakView,
|
MouseUpEvent, ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, WeakView,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
|
use project::Project;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use settings::Settings;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ui::{prelude::*, ListItem, ListItemSpacing, Tooltip};
|
use ui::{prelude::*, ListItem, ListItemSpacing, Tooltip};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{ItemHandle, TabContentParams},
|
item::{ItemHandle, ItemSettings, TabContentParams},
|
||||||
pane::{render_item_indicator, tab_details, Event as PaneEvent},
|
pane::{render_item_indicator, tab_details, Event as PaneEvent},
|
||||||
ModalView, Pane, SaveIntent, Workspace,
|
ModalView, Pane, SaveIntent, Workspace,
|
||||||
};
|
};
|
||||||
|
@ -76,8 +79,10 @@ impl TabSwitcher {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let project = workspace.project().clone();
|
||||||
workspace.toggle_modal(cx, |cx| {
|
workspace.toggle_modal(cx, |cx| {
|
||||||
let delegate = TabSwitcherDelegate::new(action, cx.view().downgrade(), weak_pane, cx);
|
let delegate =
|
||||||
|
TabSwitcherDelegate::new(project, action, cx.view().downgrade(), weak_pane, cx);
|
||||||
TabSwitcher::new(delegate, cx)
|
TabSwitcher::new(delegate, cx)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -147,11 +152,13 @@ pub struct TabSwitcherDelegate {
|
||||||
tab_switcher: WeakView<TabSwitcher>,
|
tab_switcher: WeakView<TabSwitcher>,
|
||||||
selected_index: usize,
|
selected_index: usize,
|
||||||
pane: WeakView<Pane>,
|
pane: WeakView<Pane>,
|
||||||
|
project: Model<Project>,
|
||||||
matches: Vec<TabMatch>,
|
matches: Vec<TabMatch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TabSwitcherDelegate {
|
impl TabSwitcherDelegate {
|
||||||
fn new(
|
fn new(
|
||||||
|
project: Model<Project>,
|
||||||
action: &Toggle,
|
action: &Toggle,
|
||||||
tab_switcher: WeakView<TabSwitcher>,
|
tab_switcher: WeakView<TabSwitcher>,
|
||||||
pane: WeakView<Pane>,
|
pane: WeakView<Pane>,
|
||||||
|
@ -163,6 +170,7 @@ impl TabSwitcherDelegate {
|
||||||
tab_switcher,
|
tab_switcher,
|
||||||
selected_index: 0,
|
selected_index: 0,
|
||||||
pane,
|
pane,
|
||||||
|
project,
|
||||||
matches: Vec::new(),
|
matches: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,6 +349,29 @@ impl PickerDelegate for TabSwitcherDelegate {
|
||||||
preview: tab_match.preview,
|
preview: tab_match.preview,
|
||||||
};
|
};
|
||||||
let label = tab_match.item.tab_content(params, cx);
|
let label = tab_match.item.tab_content(params, cx);
|
||||||
|
|
||||||
|
let icon = tab_match.item.tab_icon(cx).map(|icon| {
|
||||||
|
let git_status_color = ItemSettings::get_global(cx)
|
||||||
|
.git_status
|
||||||
|
.then(|| {
|
||||||
|
tab_match
|
||||||
|
.item
|
||||||
|
.project_path(cx)
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|path| self.project.read(cx).entry_for_path(path, cx))
|
||||||
|
.map(|entry| {
|
||||||
|
entry_git_aware_label_color(
|
||||||
|
entry.git_status,
|
||||||
|
entry.is_ignored,
|
||||||
|
selected,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
icon.color(git_status_color.unwrap_or_default())
|
||||||
|
});
|
||||||
|
|
||||||
let indicator = render_item_indicator(tab_match.item.boxed_clone(), cx);
|
let indicator = render_item_indicator(tab_match.item.boxed_clone(), cx);
|
||||||
let indicator_color = if let Some(ref indicator) = indicator {
|
let indicator_color = if let Some(ref indicator) = indicator {
|
||||||
indicator.color
|
indicator.color
|
||||||
|
@ -378,9 +409,7 @@ impl PickerDelegate for TabSwitcherDelegate {
|
||||||
.inset(true)
|
.inset(true)
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.child(h_flex().w_full().child(label))
|
.child(h_flex().w_full().child(label))
|
||||||
.when_some(tab_match.item.tab_icon(cx), |el, icon| {
|
.start_slot::<Icon>(icon)
|
||||||
el.start_slot(div().child(icon))
|
|
||||||
})
|
|
||||||
.map(|el| {
|
.map(|el| {
|
||||||
if self.selected_index == ix {
|
if self.selected_index == ix {
|
||||||
el.end_slot::<AnyElement>(close_button)
|
el.end_slot::<AnyElement>(close_button)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue