Skip to main content

ferroui_controls/
table_view_row.rs

1use crate::presenters::TableViewCellsPresenter;
2use crate::primitives::{TemplateAppliedEventArgs, TemplatedControlImpl, TemplatedControlImplExt};
3use crate::{ContentControlImpl, ControlImpl, ListBoxItem, TableViewColumn};
4use ferroui_base::collections::FerroList;
5use ferroui_base::input::InputElementImpl;
6use ferroui_base::interactivity::InteractiveImpl;
7use ferroui_base::layout::LayoutableImpl;
8use ferroui_base::{
9    ferro_class, ferro_class_info, ferro_impl_classes, instantiate, FerroObjectImpl, Ref, StyledElementImpl,
10    VisualImpl,
11};
12use std::cell::RefCell;
13
14const PART_CELLS_PRESENTER: &str = "PART_CellsPresenter";
15
16/// A row container in a [`TableView`](crate::TableView).
17#[repr(C)]
18pub struct TableViewRow {
19    base: ListBoxItem,
20    cells_presenter: RefCell<Option<Ref<TableViewCellsPresenter>>>,
21    columns: RefCell<Option<FerroList<Ref<TableViewColumn>>>>,
22}
23
24ferro_class!(TableViewRow: ListBoxItem);
25ferro_class_info!(TableViewRow {
26    new: TableViewRow::new,
27    markup: {
28        attributes: [TemplatePart("PART_CellsPresenter", type(Ref<TableViewCellsPresenter>))],
29    },
30});
31ferro_impl_classes!(
32    TableViewRow: FerroObjectImpl,
33    StyledElementImpl,
34    VisualImpl,
35    LayoutableImpl,
36    InteractiveImpl,
37    InputElementImpl,
38    ControlImpl,
39    ContentControlImpl
40);
41
42impl TemplatedControlImpl for TableViewRow {
43    fn on_apply_template(this: &Self, e: &TemplateAppliedEventArgs) {
44        Self::parent_on_apply_template(this, e);
45
46        if let Some(cells_presenter) = this.cells_presenter.take() {
47            debug_assert!(cells_presenter.row().is_some_and(|row| row.ptr_eq(&this.to_ref())));
48            cells_presenter.remove_cells();
49            cells_presenter.set_row(None);
50        }
51
52        let cells_presenter = e.name_scope().find_as::<TableViewCellsPresenter>(PART_CELLS_PRESENTER);
53        *this.cells_presenter.borrow_mut() = cells_presenter.clone();
54
55        if let Some(cells_presenter) = cells_presenter {
56            debug_assert!(cells_presenter.row().is_none());
57            cells_presenter.set_row(Some(&this.to_ref()));
58            cells_presenter.rebuild_cells();
59        }
60    }
61}
62
63impl TableViewRow {
64    /// Creates the class data; see [`ferroui_base::FerroObject::construct`].
65    pub fn construct() -> Self {
66        Self { base: ListBoxItem::construct(), cells_presenter: RefCell::new(None), columns: RefCell::new(None) }
67    }
68
69    pub fn new() -> Ref<Self> {
70        instantiate(Self::construct())
71    }
72
73    /// The columns of the table view the row belongs to.
74    pub(crate) fn columns(&self) -> Option<FerroList<Ref<TableViewColumn>>> {
75        self.columns.borrow().clone()
76    }
77
78    pub(crate) fn set_columns(&self, value: Option<FerroList<Ref<TableViewColumn>>>) {
79        *self.columns.borrow_mut() = value;
80    }
81
82    fn cells_presenter(&self) -> Option<Ref<TableViewCellsPresenter>> {
83        self.cells_presenter.borrow().clone()
84    }
85
86    pub(crate) fn clear_cells(&self) {
87        if let Some(cells_presenter) = self.cells_presenter() {
88            cells_presenter.clear_cells();
89        }
90    }
91
92    pub(crate) fn invalidate_cells_measure(&self) {
93        if let Some(cells_presenter) = self.cells_presenter() {
94            cells_presenter.invalidate_measure();
95        }
96    }
97
98    pub(crate) fn rebuild_cells(&self) {
99        if let Some(cells_presenter) = self.cells_presenter() {
100            cells_presenter.rebuild_cells();
101        }
102    }
103
104    pub(crate) fn refresh_cell(&self, column_index: usize) {
105        if let Some(cells_presenter) = self.cells_presenter() {
106            cells_presenter.refresh_cell(column_index);
107        }
108    }
109}