co-authored-by: conrad <conrad@zed.dev>
co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Mikayla 2023-11-20 14:46:01 -08:00
parent 6985b70859
commit 2c4d83c9af
No known key found for this signature in database
96 changed files with 1926 additions and 1955 deletions

View file

@ -1,276 +1,276 @@
use crate::prelude::*;
use crate::{Icon, IconElement, Label, TextColor};
use gpui::{prelude::*, red, Div, ElementId, Render, RenderOnce, Stateful, View};
// use crate::prelude::*;
// use crate::{Icon, IconElement, Label, TextColor};
// use gpui::{prelude::*, red, Div, ElementId, Render, RenderOnce, View};
#[derive(RenderOnce, Clone)]
pub struct Tab {
id: ElementId,
title: String,
icon: Option<Icon>,
current: bool,
dirty: bool,
fs_status: FileSystemStatus,
git_status: GitStatus,
diagnostic_status: DiagnosticStatus,
close_side: IconSide,
}
// #[derive(RenderOnce, Clone)]
// pub struct Tab {
// id: ElementId,
// title: String,
// icon: Option<Icon>,
// current: bool,
// dirty: bool,
// fs_status: FileSystemStatus,
// git_status: GitStatus,
// diagnostic_status: DiagnosticStatus,
// close_side: IconSide,
// }
#[derive(Clone, Debug)]
struct TabDragState {
title: String,
}
// #[derive(Clone, Debug)]
// struct TabDragState {
// title: String,
// }
impl Render<Self> for TabDragState {
type Element = Div<Self>;
// impl Render for TabDragState {
// type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div().w_8().h_4().bg(red())
}
}
// fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
// div().w_8().h_4().bg(red())
// }
// }
impl<V: 'static> Component<V> for Tab {
type Rendered = Stateful<V, Div<V>>;
// impl Component for Tab {
// type Rendered = gpui::Stateful<Div>;
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
let has_fs_conflict = self.fs_status == FileSystemStatus::Conflict;
let is_deleted = self.fs_status == FileSystemStatus::Deleted;
// fn render(self, cx: &mut WindowContext) -> Self::Rendered {
// let has_fs_conflict = self.fs_status == FileSystemStatus::Conflict;
// let is_deleted = self.fs_status == FileSystemStatus::Deleted;
let label = match (self.git_status, is_deleted) {
(_, true) | (GitStatus::Deleted, false) => Label::new(self.title.clone())
.color(TextColor::Hidden)
.set_strikethrough(true),
(GitStatus::None, false) => Label::new(self.title.clone()),
(GitStatus::Created, false) => Label::new(self.title.clone()).color(TextColor::Created),
(GitStatus::Modified, false) => {
Label::new(self.title.clone()).color(TextColor::Modified)
}
(GitStatus::Renamed, false) => Label::new(self.title.clone()).color(TextColor::Accent),
(GitStatus::Conflict, false) => Label::new(self.title.clone()),
};
// let label = match (self.git_status, is_deleted) {
// (_, true) | (GitStatus::Deleted, false) => Label::new(self.title.clone())
// .color(TextColor::Hidden)
// .set_strikethrough(true),
// (GitStatus::None, false) => Label::new(self.title.clone()),
// (GitStatus::Created, false) => Label::new(self.title.clone()).color(TextColor::Created),
// (GitStatus::Modified, false) => {
// Label::new(self.title.clone()).color(TextColor::Modified)
// }
// (GitStatus::Renamed, false) => Label::new(self.title.clone()).color(TextColor::Accent),
// (GitStatus::Conflict, false) => Label::new(self.title.clone()),
// };
let close_icon = || IconElement::new(Icon::Close).color(TextColor::Muted);
// let close_icon = || IconElement::new(Icon::Close).color(TextColor::Muted);
let (tab_bg, tab_hover_bg, tab_active_bg) = match self.current {
false => (
cx.theme().colors().tab_inactive_background,
cx.theme().colors().ghost_element_hover,
cx.theme().colors().ghost_element_active,
),
true => (
cx.theme().colors().tab_active_background,
cx.theme().colors().element_hover,
cx.theme().colors().element_active,
),
};
// let (tab_bg, tab_hover_bg, tab_active_bg) = match self.current {
// false => (
// cx.theme().colors().tab_inactive_background,
// cx.theme().colors().ghost_element_hover,
// cx.theme().colors().ghost_element_active,
// ),
// true => (
// cx.theme().colors().tab_active_background,
// cx.theme().colors().element_hover,
// cx.theme().colors().element_active,
// ),
// };
let drag_state = TabDragState {
title: self.title.clone(),
};
// let drag_state = TabDragState {
// title: self.title.clone(),
// };
div()
.id(self.id.clone())
.on_drag(move |_view, cx| cx.build_view(|cx| drag_state.clone()))
.drag_over::<TabDragState>(|d| d.bg(cx.theme().colors().drop_target_background))
.on_drop(|_view, state: View<TabDragState>, cx| {
eprintln!("{:?}", state.read(cx));
})
.px_2()
.py_0p5()
.flex()
.items_center()
.justify_center()
.bg(tab_bg)
.hover(|h| h.bg(tab_hover_bg))
.active(|a| a.bg(tab_active_bg))
.child(
div()
.px_1()
.flex()
.items_center()
.gap_1p5()
.children(has_fs_conflict.then(|| {
IconElement::new(Icon::ExclamationTriangle)
.size(crate::IconSize::Small)
.color(TextColor::Warning)
}))
.children(self.icon.map(IconElement::new))
.children(if self.close_side == IconSide::Left {
Some(close_icon())
} else {
None
})
.child(label)
.children(if self.close_side == IconSide::Right {
Some(close_icon())
} else {
None
}),
)
}
}
// div()
// .id(self.id.clone())
// .on_drag(move |_view, cx| cx.build_view(|cx| drag_state.clone()))
// .drag_over::<TabDragState>(|d| d.bg(cx.theme().colors().drop_target_background))
// .on_drop(|_view, state: View<TabDragState>, cx| {
// eprintln!("{:?}", state.read(cx));
// })
// .px_2()
// .py_0p5()
// .flex()
// .items_center()
// .justify_center()
// .bg(tab_bg)
// .hover(|h| h.bg(tab_hover_bg))
// .active(|a| a.bg(tab_active_bg))
// .child(
// div()
// .px_1()
// .flex()
// .items_center()
// .gap_1p5()
// .children(has_fs_conflict.then(|| {
// IconElement::new(Icon::ExclamationTriangle)
// .size(crate::IconSize::Small)
// .color(TextColor::Warning)
// }))
// .children(self.icon.map(IconElement::new))
// .children(if self.close_side == IconSide::Left {
// Some(close_icon())
// } else {
// None
// })
// .child(label)
// .children(if self.close_side == IconSide::Right {
// Some(close_icon())
// } else {
// None
// }),
// )
// }
// }
impl Tab {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
title: "untitled".to_string(),
icon: None,
current: false,
dirty: false,
fs_status: FileSystemStatus::None,
git_status: GitStatus::None,
diagnostic_status: DiagnosticStatus::None,
close_side: IconSide::Right,
}
}
// impl Tab {
// pub fn new(id: impl Into<ElementId>) -> Self {
// Self {
// id: id.into(),
// title: "untitled".to_string(),
// icon: None,
// current: false,
// dirty: false,
// fs_status: FileSystemStatus::None,
// git_status: GitStatus::None,
// diagnostic_status: DiagnosticStatus::None,
// close_side: IconSide::Right,
// }
// }
pub fn current(mut self, current: bool) -> Self {
self.current = current;
self
}
// pub fn current(mut self, current: bool) -> Self {
// self.current = current;
// self
// }
pub fn title(mut self, title: String) -> Self {
self.title = title;
self
}
// pub fn title(mut self, title: String) -> Self {
// self.title = title;
// self
// }
pub fn icon<I>(mut self, icon: I) -> Self
where
I: Into<Option<Icon>>,
{
self.icon = icon.into();
self
}
// pub fn icon<I>(mut self, icon: I) -> Self
// where
// I: Into<Option<Icon>>,
// {
// self.icon = icon.into();
// self
// }
pub fn dirty(mut self, dirty: bool) -> Self {
self.dirty = dirty;
self
}
// pub fn dirty(mut self, dirty: bool) -> Self {
// self.dirty = dirty;
// self
// }
pub fn fs_status(mut self, fs_status: FileSystemStatus) -> Self {
self.fs_status = fs_status;
self
}
// pub fn fs_status(mut self, fs_status: FileSystemStatus) -> Self {
// self.fs_status = fs_status;
// self
// }
pub fn git_status(mut self, git_status: GitStatus) -> Self {
self.git_status = git_status;
self
}
// pub fn git_status(mut self, git_status: GitStatus) -> Self {
// self.git_status = git_status;
// self
// }
pub fn diagnostic_status(mut self, diagnostic_status: DiagnosticStatus) -> Self {
self.diagnostic_status = diagnostic_status;
self
}
// pub fn diagnostic_status(mut self, diagnostic_status: DiagnosticStatus) -> Self {
// self.diagnostic_status = diagnostic_status;
// self
// }
pub fn close_side(mut self, close_side: IconSide) -> Self {
self.close_side = close_side;
self
}
}
// pub fn close_side(mut self, close_side: IconSide) -> Self {
// self.close_side = close_side;
// self
// }
// }
#[cfg(feature = "stories")]
pub use stories::*;
// #[cfg(feature = "stories")]
// pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
use super::*;
use crate::{h_stack, v_stack, Icon, Story};
use strum::IntoEnumIterator;
// #[cfg(feature = "stories")]
// mod stories {
// use super::*;
// use crate::{h_stack, v_stack, Icon, Story};
// use strum::IntoEnumIterator;
pub struct TabStory;
// pub struct TabStory;
impl Render<Self> for TabStory {
type Element = Div<Self>;
// impl Render for TabStory {
// type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let git_statuses = GitStatus::iter();
let fs_statuses = FileSystemStatus::iter();
// fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
// let git_statuses = GitStatus::iter();
// let fs_statuses = FileSystemStatus::iter();
Story::container(cx)
.child(Story::title_for::<_, Tab>(cx))
.child(
h_stack().child(
v_stack()
.gap_2()
.child(Story::label(cx, "Default"))
.child(Tab::new("default")),
),
)
.child(
h_stack().child(
v_stack().gap_2().child(Story::label(cx, "Current")).child(
h_stack()
.gap_4()
.child(
Tab::new("current")
.title("Current".to_string())
.current(true),
)
.child(
Tab::new("not_current")
.title("Not Current".to_string())
.current(false),
),
),
),
)
.child(
h_stack().child(
v_stack()
.gap_2()
.child(Story::label(cx, "Titled"))
.child(Tab::new("titled").title("label".to_string())),
),
)
.child(
h_stack().child(
v_stack()
.gap_2()
.child(Story::label(cx, "With Icon"))
.child(
Tab::new("with_icon")
.title("label".to_string())
.icon(Some(Icon::Envelope)),
),
),
)
.child(
h_stack().child(
v_stack()
.gap_2()
.child(Story::label(cx, "Close Side"))
.child(
h_stack()
.gap_4()
.child(
Tab::new("left")
.title("Left".to_string())
.close_side(IconSide::Left),
)
.child(Tab::new("right").title("Right".to_string())),
),
),
)
.child(
v_stack()
.gap_2()
.child(Story::label(cx, "Git Status"))
.child(h_stack().gap_4().children(git_statuses.map(|git_status| {
Tab::new("git_status")
.title(git_status.to_string())
.git_status(git_status)
}))),
)
.child(
v_stack()
.gap_2()
.child(Story::label(cx, "File System Status"))
.child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
Tab::new("file_system_status")
.title(fs_status.to_string())
.fs_status(fs_status)
}))),
)
}
}
}
// Story::container(cx)
// .child(Story::title_for::<_, Tab>(cx))
// .child(
// h_stack().child(
// v_stack()
// .gap_2()
// .child(Story::label(cx, "Default"))
// .child(Tab::new("default")),
// ),
// )
// .child(
// h_stack().child(
// v_stack().gap_2().child(Story::label(cx, "Current")).child(
// h_stack()
// .gap_4()
// .child(
// Tab::new("current")
// .title("Current".to_string())
// .current(true),
// )
// .child(
// Tab::new("not_current")
// .title("Not Current".to_string())
// .current(false),
// ),
// ),
// ),
// )
// .child(
// h_stack().child(
// v_stack()
// .gap_2()
// .child(Story::label(cx, "Titled"))
// .child(Tab::new("titled").title("label".to_string())),
// ),
// )
// .child(
// h_stack().child(
// v_stack()
// .gap_2()
// .child(Story::label(cx, "With Icon"))
// .child(
// Tab::new("with_icon")
// .title("label".to_string())
// .icon(Some(Icon::Envelope)),
// ),
// ),
// )
// .child(
// h_stack().child(
// v_stack()
// .gap_2()
// .child(Story::label(cx, "Close Side"))
// .child(
// h_stack()
// .gap_4()
// .child(
// Tab::new("left")
// .title("Left".to_string())
// .close_side(IconSide::Left),
// )
// .child(Tab::new("right").title("Right".to_string())),
// ),
// ),
// )
// .child(
// v_stack()
// .gap_2()
// .child(Story::label(cx, "Git Status"))
// .child(h_stack().gap_4().children(git_statuses.map(|git_status| {
// Tab::new("git_status")
// .title(git_status.to_string())
// .git_status(git_status)
// }))),
// )
// .child(
// v_stack()
// .gap_2()
// .child(Story::label(cx, "File System Status"))
// .child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
// Tab::new("file_system_status")
// .title(fs_status.to_string())
// .fs_status(fs_status)
// }))),
// )
// }
// }
// }