diff --git a/examples/table-view/src/main.rs b/examples/table-view/src/main.rs index ea641144..23df06a2 100644 --- a/examples/table-view/src/main.rs +++ b/examples/table-view/src/main.rs @@ -11,7 +11,7 @@ use cosmic::widget::table; use cosmic::widget::{self, nav_bar}; use cosmic::{executor, iced}; -#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)] pub enum Category { #[default] Name, diff --git a/src/widget/table/model/category.rs b/src/widget/table/model/category.rs index efa4624a..c3dd5400 100644 --- a/src/widget/table/model/category.rs +++ b/src/widget/table/model/category.rs @@ -4,7 +4,7 @@ use crate::widget::Icon; /// Implementation of std::fmt::Display allows user to customize the header /// Ideally, this is implemented on an enum. -pub trait ItemCategory: Default + std::fmt::Display + Clone + Copy + PartialEq + Eq { +pub trait ItemCategory: Default + std::fmt::Display + Clone + Copy + PartialEq + Eq + std::hash::Hash { /// Function that gets the width of the data fn width(&self) -> iced::Length; } diff --git a/src/widget/table/widget/standard.rs b/src/widget/table/widget/standard.rs index f9450c70..bf86153c 100644 --- a/src/widget/table/widget/standard.rs +++ b/src/widget/table/widget/standard.rs @@ -40,7 +40,8 @@ where #[setters(skip)] pub(super) item_context_tree: Option>>, #[setters(skip)] - pub(super) category_context_tree: Option>>, + pub(super) category_context_trees: + std::collections::HashMap>>>, #[setters(skip)] pub(super) on_item_select: Option Message + 'a>>, @@ -64,11 +65,15 @@ where fn from(val: TableView<'a, SelectionMode, Item, Category, Message>) -> Self { let cosmic_theme::Spacing { space_xxxs, .. } = theme::active().cosmic().spacing; + let mut category_contexts = val.category_context_trees.into_values(); + let header_row = val .model .categories .iter() .map(|category| { + let cat_context_tree = category_contexts.next().unwrap(); + widget::row() .spacing(space_xxxs) .push(widget::text::heading(category.to_string())) @@ -110,6 +115,7 @@ where mouse_area } }) + .apply(|mouse_area| widget::context_menu(mouse_area, cat_context_tree)) .apply(Element::from) }) .collect::>>() @@ -217,7 +223,7 @@ where .. } = theme::active().cosmic().spacing; - Self { + let mut result = Self { model, element_padding: Padding::from(0), @@ -232,8 +238,14 @@ where on_category_select: None, on_category_context: None, - category_context_tree: None, + category_context_trees: std::collections::HashMap::new(), + }; + + for category in model.categories.iter().cloned() { + result.category_context_trees.insert(category, None); } + + result } pub fn on_item_select(mut self, on_select: F) -> Self @@ -266,16 +278,15 @@ where self } - pub fn category_context(mut self, context_menu: Option>>) -> Self + pub fn category_context(mut self, category: Category, context_menu: Option>>) -> Self where Message: 'static, { - self.category_context_tree = - context_menu.map(|menus| vec![menu::Tree::with_children(widget::row(), menus)]); - - if let Some(ref mut context_menu) = self.category_context_tree { - context_menu.iter_mut().for_each(menu::Tree::set_index); - } + *self.category_context_trees.get_mut(&category).unwrap() = + context_menu.map(|menus| vec![menu::Tree::with_children(widget::row(), menus)]); + if let Some(ref mut context_menu) = self.category_context_trees.get_mut(&category).unwrap() { + context_menu.iter_mut().for_each(menu::Tree::set_index); + } self }