// Copyright 2022 System76 // SPDX-License-Identifier: MPL-2.0 use slotmap::{SecondaryMap, SlotMap}; use std::borrow::Cow; slotmap::new_key_type! { /// An ID for a segmented button pub struct Key; } /// Contains all state for interacting with a segmented button. pub struct State { /// State that is shareable across widget(s). pub inner: SharedWidgetState, /// State unique to the application. pub data: SecondaryState, } impl Default for State { fn default() -> Self { Self { inner: SharedWidgetState::default(), data: SecondaryState::default(), } } } /// State which is most useful to the widget. #[derive(Default)] pub struct SharedWidgetState { /// The content used for drawing segmented buttons. pub buttons: SlotMap, /// The actively-selected segmented button. pub active: Key, } /// State which is most useful to the application. pub type SecondaryState = SecondaryMap; impl State { /// The ID of the active button. #[must_use] pub fn active(&self) -> Key { self.inner.active } /// Get the application data for the active button. #[must_use] pub fn active_data(&self) -> Option<&Data> { self.data(self.active()) } /// Get the application data for a button. #[must_use] pub fn data(&self, key: Key) -> Option<&Data> { self.data.get(key) } /// Insert a new button. pub fn insert(&mut self, content: impl Into, data: Data) -> Key { let key = self.inner.buttons.insert(content.into()); self.data.insert(key, data); key } /// Removes a button. pub fn remove(&mut self, key: Key) -> Option { self.inner.buttons.remove(key); self.data.remove(key) } /// Activates this button. pub fn activate(&mut self, key: Key) { self.inner.active = key; } } /// Data to be drawn in a segmented button. pub struct ButtonContent { pub text: Cow<'static, str>, } impl From for ButtonContent { fn from(text: String) -> Self { ButtonContent { text: Cow::Owned(text), } } } impl From<&'static str> for ButtonContent { fn from(text: &'static str) -> Self { ButtonContent { text: Cow::Borrowed(text), } } } impl From> for ButtonContent { fn from(text: Cow<'static, str>) -> Self { ButtonContent { text } } }