tab.rs

  1// use crate::prelude::*;
  2// use crate::{Icon, IconElement, Label, TextColor};
  3// use gpui::{prelude::*, red, Div, ElementId, Render, RenderOnce, View};
  4
  5// #[derive(RenderOnce, Clone)]
  6// pub struct Tab {
  7//     id: ElementId,
  8//     title: String,
  9//     icon: Option<Icon>,
 10//     current: bool,
 11//     dirty: bool,
 12//     fs_status: FileSystemStatus,
 13//     git_status: GitStatus,
 14//     diagnostic_status: DiagnosticStatus,
 15//     close_side: IconSide,
 16// }
 17
 18// #[derive(Clone, Debug)]
 19// struct TabDragState {
 20//     title: String,
 21// }
 22
 23// impl Render for TabDragState {
 24//     type Element = Div;
 25
 26//     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
 27//         div().w_8().h_4().bg(red())
 28//     }
 29// }
 30
 31// impl Component for Tab {
 32//     type Rendered = gpui::Stateful<Div>;
 33
 34//     fn render(self, cx: &mut WindowContext) -> Self::Rendered {
 35//         let has_fs_conflict = self.fs_status == FileSystemStatus::Conflict;
 36//         let is_deleted = self.fs_status == FileSystemStatus::Deleted;
 37
 38//         let label = match (self.git_status, is_deleted) {
 39//             (_, true) | (GitStatus::Deleted, false) => Label::new(self.title.clone())
 40//                 .color(TextColor::Hidden)
 41//                 .set_strikethrough(true),
 42//             (GitStatus::None, false) => Label::new(self.title.clone()),
 43//             (GitStatus::Created, false) => Label::new(self.title.clone()).color(TextColor::Created),
 44//             (GitStatus::Modified, false) => {
 45//                 Label::new(self.title.clone()).color(TextColor::Modified)
 46//             }
 47//             (GitStatus::Renamed, false) => Label::new(self.title.clone()).color(TextColor::Accent),
 48//             (GitStatus::Conflict, false) => Label::new(self.title.clone()),
 49//         };
 50
 51//         let close_icon = || IconElement::new(Icon::Close).color(TextColor::Muted);
 52
 53//         let (tab_bg, tab_hover_bg, tab_active_bg) = match self.current {
 54//             false => (
 55//                 cx.theme().colors().tab_inactive_background,
 56//                 cx.theme().colors().ghost_element_hover,
 57//                 cx.theme().colors().ghost_element_active,
 58//             ),
 59//             true => (
 60//                 cx.theme().colors().tab_active_background,
 61//                 cx.theme().colors().element_hover,
 62//                 cx.theme().colors().element_active,
 63//             ),
 64//         };
 65
 66//         let drag_state = TabDragState {
 67//             title: self.title.clone(),
 68//         };
 69
 70//         div()
 71//             .id(self.id.clone())
 72//             .on_drag(move |_view, cx| cx.build_view(|cx| drag_state.clone()))
 73//             .drag_over::<TabDragState>(|d| d.bg(cx.theme().colors().drop_target_background))
 74//             .on_drop(|_view, state: View<TabDragState>, cx| {
 75//                 eprintln!("{:?}", state.read(cx));
 76//             })
 77//             .px_2()
 78//             .py_0p5()
 79//             .flex()
 80//             .items_center()
 81//             .justify_center()
 82//             .bg(tab_bg)
 83//             .hover(|h| h.bg(tab_hover_bg))
 84//             .active(|a| a.bg(tab_active_bg))
 85//             .child(
 86//                 div()
 87//                     .px_1()
 88//                     .flex()
 89//                     .items_center()
 90//                     .gap_1p5()
 91//                     .children(has_fs_conflict.then(|| {
 92//                         IconElement::new(Icon::ExclamationTriangle)
 93//                             .size(crate::IconSize::Small)
 94//                             .color(TextColor::Warning)
 95//                     }))
 96//                     .children(self.icon.map(IconElement::new))
 97//                     .children(if self.close_side == IconSide::Left {
 98//                         Some(close_icon())
 99//                     } else {
