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}