cosmic/widget/table/model/
entity.rs

1// Copyright 2023 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4use slotmap::{SecondaryMap, SparseSecondaryMap};
5
6use super::{
7    Entity, Model, Selectable,
8    category::{ItemCategory, ItemInterface},
9};
10
11/// A newly-inserted item which may have additional actions applied to it.
12pub struct EntityMut<
13    'a,
14    SelectionMode: Default,
15    Item: ItemInterface<Category>,
16    Category: ItemCategory,
17> {
18    pub(super) id: Entity,
19    pub(super) model: &'a mut Model<SelectionMode, Item, Category>,
20}
21
22impl<'a, SelectionMode: Default, Item: ItemInterface<Category>, Category: ItemCategory>
23    EntityMut<'a, SelectionMode, Item, Category>
24where
25    Model<SelectionMode, Item, Category>: Selectable,
26{
27    /// Activates the newly-inserted item.
28    ///
29    /// ```ignore
30    /// model.insert().text("Item A").activate();
31    /// ```
32    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
33    pub fn activate(self) -> Self {
34        self.model.activate(self.id);
35        self
36    }
37
38    /// Associates extra data with an external secondary map.
39    ///
40    /// The secondary map internally uses a `Vec`, so should only be used for data that
41    /// is commonly associated.
42    ///
43    /// ```ignore
44    /// let mut secondary_data = segmented_button::SecondaryMap::default();
45    /// model.insert().text("Item A").secondary(&mut secondary_data, String::new("custom data"));
46    /// ```
47    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
48    pub fn secondary<Data>(self, map: &mut SecondaryMap<Entity, Data>, data: Data) -> Self {
49        map.insert(self.id, data);
50        self
51    }
52
53    /// Associates extra data with an external sparse secondary map.
54    ///
55    /// Sparse maps internally use a `HashMap`, for data that is sparsely associated.
56    ///
57    /// ```ignore
58    /// let mut secondary_data = segmented_button::SparseSecondaryMap::default();
59    /// model.insert().text("Item A").secondary(&mut secondary_data, String::new("custom data"));
60    /// ```
61    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
62    pub fn secondary_sparse<Data>(
63        self,
64        map: &mut SparseSecondaryMap<Entity, Data>,
65        data: Data,
66    ) -> Self {
67        map.insert(self.id, data);
68        self
69    }
70
71    /// Associates data with the item.
72    ///
73    /// There may only be one data component per Rust type.
74    ///
75    /// ```ignore
76    /// model.insert().text("Item A").data(String::from("custom string"));
77    /// ```
78    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
79    pub fn data<Data: 'static>(self, data: Data) -> Self {
80        self.model.data_set(self.id, data);
81        self
82    }
83
84    /// Returns the ID of the item that was inserted.
85    ///
86    /// ```ignore
87    /// let id = model.insert("Item A").id();
88    /// ```
89    #[must_use]
90    pub fn id(self) -> Entity {
91        self.id
92    }
93
94    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
95    pub fn indent(self, indent: u16) -> Self {
96        self.model.indent_set(self.id, indent);
97        self
98    }
99
100    /// Define the position of the item.
101    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
102    pub fn position(self, position: u16) -> Self {
103        self.model.position_set(self.id, position);
104        self
105    }
106
107    /// Swap the position with another item in the model.
108    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
109    pub fn position_swap(self, other: Entity) -> Self {
110        self.model.position_swap(self.id, other);
111        self
112    }
113
114    /// Defines the text for the item.
115    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
116    pub fn item(self, item: Item) -> Self {
117        self.model.item_set(self.id, item);
118        self
119    }
120
121    /// Calls a function with the ID without consuming the wrapper.
122    #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)]
123    pub fn with_id(self, func: impl FnOnce(Entity)) -> Self {
124        func(self.id);
125        self
126    }
127}