Skip to main content

tree_table/types/
event_data.rs

1use crate::ChangeIndexCell;
2use crate::types::Change;
3use alloc::rc::Rc;
4use alloc::string::String;
5use alloc::vec::Vec;
6use hashbrown::HashMap;
7
8#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
9#[cfg_attr(feature = "tsify", tsify(from_wasm_abi))]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[derive(Debug, Clone, PartialEq)]
12pub struct TreeChange {
13    pub par: Option<ChangeIndexCell>,
14    pub chn: Option<ChangeIndexCell>,
15}
16
17pub enum TreeChangeKind {
18    Par,
19    Chn,
20}
21
22#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
23#[cfg_attr(feature = "tsify", tsify(from_wasm_abi))]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25#[derive(Debug, Default, Clone, PartialEq)]
26pub struct EventData {
27    pub widget_name: String,
28    pub widget_id: u32,
29    pub changes: Vec<Change>,
30    // FOR UNDO, cells that were modified by a change
31    #[cfg_attr(feature = "serde", serde(skip_serializing, default))]
32    pub tree_changes: HashMap<Rc<str>, TreeChange>,
33}
34
35impl EventData {
36    #[inline]
37    pub fn tree_change_required(&self, iid: &Rc<str>, kind: TreeChangeKind) -> bool {
38        if let Some(tree_change) = self.tree_changes.get(iid) {
39            match kind {
40                TreeChangeKind::Par => tree_change.par.is_none(),
41                TreeChangeKind::Chn => tree_change.chn.is_none(),
42            }
43        } else {
44            true
45        }
46    }
47    #[inline]
48    pub fn add_tree_change(&mut self, iid: &Rc<str>, change: ChangeIndexCell) {
49        if let Some(tree_change) = self.tree_changes.get_mut(iid) {
50            match change {
51                ChangeIndexCell::SetPar(_) => {
52                    if tree_change.par.is_none() {
53                        tree_change.par = Some(change)
54                    }
55                }
56                ChangeIndexCell::SetChn(_) => {
57                    if tree_change.chn.is_none() {
58                        tree_change.chn = Some(change)
59                    }
60                }
61                _ => (),
62            }
63        } else {
64            match change {
65                ChangeIndexCell::SetPar(_) => {
66                    self.tree_changes.insert(
67                        iid.clone(),
68                        TreeChange {
69                            par: Some(change),
70                            chn: None,
71                        },
72                    );
73                }
74                ChangeIndexCell::SetChn(_) => {
75                    self.tree_changes.insert(
76                        iid.clone(),
77                        TreeChange {
78                            par: None,
79                            chn: Some(change),
80                        },
81                    );
82                }
83                _ => (),
84            }
85        }
86    }
87
88    #[inline]
89    pub fn has_non_selection_change(&self, reverse: bool) -> bool {
90        if reverse {
91            self.changes.iter().rev().any(|c| !c.is_selection_change())
92        } else {
93            self.changes.iter().any(|c| !c.is_selection_change())
94        }
95    }
96}