mathtex_editor_core/
menu.rs1use crate::model::NodeId;
4use crate::ops::{SwapKind, SwapVariant};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum MenuItemKind {
9 Delete,
11 Swap,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
17pub struct MenuItem {
18 pub label: String,
20 pub kind: MenuItemKind,
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26pub struct MenuView {
27 pub items: Vec<MenuItem>,
29 pub selected: usize,
31 pub query: String,
33}
34
35pub(crate) enum RowEffect<'a> {
37 Delete,
38 Swap(&'a SwapKind),
39}
40
41pub(crate) struct Menu {
43 pub(crate) anchor: NodeId,
44 variants: Vec<SwapVariant>,
45 pub(crate) query: String,
46 pub(crate) selected: usize,
47}
48
49impl Menu {
50 pub(crate) fn for_node(anchor: NodeId, variants: Vec<SwapVariant>) -> Self {
51 Self { anchor, variants, query: String::new(), selected: 0 }
52 }
53
54 fn visible_variants(&self) -> impl Iterator<Item = &SwapVariant> {
55 let q = self.query.to_lowercase();
56 self.variants.iter().filter(move |v| q.is_empty() || v.label.to_lowercase().contains(&q))
57 }
58
59 pub(crate) fn visible(&self) -> Vec<RowEffect<'_>> {
61 std::iter::once(RowEffect::Delete).chain(self.visible_variants().map(|v| RowEffect::Swap(&v.kind))).collect()
62 }
63
64 pub(crate) fn view(&self) -> MenuView {
65 let delete = MenuItem { label: "Delete".to_string(), kind: MenuItemKind::Delete };
66 let swaps = self.visible_variants().map(|v| MenuItem { label: v.label.clone(), kind: MenuItemKind::Swap });
67 MenuView { items: std::iter::once(delete).chain(swaps).collect(), selected: self.selected, query: self.query.clone() }
68 }
69}