context_menu.rs

 1use crate::prelude::*;
 2use crate::theme::theme;
 3use crate::{
 4    v_stack, Label, List, ListEntry, ListItem, ListItemVariant, ListSeparator, ListSubHeader,
 5};
 6
 7#[derive(Clone)]
 8pub enum ContextMenuItem {
 9    Header(&'static str),
10    Entry(Label),
11    Separator,
12}
13
14impl ContextMenuItem {
15    fn to_list_item(self) -> ListItem {
16        match self {
17            ContextMenuItem::Header(label) => ListSubHeader::new(label).into(),
18            ContextMenuItem::Entry(label) => {
19                ListEntry::new(label).variant(ListItemVariant::Inset).into()
20            }
21            ContextMenuItem::Separator => ListSeparator::new().into(),
22        }
23    }
24    pub fn header(label: &'static str) -> Self {
25        Self::Header(label)
26    }
27    pub fn separator() -> Self {
28        Self::Separator
29    }
30    pub fn entry(label: Label) -> Self {
31        Self::Entry(label)
32    }
33}
34
35#[derive(Element)]
36pub struct ContextMenu {
37    items: Vec<ContextMenuItem>,
38}
39
40impl ContextMenu {
41    pub fn new(items: impl IntoIterator<Item = ContextMenuItem>) -> Self {
42        Self {
43            items: items.into_iter().collect(),
44        }
45    }
46    fn render<V: 'static>(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
47        let theme = theme(cx);
48        v_stack()
49            .flex()
50            .fill(theme.lowest.base.default.background)
51            .border()
52            .border_color(theme.lowest.base.default.border)
53            .child(
54                List::new(
55                    self.items
56                        .clone()
57                        .into_iter()
58                        .map(ContextMenuItem::to_list_item)
59                        .collect(),
60                )
61                .set_toggle(ToggleState::Toggled),
62            )
63        //div().p_1().children(self.items.clone())
64    }
65}