use crate::host::Rect;
use crate::model::NodeId;
use crate::ops::SwapVariant;
#[derive(Debug, Clone, PartialEq)]
pub struct MenuItem {
pub label: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MenuView {
pub anchor: Rect,
pub items: Vec<MenuItem>,
pub selected: usize,
pub query: String,
}
pub(crate) enum RowEffect<'a> {
Delete,
Swap(&'a SwapVariant),
}
impl RowEffect<'_> {
pub(crate) fn label(&self) -> String {
match self {
RowEffect::Delete => "Delete".to_string(),
RowEffect::Swap(v) => v.label().to_string(),
}
}
}
pub(crate) struct Menu {
pub(crate) anchor: NodeId,
variants: Vec<SwapVariant>,
pub(crate) query: String,
pub(crate) selected: usize,
}
impl Menu {
pub(crate) fn for_node(anchor: NodeId, variants: Vec<SwapVariant>) -> Self {
Self {
anchor,
variants,
query: String::new(),
selected: 0,
}
}
pub(crate) fn visible(&self) -> Vec<RowEffect<'_>> {
let mut out = vec![RowEffect::Delete];
let q = self.query.to_lowercase();
out.extend(
self.variants
.iter()
.filter(|v| q.is_empty() || v.label().to_lowercase().contains(&q))
.map(RowEffect::Swap),
);
out
}
}