100//                         None
101//                     })
102//                     .child(label)
103//                     .children(if self.close_side == IconSide::Right {
104//                         Some(close_icon())
105//                     } else {
106//                         None
107//                     }),
108//             )
109//     }
110// }
111
112// impl Tab {
113//     pub fn new(id: impl Into<ElementId>) -> Self {
114//         Self {
115//             id: id.into(),
116//             title: "untitled".to_string(),
117//             icon: None,
118//             current: false,
119//             dirty: false,
120//             fs_status: FileSystemStatus::None,
121//             git_status: GitStatus::None,
122//             diagnostic_status: DiagnosticStatus::None,
123//             close_side: IconSide::Right,
124//         }
125//     }
126
127//     pub fn current(mut self, current: bool) -> Self {
128//         self.current = current;
129//         self
130//     }
131
132//     pub fn title(mut self, title: String) -> Self {
133//         self.title = title;
134//         self
135//     }
136
137//     pub fn icon<I>(mut self, icon: I) -> Self
138//     where
139//         I: Into<Option<Icon>>,
140//     {
141//         self.icon = icon.into();
142//         self
143//     }
144
145//     pub fn dirty(mut self, dirty: bool) -> Self {
146//         self.dirty = dirty;
147//         self
148//     }
149
150//     pub fn fs_status(mut self, fs_status: FileSystemStatus) -> Self {
151//         self.fs_status = fs_status;
152//         self
153//     }
154
155//     pub fn git_status(mut self, git_status: GitStatus) -> Self {
156//         self.git_status = git_status;
157//         self
158//     }
159
160//     pub fn diagnostic_status(mut self, diagnostic_status: DiagnosticStatus) -> Self {
161//         self.diagnostic_status = diagnostic_status;
162//         self
163//     }
164
165//     pub fn close_side(mut self, close_side: IconSide) -> Self {
166//         self.close_side = close_side;
167//         self
168//     }
169// }
170
171// #[cfg(feature = "stories")]
172// pub use stories::*;
173
174// #[cfg(feature = "stories")]
175// mod stories {
176//     use super::*;
177//     use crate::{h_stack, v_stack, Icon, Story};
178//     use strum::IntoEnumIterator;
179
180//     pub struct TabStory;
181
182//     impl Render for TabStory {
183//         type Element = Div;
184
185//         fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
186//             let git_statuses = GitStatus::iter();
187//             let fs_statuses = FileSystemStatus::iter();
188
189//             Story::container(cx)
190//                 .child(Story::title_for::<_, Tab>(cx))
191//                 .child(
192//                     h_stack().child(
193//                         v_stack()
194//                             .gap_2()
195//                             .child(Story::label(cx, "Default"))
196//                             .child(Tab::new("default")),
197//                     ),
198//                 )
199//                 .child(
200//                     h_stack().child(
201//                         v_stack().gap_2().child(Story::label(cx, "Current")).child(
202//                             h_stack()
203//                                 .gap_4()
204//                                 .child(
205//                                     Tab::new("current")
206//                                         .title("Current".to_string())
207//                                         .current(true),
208//                                 )
209//                                 .child(
210//                                     Tab::new("not_current")
211//                                         .title("Not Current".to_string())
212//                                         .current(false),
213//                                 ),
214//                         ),
215//                     ),
216//                 )
217//                 .child(
218//                     h_stack().child(
219//                         v_stack()
220//                             .gap_2()
221//                             .child(Story::label(cx, "Titled"))
222//                             .child(Tab::new("titled").title("label".to_string())),
223//                     ),
224//                 )
225//                 .child(
226//                     h_stack().child(
227//                         v_stack()
228//                             .gap_2()
229//                             .child(Story::label(cx, "With Icon"))
230//                             .child(
231//                                 Tab::new("with_icon")
232//                                     .title("label".to_string())
233//                                     .icon(Some(Icon::Envelope)),
234//                             ),
235//                     ),
236//                 )
237//                 .child(
238//                     h_stack().child(
239//                         v_stack()
240//                             .gap_2()
241//                             .child(Story::label(cx, "Close Side"))
242//                             .child(
243//                                 h_stack()
244//                                     .gap_4()
245//                                     .child(
246//                                         Tab::new("left")
247//                                             .title("Left".to_string())
248//                                             .close_side(IconSide::Left),
249//                                     )
250//                                     .child(Tab::new("right").title("Right".to_string())),
251//                             ),
252//                     ),
253//                 )
254//                 .child(
255//                     v_stack()
256//                         .gap_2()
257//                         .child(Story::label(cx, "Git Status"))
258//                         .child(h_stack().gap_4().children(git_statuses.map(|git_status| {
259//                             Tab::new("git_status")
260//                                 .title(git_status.to_string())
261//                                 .git_status(git_status)
262//                         }))),
263//                 )
264//                 .child(
265//                     v_stack()
266//                         .gap_2()
267//                         .child(Story::label(cx, "File System Status"))
268//                         .child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
269//                             Tab::new("file_system_status")
270//                                 .title(fs_status.to_string())
271//                                 .fs_status(fs_status)
272//                         }))),
273//                 )
274//         }
275//     }
276// }