diff --git a/src/widget/segmented_button/mod.rs b/src/widget/segmented_button/mod.rs index 34b6ec74..ba9a336a 100644 --- a/src/widget/segmented_button/mod.rs +++ b/src/widget/segmented_button/mod.rs @@ -97,3 +97,11 @@ pub type SecondaryMap = slotmap::SecondaryMap; /// /// Sparse maps internally use a `HashMap`, for data that is sparsely associated. pub type SparseSecondaryMap = slotmap::SparseSecondaryMap; + +/// Defines the color of the icon for a segmented item. +#[derive(Clone, Copy, Debug, Default, PartialEq)] +enum IconColor { + #[default] + None, + Color(crate::iced::Color), +} diff --git a/src/widget/segmented_button/model/builder.rs b/src/widget/segmented_button/model/builder.rs index 2ffa16e0..7cbb1e5e 100644 --- a/src/widget/segmented_button/model/builder.rs +++ b/src/widget/segmented_button/model/builder.rs @@ -1,6 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: MPL-2.0 +use iced::Color; use slotmap::{SecondaryMap, SparseSecondaryMap}; use super::{Entity, Model, Selectable}; @@ -108,6 +109,13 @@ where self } + /// Defines the color of an icon. + #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] + pub fn icon_color(mut self, icon: Option) -> Self { + self.model.0.icon_color_set(self.id, icon); + self + } + /// Define the position of the newly-inserted item. #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] pub fn position(mut self, position: u16) -> Self { diff --git a/src/widget/segmented_button/model/entity.rs b/src/widget/segmented_button/model/entity.rs index cf1eeac0..e3236250 100644 --- a/src/widget/segmented_button/model/entity.rs +++ b/src/widget/segmented_button/model/entity.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; +use iced::Color; use slotmap::{SecondaryMap, SparseSecondaryMap}; use crate::widget::IconSource; @@ -94,6 +95,13 @@ where self } + /// Define the color for the icon. + #[allow(clippy::must_use_candidate, clippy::return_self_not_must_use)] + pub fn icon_color(self, icon: Option) -> Self { + self.model.icon_color_set(self.id, icon); + self + } + /// Returns the ID of the item that was inserted. /// /// ```ignore diff --git a/src/widget/segmented_button/model/mod.rs b/src/widget/segmented_button/model/mod.rs index db1e844e..425dcf81 100644 --- a/src/widget/segmented_button/model/mod.rs +++ b/src/widget/segmented_button/model/mod.rs @@ -11,11 +11,14 @@ mod selection; pub use self::selection::{MultiSelect, Selectable, SingleSelect}; use crate::widget::IconSource; +use iced::Color; use slotmap::{SecondaryMap, SlotMap}; use std::any::{Any, TypeId}; use std::borrow::Cow; use std::collections::{HashMap, VecDeque}; +use super::IconColor; + slotmap::new_key_type! { /// A unique ID for an item in the [`Model`]. pub struct Entity; @@ -244,6 +247,24 @@ where self.icons.insert(id, icon.into()) } + /// Sets the color of the icon. By default, the color matches the text. + pub fn icon_color_set(&mut self, id: Entity, color: Option) { + if self.contains_item(id) { + self.data_set( + id, + match color { + Some(color) => IconColor::Color(color), + None => IconColor::None, + }, + ); + } + } + + /// Unsets the defined color of an icon. + pub fn icon_color_remove(&mut self, id: Entity) { + self.data_remove::(id); + } + /// Removes the icon from an item. /// /// ```ignore diff --git a/src/widget/segmented_button/widget.rs b/src/widget/segmented_button/widget.rs index f54efc27..32bbe68f 100644 --- a/src/widget/segmented_button/widget.rs +++ b/src/widget/segmented_button/widget.rs @@ -3,6 +3,7 @@ use super::model::{Entity, Model, Selectable}; use super::style::StyleSheet; +use super::IconColor; use crate::widget::{icon, IconSource}; use derive_setters::Setters; use iced::{ @@ -466,6 +467,12 @@ where status_appearance.middle }; + let icon_color = match self.model.data::(key).copied() { + Some(IconColor::None) => None, + Some(IconColor::Color(color)) => Some(color), + None => Some(status_appearance.text_color), + }; + // Render the background of the button. if status_appearance.background.is_some() { renderer.fill_quad( @@ -529,12 +536,7 @@ where unimplemented!() } icon::Handle::Svg(handle) => { - iced_native::svg::Renderer::draw( - renderer, - handle, - Some(status_appearance.text_color), - icon_bounds, - ); + iced_native::svg::Renderer::draw(renderer, handle, icon_color, icon_bounds); } }