// Copyright 2023 System76 // SPDX-License-Identifier: MPL-2.0 use std::borrow::Cow; use slotmap::{SecondaryMap, SparseSecondaryMap}; use crate::widget::IconSource; use super::{Entity, Model, Selectable}; /// A newly-inserted item which may have additional actions applied to it. pub struct EntityMut<'a, SelectionMode: Default> { pub(super) id: Entity, pub(super) model: &'a mut Model, } impl<'a, SelectionMode: Default> EntityMut<'a, SelectionMode> where Model: Selectable, { /// Activates the newly-inserted item. /// /// ```ignore /// model.insert().text("Item A").activate(); /// ``` #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn activate(self) -> Self { self.model.activate(self.id); self } /// Associates extra data with an external secondary map. /// /// The secondary map internally uses a `Vec`, so should only be used for data that /// is commonly associated. /// /// ```ignore /// let mut secondary_data = segmented_button::SecondaryMap::default(); /// model.insert().text("Item A").secondary(&mut secondary_data, String::new("custom data")); /// ``` #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn secondary(self, map: &mut SecondaryMap, data: Data) -> Self { map.insert(self.id, data); self } /// Associates extra data with an external sparse secondary map. /// /// Sparse maps internally use a `HashMap`, for data that is sparsely associated. /// /// ```ignore /// let mut secondary_data = segmented_button::SparseSecondaryMap::default(); /// model.insert().text("Item A").secondary(&mut secondary_data, String::new("custom data")); /// ``` #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn secondary_sparse( self, map: &mut SparseSecondaryMap, data: Data, ) -> Self { map.insert(self.id, data); self } /// Associates data with the item. /// /// There may only be one data component per Rust type. /// /// ```ignore /// model.insert().text("Item A").data(String::from("custom string")); /// ``` #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn data(self, data: Data) -> Self { self.model.data_set(self.id, data); self } /// Define an icon for the item. /// /// ```ignore /// model.insert().text("Item A").icon(IconSource::from("icon-a")); /// ``` #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn icon(self, icon: impl Into>) -> Self { self.model.icon_set(self.id, icon); self } /// Returns the ID of the item that was inserted. /// /// ```ignore /// let id = model.insert("Item A").id(); /// ``` #[must_use] pub fn id(self) -> Entity { self.id } /// Define the position of the item. #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn position(self, position: u16) -> Self { self.model.position_set(self.id, position); self } /// Swap the position with another item in the model. #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn position_swap(self, other: Entity) -> Self { self.model.position_swap(self.id, other); self } /// Defines the text for the item. #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn text(self, text: impl Into>) -> Self { self.model.text_set(self.id, text); self } /// Calls a function with the ID without consuming the wrapper. #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn with_id(self, func: impl FnOnce(Entity)) -> Self { func(self.id); self } }