dropdown: accept impl Into<Cow<'_, str>

This allows using `format!` in the `view` function rather than
having to store all strings in the model
which is in theory less efficient but it's also much less likely to lead to stale data.
This commit is contained in:
Sosthène Guédon 2025-05-24 18:21:42 +02:00
parent b61a7ebd5f
commit ef4682853f
2 changed files with 16 additions and 13 deletions

View file

@ -4,6 +4,8 @@
//! Displays a list of options in a popover menu on select. //! Displays a list of options in a popover menu on select.
use std::borrow::Cow;
pub mod menu; pub mod menu;
use iced_core::window; use iced_core::window;
pub use menu::Menu; pub use menu::Menu;
@ -17,14 +19,15 @@ use crate::surface;
/// Displays a list of options in a popover menu on select. /// Displays a list of options in a popover menu on select.
pub fn dropdown< pub fn dropdown<
'a,
S: AsRef<str> + std::clone::Clone + Send + Sync + 'static, S: AsRef<str> + std::clone::Clone + Send + Sync + 'static,
Message: 'static + Clone, Message: 'static + Clone,
>( >(
selections: &[S], selections: impl Into<Cow<'a, [S]>>,
selected: Option<usize>, selected: Option<usize>,
on_selected: impl Fn(usize) -> Message + Send + Sync + 'static, on_selected: impl Fn(usize) -> Message + Send + Sync + 'static,
) -> Dropdown<'_, S, Message, Message> { ) -> Dropdown<'a, S, Message, Message> {
Dropdown::new(selections, selected, on_selected) Dropdown::new(selections.into(), selected, on_selected)
} }
/// Displays a list of options in a popover menu on select. /// Displays a list of options in a popover menu on select.
@ -35,7 +38,7 @@ pub fn popup_dropdown<
Message: 'static + Clone, Message: 'static + Clone,
AppMessage: 'static + Clone, AppMessage: 'static + Clone,
>( >(
selections: &'a [S], selections: impl Into<Cow<'a, [S]>>,
selected: Option<usize>, selected: Option<usize>,
on_selected: impl Fn(usize) -> Message + Send + Sync + 'static, on_selected: impl Fn(usize) -> Message + Send + Sync + 'static,
_parent_id: window::Id, _parent_id: window::Id,
@ -43,7 +46,7 @@ pub fn popup_dropdown<
_map_action: impl Fn(Message) -> AppMessage + Send + Sync + 'static, _map_action: impl Fn(Message) -> AppMessage + Send + Sync + 'static,
) -> Dropdown<'a, S, Message, AppMessage> { ) -> Dropdown<'a, S, Message, AppMessage> {
let dropdown: Dropdown<'_, S, Message, AppMessage> = let dropdown: Dropdown<'_, S, Message, AppMessage> =
Dropdown::new(selections, selected, on_selected); Dropdown::new(selections.into(), selected, on_selected);
#[cfg(all(feature = "winit", feature = "wayland"))] #[cfg(all(feature = "winit", feature = "wayland"))]
let dropdown = dropdown.with_popup(_parent_id, _on_surface_action, _map_action); let dropdown = dropdown.with_popup(_parent_id, _on_surface_action, _map_action);

View file

@ -34,9 +34,9 @@ where
#[setters(skip)] #[setters(skip)]
on_selected: Arc<dyn Fn(usize) -> Message + Send + Sync>, on_selected: Arc<dyn Fn(usize) -> Message + Send + Sync>,
#[setters(skip)] #[setters(skip)]
selections: &'a [S], selections: Cow<'a, [S]>,
#[setters] #[setters]
icons: &'a [icon::Handle], icons: Cow<'a, [icon::Handle]>,
#[setters(skip)] #[setters(skip)]
selected: Option<usize>, selected: Option<usize>,
#[setters(into)] #[setters(into)]
@ -73,14 +73,14 @@ where
/// Creates a new [`Dropdown`] with the given list of selections, the current /// Creates a new [`Dropdown`] with the given list of selections, the current
/// selected value, and the message to produce when an option is selected. /// selected value, and the message to produce when an option is selected.
pub fn new( pub fn new(
selections: &'a [S], selections: Cow<'a, [S]>,
selected: Option<usize>, selected: Option<usize>,
on_selected: impl Fn(usize) -> Message + 'static + Send + Sync, on_selected: impl Fn(usize) -> Message + 'static + Send + Sync,
) -> Self { ) -> Self {
Self { Self {
on_selected: Arc::new(on_selected), on_selected: Arc::new(on_selected),
selections, selections,
icons: &[], icons: Cow::Borrowed(&[]),
selected, selected,
width: Length::Shrink, width: Length::Shrink,
gap: Self::DEFAULT_GAP, gap: Self::DEFAULT_GAP,
@ -246,12 +246,12 @@ where
self.positioner.clone(), self.positioner.clone(),
self.on_selected.clone(), self.on_selected.clone(),
self.selected, self.selected,
self.selections, &self.selections,
|| tree.state.downcast_mut::<State>(), || tree.state.downcast_mut::<State>(),
self.window_id, self.window_id,
self.on_surface_action.clone(), self.on_surface_action.clone(),
self.action_map.clone(), self.action_map.clone(),
self.icons, &self.icons,
self.gap, self.gap,
self.padding, self.padding,
self.text_size, self.text_size,
@ -322,8 +322,8 @@ where
self.text_size.unwrap_or(14.0), self.text_size.unwrap_or(14.0),
self.text_line_height, self.text_line_height,
self.font, self.font,
self.selections, &self.selections,
self.icons, &self.icons,
self.selected, self.selected,
self.on_selected.as_ref(), self.on_selected.as_ref(),
translation, translation,