diff --git a/examples/table-view/src/main.rs b/examples/table-view/src/main.rs index b7cbb8ab..f4c34070 100644 --- a/examples/table-view/src/main.rs +++ b/examples/table-view/src/main.rs @@ -28,7 +28,7 @@ impl std::fmt::Display for Category { } } -impl table::model::category::ItemCategory for Category { +impl table::ItemCategory for Category { fn width(&self) -> iced::Length { match self { Self::Name => iced::Length::Fill, @@ -54,7 +54,7 @@ impl Default for Item { } } -impl table::model::category::ItemInterface for Item { +impl table::ItemInterface for Item { fn get_icon(&self, category: Category) -> Option { if category == Category::Name { Some(cosmic::widget::icon::from_name("application-x-executable-symbolic").icon()) @@ -104,7 +104,7 @@ pub enum Message { /// The [`App`] stores application-specific state. pub struct App { core: Core, - table_model: table::Model, + table_model: table::SingleSelectModel, } /// Implement [`cosmic::Application`] to integrate with COSMIC. @@ -192,9 +192,19 @@ impl cosmic::Application for App { /// Creates a view after each update. fn view(&self) -> Element { - table::TableView::new(&self.table_model) - .on_item_select(Message::ItemSelect) - .on_category_select(Message::CategorySelect) - .element_standard() + cosmic::widget::responsive(|size| { + if size.width < 600.0 { + table::SingleSelectTableView::new(&self.table_model) + .on_item_select(Message::ItemSelect) + .on_category_select(Message::CategorySelect) + .element_compact() + } else { + table::SingleSelectTableView::new(&self.table_model) + .on_item_select(Message::ItemSelect) + .on_category_select(Message::CategorySelect) + .element_standard() + } + }) + .into() } } diff --git a/src/widget/table/mod.rs b/src/widget/table/mod.rs index 9f4ce541..594e73d2 100644 --- a/src/widget/table/mod.rs +++ b/src/widget/table/mod.rs @@ -2,6 +2,19 @@ //! pub mod model; -pub use model::{Entity, Model}; +pub use model::{ + category::ItemCategory, + category::ItemInterface, + selection::{MultiSelect, SingleSelect}, + Entity, Model, +}; pub mod widget; pub use widget::TableView; + +pub type SingleSelectTableView<'a, Item, Category, Message> = + TableView<'a, SingleSelect, Item, Category, Message>; +pub type SingleSelectModel = Model; + +pub type MultiSelectTableView<'a, Item, Category, Message> = + TableView<'a, MultiSelect, Item, Category, Message>; +pub type MultiSelectModel = Model; diff --git a/src/widget/table/widget/mod.rs b/src/widget/table/widget/mod.rs index 0cb826a4..73cb60c3 100644 --- a/src/widget/table/widget/mod.rs +++ b/src/widget/table/widget/mod.rs @@ -199,12 +199,11 @@ where .apply(Element::from)] } else { self.model - .order .iter() .map(|entity| { - let item = self.model.item(*entity).unwrap(); + let item = self.model.item(entity).unwrap(); let categories = &self.model.categories; - let selected = self.model.is_active(*entity); + let selected = self.model.is_active(entity); vec![ divider::horizontal::default() @@ -222,20 +221,12 @@ where .apply(container) .width(category.width()) .align_y(Alignment::Center) - .padding(self.item_padding) .apply(Element::from) }) .collect::>>() .apply(widget::row::with_children) - .apply(widget::mouse_area) - .apply(|mouse_area| { - if let Some(ref on_item_select) = self.on_item_select { - mouse_area.on_press((on_item_select)(*entity)) - } else { - mouse_area - } - }) .apply(container) + .padding(self.item_padding) .class(theme::Container::custom(move |theme| { widget::container::Style { icon_color: if selected { @@ -262,6 +253,14 @@ where shadow: Default::default(), } })) + .apply(widget::mouse_area) + .apply(|mouse_area| { + if let Some(ref on_item_select) = self.on_item_select { + mouse_area.on_press((on_item_select)(entity)) + } else { + mouse_area + } + }) .apply(Element::from), ] }) @@ -273,6 +272,8 @@ where .flatten() .collect::>>() .apply(widget::column::with_children) + .spacing(self.item_spacing) + .padding(self.element_padding) .apply(Element::from) } @@ -283,7 +284,9 @@ where .iter() .map(|entity| { let item = self.model.item(entity).unwrap(); + let selected = self.model.is_active(entity); widget::column() + .spacing(self.item_spacing) .push( widget::divider::horizontal::default() .apply(container) @@ -291,6 +294,7 @@ where ) .push( widget::row() + .spacing(space_xxxs) .align_y(Alignment::Center) .push_maybe( item.get_icon(Category::default()).map(|icon| icon.size(48)), @@ -321,12 +325,49 @@ where }), ) .apply(container) - .padding(self.item_padding), + .padding(self.item_padding) + .width(iced::Length::Fill) + .class(theme::Container::custom(move |theme| { + widget::container::Style { + icon_color: if selected { + Some(theme.cosmic().on_accent_color().into()) + } else { + None + }, + text_color: if selected { + Some(theme.cosmic().on_accent_color().into()) + } else { + None + }, + background: if selected { + Some(iced::Background::Color( + theme.cosmic().accent_color().into(), + )) + } else { + None + }, + border: Border { + radius: theme.cosmic().radius_xs().into(), + ..Default::default() + }, + shadow: Default::default(), + } + })) + .apply(widget::mouse_area) + .apply(|ma| { + if let Some(on_item_select) = &self.on_item_select { + ma.on_press((on_item_select)(entity)) + } else { + ma + } + }), ) .apply(Element::from) }) .collect::>>() .apply(widget::column::with_children) + .spacing(self.item_spacing) + .padding(self.element_padding) .apply(Element::from) } }