Fix inactive tab styles (the verbose way) (#3591)
This PR fixes the inactive tab style to properly show the label using the muted text color. I went about fixing this in the most direct way possible, but the solution leaves a lot to be desired, IMO. I plan to explore some ideas on how we can improve the state of styling the tab content without having the same styles repeated all over the place and subsequently out-of-sync. Release Notes: - N/A
This commit is contained in:
parent
fcbc18a380
commit
f02a3e8c68
9 changed files with 108 additions and 59 deletions
|
@ -17,7 +17,7 @@ use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use ui::Label;
|
use ui::{prelude::*, Label};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{FollowableItem, Item, ItemEvent, ItemHandle},
|
item::{FollowableItem, Item, ItemEvent, ItemHandle},
|
||||||
|
@ -253,7 +253,7 @@ impl Item for ChannelView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, _: Option<usize>, cx: &WindowContext) -> AnyElement {
|
fn tab_content(&self, _: Option<usize>, selected: bool, cx: &WindowContext) -> AnyElement {
|
||||||
let label = if let Some(channel) = self.channel(cx) {
|
let label = if let Some(channel) = self.channel(cx) {
|
||||||
match (
|
match (
|
||||||
channel.can_edit_notes(),
|
channel.can_edit_notes(),
|
||||||
|
@ -266,7 +266,13 @@ impl Item for ChannelView {
|
||||||
} else {
|
} else {
|
||||||
format!("channel notes (disconnected)")
|
format!("channel notes (disconnected)")
|
||||||
};
|
};
|
||||||
Label::new(label).into_any_element()
|
Label::new(label)
|
||||||
|
.color(if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
})
|
||||||
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<View<Self>> {
|
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<View<Self>> {
|
||||||
|
|
|
@ -633,8 +633,44 @@ impl Item for ProjectDiagnosticsEditor {
|
||||||
Some("Project Diagnostics".into())
|
Some("Project Diagnostics".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, _detail: Option<usize>, _: &WindowContext) -> AnyElement {
|
fn tab_content(&self, _detail: Option<usize>, selected: bool, _: &WindowContext) -> AnyElement {
|
||||||
render_summary(&self.summary)
|
if self.summary.error_count == 0 && self.summary.warning_count == 0 {
|
||||||
|
let label = Label::new("No problems");
|
||||||
|
label.into_any_element()
|
||||||
|
} else {
|
||||||
|
h_stack()
|
||||||
|
.gap_1()
|
||||||
|
.when(self.summary.error_count > 0, |then| {
|
||||||
|
then.child(
|
||||||
|
h_stack()
|
||||||
|
.gap_1()
|
||||||
|
.child(IconElement::new(Icon::XCircle).color(Color::Error))
|
||||||
|
.child(Label::new(self.summary.error_count.to_string()).color(
|
||||||
|
if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.when(self.summary.warning_count > 0, |then| {
|
||||||
|
then.child(
|
||||||
|
h_stack()
|
||||||
|
.child(
|
||||||
|
IconElement::new(Icon::ExclamationTriangle).color(Color::Warning),
|
||||||
|
)
|
||||||
|
.child(Label::new(self.summary.warning_count.to_string()).color(
|
||||||
|
if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.into_any_element()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_project_item(
|
fn for_each_project_item(
|
||||||
|
@ -782,32 +818,6 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn render_summary(summary: &DiagnosticSummary) -> AnyElement {
|
|
||||||
if summary.error_count == 0 && summary.warning_count == 0 {
|
|
||||||
let label = Label::new("No problems");
|
|
||||||
label.into_any_element()
|
|
||||||
} else {
|
|
||||||
h_stack()
|
|
||||||
.gap_1()
|
|
||||||
.when(summary.error_count > 0, |then| {
|
|
||||||
then.child(
|
|
||||||
h_stack()
|
|
||||||
.gap_1()
|
|
||||||
.child(IconElement::new(Icon::XCircle).color(Color::Error))
|
|
||||||
.child(Label::new(summary.error_count.to_string())),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.when(summary.warning_count > 0, |then| {
|
|
||||||
then.child(
|
|
||||||
h_stack()
|
|
||||||
.child(IconElement::new(Icon::ExclamationTriangle).color(Color::Warning))
|
|
||||||
.child(Label::new(summary.warning_count.to_string())),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.into_any_element()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compare_diagnostics<L: language::ToOffset, R: language::ToOffset>(
|
fn compare_diagnostics<L: language::ToOffset, R: language::ToOffset>(
|
||||||
lhs: &DiagnosticEntry<L>,
|
lhs: &DiagnosticEntry<L>,
|
||||||
rhs: &DiagnosticEntry<R>,
|
rhs: &DiagnosticEntry<R>,
|
||||||
|
|
|
@ -580,7 +580,7 @@ impl Item for Editor {
|
||||||
Some(path.to_string_lossy().to_string().into())
|
Some(path.to_string_lossy().to_string().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement {
|
fn tab_content(&self, detail: Option<usize>, selected: bool, cx: &WindowContext) -> AnyElement {
|
||||||
let theme = cx.theme();
|
let theme = cx.theme();
|
||||||
|
|
||||||
let description = detail.and_then(|detail| {
|
let description = detail.and_then(|detail| {
|
||||||
|
@ -597,7 +597,11 @@ impl Item for Editor {
|
||||||
|
|
||||||
h_stack()
|
h_stack()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.child(Label::new(self.title(cx).to_string()))
|
.child(Label::new(self.title(cx).to_string()).color(if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
}))
|
||||||
.when_some(description, |this, description| {
|
.when_some(description, |this, description| {
|
||||||
this.child(Label::new(description).color(Color::Muted))
|
this.child(Label::new(description).color(Color::Muted))
|
||||||
})
|
})
|
||||||
|
|
|
@ -33,8 +33,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ui::{
|
use ui::{
|
||||||
h_stack, v_stack, Button, ButtonCommon, Clickable, Disableable, Icon, IconButton, IconElement,
|
h_stack, prelude::*, v_stack, Button, Icon, IconButton, IconElement, Label, LabelCommon,
|
||||||
Label, LabelCommon, LabelSize, Selectable, Tooltip,
|
LabelSize, Selectable, Tooltip,
|
||||||
};
|
};
|
||||||
use util::{paths::PathMatcher, ResultExt as _};
|
use util::{paths::PathMatcher, ResultExt as _};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
|
@ -511,7 +511,7 @@ impl Item for ProjectSearchView {
|
||||||
.update(cx, |editor, cx| editor.deactivated(cx));
|
.update(cx, |editor, cx| editor.deactivated(cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, _: Option<usize>, cx: &WindowContext<'_>) -> AnyElement {
|
fn tab_content(&self, _: Option<usize>, selected: bool, cx: &WindowContext<'_>) -> AnyElement {
|
||||||
let last_query: Option<SharedString> = self
|
let last_query: Option<SharedString> = self
|
||||||
.model
|
.model
|
||||||
.read(cx)
|
.read(cx)
|
||||||
|
@ -527,7 +527,11 @@ impl Item for ProjectSearchView {
|
||||||
.unwrap_or_else(|| "Project search".into());
|
.unwrap_or_else(|| "Project search".into());
|
||||||
h_stack()
|
h_stack()
|
||||||
.child(IconElement::new(Icon::MagnifyingGlass))
|
.child(IconElement::new(Icon::MagnifyingGlass))
|
||||||
.child(Label::new(tab_name))
|
.child(Label::new(tab_name).color(if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
}))
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -686,13 +686,22 @@ impl Item for TerminalView {
|
||||||
Some(self.terminal().read(cx).title().into())
|
Some(self.terminal().read(cx).title().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, _detail: Option<usize>, cx: &WindowContext) -> AnyElement {
|
fn tab_content(
|
||||||
|
&self,
|
||||||
|
_detail: Option<usize>,
|
||||||
|
selected: bool,
|
||||||
|
cx: &WindowContext,
|
||||||
|
) -> AnyElement {
|
||||||
let title = self.terminal().read(cx).title();
|
let title = self.terminal().read(cx).title();
|
||||||
|
|
||||||
h_stack()
|
h_stack()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.child(IconElement::new(Icon::Terminal))
|
.child(IconElement::new(Icon::Terminal))
|
||||||
.child(Label::new(title))
|
.child(Label::new(title).color(if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
}))
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@ mod base_keymap_setting;
|
||||||
|
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, red, AnyElement, AppContext, Div, Element, EventEmitter, FocusHandle, Focusable,
|
div, red, AnyElement, AppContext, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
|
||||||
FocusableView, InteractiveElement, ParentElement, Render, Styled, Subscription, View,
|
InteractiveElement, ParentElement, Render, Styled, Subscription, View, ViewContext,
|
||||||
ViewContext, VisualContext, WeakView, WindowContext,
|
VisualContext, WeakView, WindowContext,
|
||||||
};
|
};
|
||||||
use settings::{Settings, SettingsStore};
|
use settings::{Settings, SettingsStore};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use ui::prelude::*;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::DockPosition,
|
dock::DockPosition,
|
||||||
item::{Item, ItemEvent},
|
item::{Item, ItemEvent},
|
||||||
|
@ -261,8 +262,14 @@ impl FocusableView for WelcomePage {
|
||||||
impl Item for WelcomePage {
|
impl Item for WelcomePage {
|
||||||
type Event = ItemEvent;
|
type Event = ItemEvent;
|
||||||
|
|
||||||
fn tab_content(&self, _: Option<usize>, _: &WindowContext) -> AnyElement {
|
fn tab_content(&self, _: Option<usize>, selected: bool, _: &WindowContext) -> AnyElement {
|
||||||
"Welcome to Zed!".into_any()
|
Label::new("Welcome to Zed!")
|
||||||
|
.color(if selected {
|
||||||
|
Color::Default
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
})
|
||||||
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_toolbar(&self) -> bool {
|
fn show_toolbar(&self) -> bool {
|
||||||
|
|
|
@ -106,7 +106,7 @@ pub trait Item: FocusableView + EventEmitter<Self::Event> {
|
||||||
fn tab_description(&self, _: usize, _: &AppContext) -> Option<SharedString> {
|
fn tab_description(&self, _: usize, _: &AppContext) -> Option<SharedString> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
|
fn tab_content(&self, detail: Option<usize>, selected: bool, cx: &WindowContext) -> AnyElement;
|
||||||
|
|
||||||
/// (model id, Item)
|
/// (model id, Item)
|
||||||
fn for_each_project_item(
|
fn for_each_project_item(
|
||||||
|
@ -218,7 +218,7 @@ pub trait ItemHandle: 'static + Send {
|
||||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
|
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
|
||||||
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString>;
|
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString>;
|
||||||
fn tab_description(&self, detail: usize, cx: &AppContext) -> Option<SharedString>;
|
fn tab_description(&self, detail: usize, cx: &AppContext) -> Option<SharedString>;
|
||||||
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
|
fn tab_content(&self, detail: Option<usize>, selected: bool, cx: &WindowContext) -> AnyElement;
|
||||||
fn dragged_tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
|
fn dragged_tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement;
|
||||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
||||||
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]>;
|
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]>;
|
||||||
|
@ -311,12 +311,12 @@ impl<T: Item> ItemHandle for View<T> {
|
||||||
self.read(cx).tab_description(detail, cx)
|
self.read(cx).tab_description(detail, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement {
|
fn tab_content(&self, detail: Option<usize>, selected: bool, cx: &WindowContext) -> AnyElement {
|
||||||
self.read(cx).tab_content(detail, cx)
|
self.read(cx).tab_content(detail, selected, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dragged_tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement {
|
fn dragged_tab_content(&self, detail: Option<usize>, cx: &WindowContext) -> AnyElement {
|
||||||
self.read(cx).tab_content(detail, cx)
|
self.read(cx).tab_content(detail, true, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
||||||
|
@ -941,6 +941,7 @@ pub mod test {
|
||||||
fn tab_content(
|
fn tab_content(
|
||||||
&self,
|
&self,
|
||||||
detail: Option<usize>,
|
detail: Option<usize>,
|
||||||
|
selected: bool,
|
||||||
cx: &ui::prelude::WindowContext,
|
cx: &ui::prelude::WindowContext,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
self.tab_detail.set(detail);
|
self.tab_detail.set(detail);
|
||||||
|
|
|
@ -1424,7 +1424,9 @@ impl Pane {
|
||||||
detail: usize,
|
detail: usize,
|
||||||
cx: &mut ViewContext<'_, Pane>,
|
cx: &mut ViewContext<'_, Pane>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let label = item.tab_content(Some(detail), cx);
|
let is_active = ix == self.active_item_index;
|
||||||
|
|
||||||
|
let label = item.tab_content(Some(detail), is_active, cx);
|
||||||
let close_side = &ItemSettings::get_global(cx).close_position;
|
let close_side = &ItemSettings::get_global(cx).close_position;
|
||||||
|
|
||||||
let (text_color, tab_bg, tab_hover_bg, tab_active_bg) = match ix == self.active_item_index {
|
let (text_color, tab_bg, tab_hover_bg, tab_active_bg) = match ix == self.active_item_index {
|
||||||
|
@ -1442,8 +1444,6 @@ impl Pane {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_active = ix == self.active_item_index;
|
|
||||||
|
|
||||||
let indicator = maybe!({
|
let indicator = maybe!({
|
||||||
let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) {
|
let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) {
|
||||||
(true, _) => Color::Warning,
|
(true, _) => Color::Warning,
|
||||||
|
@ -1473,7 +1473,7 @@ impl Pane {
|
||||||
ClosePosition::Left => ui::TabCloseSide::Start,
|
ClosePosition::Left => ui::TabCloseSide::Start,
|
||||||
ClosePosition::Right => ui::TabCloseSide::End,
|
ClosePosition::Right => ui::TabCloseSide::End,
|
||||||
})
|
})
|
||||||
.selected(ix == self.active_item_index())
|
.selected(is_active)
|
||||||
.on_click(cx.listener(move |pane: &mut Self, event, cx| {
|
.on_click(cx.listener(move |pane: &mut Self, event, cx| {
|
||||||
pane.activate_item(ix, true, true, cx)
|
pane.activate_item(ix, true, true, cx)
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -12,7 +12,7 @@ use gpui::{
|
||||||
VisualContext, WindowContext,
|
VisualContext, WindowContext,
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use ui::{h_stack, Icon, IconElement};
|
use ui::{h_stack, prelude::*, Icon, IconElement, Label};
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Close,
|
Close,
|
||||||
|
@ -90,14 +90,22 @@ impl Item for SharedScreen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content(&self, _: Option<usize>, _: &WindowContext<'_>) -> gpui::AnyElement {
|
fn tab_content(
|
||||||
|
&self,
|
||||||
|
_: Option<usize>,
|
||||||
|
selected: bool,
|
||||||
|
_: &WindowContext<'_>,
|
||||||
|
) -> gpui::AnyElement {
|
||||||
h_stack()
|
h_stack()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(IconElement::new(Icon::Screen))
|
.child(IconElement::new(Icon::Screen))
|
||||||
.child(SharedString::from(format!(
|
.child(
|
||||||
"{}'s screen",
|
Label::new(format!("{}'s screen", self.user.github_login)).color(if selected {
|
||||||
self.user.github_login
|
Color::Default
|
||||||
)))
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
}),
|
||||||
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue