diff options
author | 2023-01-02 20:36:40 +0100 | |
---|---|---|
committer | 2023-01-02 20:36:40 +0100 | |
commit | da1b375579c0d4e7a6bd463c8e000af5668354ae (patch) | |
tree | 6eb2dffa65a0cf91762c160f43d02c16df796bd1 | |
parent | d956b8a9fb9d0f18c5568c91fc7b97900477a68e (diff) | |
parent | 39f49186cefa688a1cc80ed754ec4028c642636a (diff) | |
download | iced-da1b375579c0d4e7a6bd463c8e000af5668354ae.tar.gz iced-da1b375579c0d4e7a6bd463c8e000af5668354ae.tar.bz2 iced-da1b375579c0d4e7a6bd463c8e000af5668354ae.zip |
Merge pull request #1562 from casperstorm/feat/custom-accessory-content
Added ability to customize the handle of a `pick_list`
-rw-r--r-- | native/src/widget/pick_list.rs | 97 | ||||
-rw-r--r-- | src/widget.rs | 2 | ||||
-rw-r--r-- | style/src/pick_list.rs | 4 | ||||
-rw-r--r-- | style/src/theme.rs | 4 |
4 files changed, 88 insertions, 19 deletions
diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 52cb1ad1..c2853314 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -20,6 +20,60 @@ use std::borrow::Cow; pub use iced_style::pick_list::{Appearance, StyleSheet}; +/// The handle to the right side of the [`PickList`]. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Handle<Renderer> +where + Renderer: text::Renderer, +{ + /// Displays an arrow icon (▼). + /// + /// This is the default. + Arrow { + /// Font size of the content. + size: Option<u16>, + }, + /// A custom handle. + Custom { + /// Font that will be used to display the `text`, + font: Renderer::Font, + /// Text that will be shown. + text: String, + /// Font size of the content. + size: Option<u16>, + }, + /// No handle will be shown. + None, +} + +impl<Renderer> Default for Handle<Renderer> +where + Renderer: text::Renderer, +{ + fn default() -> Self { + Self::Arrow { size: None } + } +} + +impl<Renderer> Handle<Renderer> +where + Renderer: text::Renderer, +{ + fn content(&self) -> Option<(Renderer::Font, String, Option<u16>)> { + match self { + Self::Arrow { size } => Some(( + Renderer::ICON_FONT, + Renderer::ARROW_DOWN_ICON.to_string(), + *size, + )), + Self::Custom { font, text, size } => { + Some((font.clone(), text.clone(), *size)) + } + Self::None => None, + } + } +} + /// A widget for selecting a single value from a list of options. #[allow(missing_debug_implementations)] pub struct PickList<'a, T, Message, Renderer> @@ -36,6 +90,7 @@ where padding: Padding, text_size: Option<u16>, font: Renderer::Font, + handle: Handle<Renderer>, style: <Renderer::Theme as StyleSheet>::Style, } @@ -67,9 +122,10 @@ where placeholder: None, selected, width: Length::Shrink, - text_size: None, padding: Self::DEFAULT_PADDING, + text_size: None, font: Default::default(), + handle: Default::default(), style: Default::default(), } } @@ -104,6 +160,12 @@ where self } + /// Sets the [`Handle`] of the [`PickList`]. + pub fn handle(mut self, handle: Handle<Renderer>) -> Self { + self.handle = handle; + self + } + /// Sets the style of the [`PickList`]. pub fn style( mut self, @@ -214,6 +276,7 @@ where &self.font, self.placeholder.as_deref(), self.selected.as_ref(), + &self.handle, &self.style, ) } @@ -515,6 +578,7 @@ pub fn draw<T, Renderer>( font: &Renderer::Font, placeholder: Option<&str>, selected: Option<&T>, + handle: &Handle<Renderer>, style: &<Renderer::Theme as StyleSheet>::Style, ) where Renderer: text::Renderer, @@ -541,19 +605,24 @@ pub fn draw<T, Renderer>( style.background, ); - renderer.fill_text(Text { - content: &Renderer::ARROW_DOWN_ICON.to_string(), - font: Renderer::ICON_FONT, - size: bounds.height * style.icon_size, - bounds: Rectangle { - x: bounds.x + bounds.width - f32::from(padding.horizontal()), - y: bounds.center_y(), - ..bounds - }, - color: style.text_color, - horizontal_alignment: alignment::Horizontal::Right, - vertical_alignment: alignment::Vertical::Center, - }); + if let Some((font, text, size)) = handle.content() { + let size = f32::from(size.unwrap_or_else(|| renderer.default_size())); + + renderer.fill_text(Text { + content: &text, + size, + font, + color: style.handle_color, + bounds: Rectangle { + x: bounds.x + bounds.width - f32::from(padding.horizontal()), + y: bounds.center_y() - size / 2.0, + height: size, + ..bounds + }, + horizontal_alignment: alignment::Horizontal::Right, + vertical_alignment: alignment::Vertical::Top, + }); + } let label = selected.map(ToString::to_string); diff --git a/src/widget.rs b/src/widget.rs index 76cea7be..d2d4a1b8 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -80,7 +80,7 @@ pub mod pane_grid { pub mod pick_list { //! Display a dropdown list of selectable values. - pub use iced_native::widget::pick_list::{Appearance, StyleSheet}; + pub use iced_native::widget::pick_list::{Appearance, Handle, StyleSheet}; /// A widget allowing the selection of a single value from a list of options. pub type PickList<'a, T, Message, Renderer = crate::Renderer> = diff --git a/style/src/pick_list.rs b/style/src/pick_list.rs index 8d93dff2..11e13b01 100644 --- a/style/src/pick_list.rs +++ b/style/src/pick_list.rs @@ -8,6 +8,8 @@ pub struct Appearance { pub text_color: Color, /// The placeholder [`Color`] of the pick list. pub placeholder_color: Color, + /// The handle [`Color`] of the pick list. + pub handle_color: Color, /// The [`Background`] of the pick list. pub background: Background, /// The border radius of the pick list. @@ -16,8 +18,6 @@ pub struct Appearance { pub border_width: f32, /// The border color of the pick list. pub border_color: Color, - /// The size of the arrow icon of the pick list. - pub icon_size: f32, } /// A set of rules that dictate the style of a container. diff --git a/style/src/theme.rs b/style/src/theme.rs index 271d9a29..a766b279 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -535,10 +535,10 @@ impl pick_list::StyleSheet for Theme { text_color: palette.background.weak.text, background: palette.background.weak.color.into(), placeholder_color: palette.background.strong.color, + handle_color: palette.background.weak.text, border_radius: 2.0, border_width: 1.0, border_color: palette.background.strong.color, - icon_size: 0.7, } } PickList::Custom(custom, _) => custom.active(self), @@ -554,10 +554,10 @@ impl pick_list::StyleSheet for Theme { text_color: palette.background.weak.text, background: palette.background.weak.color.into(), placeholder_color: palette.background.strong.color, + handle_color: palette.background.weak.text, border_radius: 2.0, border_width: 1.0, border_color: palette.primary.strong.color, - icon_size: 0.7, } } PickList::Custom(custom, _) => custom.hovered(self), |