Skip to main content

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