toolbar.rs

  1use gpui2::AnyElement;
  2use smallvec::SmallVec;
  3
  4use crate::prelude::*;
  5
  6#[derive(Clone)]
  7pub struct ToolbarItem {}
  8
  9#[derive(Element)]
 10pub struct Toolbar<S: 'static + Send + Sync> {
 11    left_items: SmallVec<[AnyElement<S>; 2]>,
 12    right_items: SmallVec<[AnyElement<S>; 2]>,
 13}
 14
 15impl<S: 'static + Send + Sync> Toolbar<S> {
 16    pub fn new() -> Self {
 17        Self {
 18            left_items: SmallVec::new(),
 19            right_items: SmallVec::new(),
 20        }
 21    }
 22
 23    pub fn left_item(mut self, child: impl IntoAnyElement<S>) -> Self
 24    where
 25        Self: Sized,
 26    {
 27        self.left_items.push(child.into_any());
 28        self
 29    }
 30
 31    pub fn left_items(mut self, iter: impl IntoIterator<Item = impl IntoAnyElement<S>>) -> Self
 32    where
 33        Self: Sized,
 34    {
 35        self.left_items
 36            .extend(iter.into_iter().map(|item| item.into_any()));
 37        self
 38    }
 39
 40    pub fn right_item(mut self, child: impl IntoAnyElement<S>) -> Self
 41    where
 42        Self: Sized,
 43    {
 44        self.right_items.push(child.into_any());
 45        self
 46    }
 47
 48    pub fn right_items(mut self, iter: impl IntoIterator<Item = impl IntoAnyElement<S>>) -> Self
 49    where
 50        Self: Sized,
 51    {
 52        self.right_items
 53            .extend(iter.into_iter().map(|item| item.into_any()));
 54        self
 55    }
 56
 57    fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
 58        let color = ThemeColor::new(cx);
 59
 60        div()
 61            .bg(color.toolbar)
 62            .p_2()
 63            .flex()
 64            .justify_between()
 65            .child(div().flex().children(self.left_items.drain(..)))
 66            .child(div().flex().children(self.right_items.drain(..)))
 67    }
 68}
 69
 70#[cfg(feature = "stories")]
 71pub use stories::*;
 72
 73#[cfg(feature = "stories")]
 74mod stories {
 75    use std::marker::PhantomData;
 76    use std::path::PathBuf;
 77    use std::str::FromStr;
 78
 79    use crate::{Breadcrumb, HighlightedText, Icon, IconButton, Story, Symbol};
 80
 81    use super::*;
 82
 83    #[derive(Element)]
 84    pub struct ToolbarStory<S: 'static + Send + Sync + Clone> {
 85        state_type: PhantomData<S>,
 86    }
 87
 88    impl<S: 'static + Send + Sync + Clone> ToolbarStory<S> {
 89        pub fn new() -> Self {
 90            Self {
 91                state_type: PhantomData,
 92            }
 93        }
 94
 95        fn render(
 96            &mut self,
 97            _view: &mut S,
 98            cx: &mut ViewContext<S>,
 99        ) -> impl Element<ViewState = S> {
100            let color = ThemeColor::new(cx);
101
102            Story::container(cx)
103                .child(Story::title_for::<_, Toolbar<S>>(cx))
104                .child(Story::label(cx, "Default"))
105                .child(
106                    Toolbar::new()
107                        .left_item(Breadcrumb::new(
108                            PathBuf::from_str("crates/ui/src/components/toolbar.rs").unwrap(),
109                            vec![
110                                Symbol(vec![
111                                    HighlightedText {
112                                        text: "impl ".to_string(),
113                                        color: color.syntax.keyword,
114                                    },
115                                    HighlightedText {
116                                        text: "ToolbarStory".to_string(),
117                                        color: color.syntax.function,
118                                    },
119                                ]),
120                                Symbol(vec![
121                                    HighlightedText {
122                                        text: "fn ".to_string(),
123                                        color: color.syntax.keyword,
124                                    },
125                                    HighlightedText {
126                                        text: "render".to_string(),
127                                        color: color.syntax.function,
128                                    },
129                                ]),
130                            ],
131                        ))
132                        .right_items(vec![
133                            IconButton::new("toggle_inlay_hints", Icon::InlayHint),
134                            IconButton::new("buffer_search", Icon::MagnifyingGlass),
135                            IconButton::new("inline_assist", Icon::MagicWand),
136                        ]),
137                )
138        }
139    }
140}