diff --git a/CHANGELOG.md b/CHANGELOG.md index af3006f49a..14e72d07a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `on_open` and `on_close` handlers for `PickList`. [#2174](https://github.com/iced-rs/iced/pull/2174) - Support for generic `Element` in `Tooltip`. [#2228](https://github.com/iced-rs/iced/pull/2228) - Container and `gap` styling for `Scrollable`. [#2239](https://github.com/iced-rs/iced/pull/2239) +- Use `Borrow` for both `options` and `selected` in PickList. [#2251](https://github.com/iced-rs/iced/pull/2251) ### Changed - Enable WebGPU backend in `wgpu` by default instead of WebGL. [#2068](https://github.com/iced-rs/iced/pull/2068) diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs index b626c70dd6..f41c9986f8 100644 --- a/examples/layout/src/main.rs +++ b/examples/layout/src/main.rs @@ -88,11 +88,7 @@ impl Application for Layout { horizontal_space(Length::Fill), checkbox("Explain", self.explain) .on_toggle(Message::ExplainToggled), - pick_list( - Theme::ALL, - Some(self.theme.clone()), - Message::ThemeSelected - ), + pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected), ] .spacing(20) .align_items(Alignment::Center); diff --git a/examples/qr_code/src/main.rs b/examples/qr_code/src/main.rs index 8b2e950020..9f75eaf6c8 100644 --- a/examples/qr_code/src/main.rs +++ b/examples/qr_code/src/main.rs @@ -60,11 +60,7 @@ impl Sandbox for QRGenerator { let choose_theme = row![ text("Theme:"), - pick_list( - Theme::ALL, - Some(self.theme.clone()), - Message::ThemeChanged, - ) + pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged,) ] .spacing(10) .align_items(Alignment::Center); diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index cf2dcb8aaf..c26215b6f2 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -55,12 +55,8 @@ impl Sandbox for Styling { fn view(&self) -> Element { let choose_theme = column![ text("Theme:"), - pick_list( - Theme::ALL, - Some(self.theme.clone()), - Message::ThemeChanged - ) - .width(Length::Fill), + pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged) + .width(Length::Fill), ] .spacing(10); diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index a5411c899d..e9898d6743 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -22,7 +22,7 @@ use crate::toggler::{self, Toggler}; use crate::tooltip::{self, Tooltip}; use crate::{Column, MouseArea, Row, Space, Themer, VerticalSlider}; -use std::borrow::Cow; +use std::borrow::Borrow; use std::ops::RangeInclusive; /// Creates a [`Column`] with the given children. @@ -264,14 +264,15 @@ where /// Creates a new [`PickList`]. /// /// [`PickList`]: crate::PickList -pub fn pick_list<'a, Message, Theme, Renderer, T>( - options: impl Into>, - selected: Option, +pub fn pick_list<'a, T, L, V, Message, Theme, Renderer>( + options: L, + selected: Option, on_selected: impl Fn(T) -> Message + 'a, -) -> PickList<'a, T, Message, Theme, Renderer> +) -> PickList<'a, T, L, V, Message, Theme, Renderer> where - T: ToString + PartialEq + 'static, - [T]: ToOwned>, + T: ToString + PartialEq + Clone + 'a, + L: Borrow<[T]> + 'a, + V: Borrow + 'a, Message: Clone, Renderer: core::text::Renderer, Theme: pick_list::StyleSheet diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 840c94fab2..1f20e2bce2 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -17,7 +17,7 @@ use crate::core::{ use crate::overlay::menu::{self, Menu}; use crate::scrollable; -use std::borrow::Cow; +use std::borrow::Borrow; pub use crate::style::pick_list::{Appearance, StyleSheet}; @@ -26,20 +26,24 @@ pub use crate::style::pick_list::{Appearance, StyleSheet}; pub struct PickList< 'a, T, + L, + V, Message, Theme = crate::Theme, Renderer = crate::Renderer, > where - [T]: ToOwned>, + T: ToString + PartialEq + Clone, + L: Borrow<[T]> + 'a, + V: Borrow + 'a, Theme: StyleSheet, Renderer: text::Renderer, { on_select: Box Message + 'a>, on_open: Option, on_close: Option, - options: Cow<'a, [T]>, + options: L, placeholder: Option, - selected: Option, + selected: Option, width: Length, padding: Padding, text_size: Option, @@ -50,11 +54,12 @@ pub struct PickList< style: Theme::Style, } -impl<'a, T: 'a, Message, Theme, Renderer> - PickList<'a, T, Message, Theme, Renderer> +impl<'a, T, L, V, Message, Theme, Renderer> + PickList<'a, T, L, V, Message, Theme, Renderer> where - T: ToString + PartialEq, - [T]: ToOwned>, + T: ToString + PartialEq + Clone, + L: Borrow<[T]> + 'a, + V: Borrow + 'a, Message: Clone, Theme: StyleSheet + scrollable::StyleSheet @@ -69,15 +74,15 @@ where /// Creates a new [`PickList`] with the given list of options, the current /// selected value, and the message to produce when an option is selected. pub fn new( - options: impl Into>, - selected: Option, + options: L, + selected: Option, on_select: impl Fn(T) -> Message + 'a, ) -> Self { Self { on_select: Box::new(on_select), on_open: None, on_close: None, - options: options.into(), + options, placeholder: None, selected, width: Length::Shrink, @@ -164,11 +169,12 @@ where } } -impl<'a, T: 'a, Message, Theme, Renderer> Widget - for PickList<'a, T, Message, Theme, Renderer> +impl<'a, T, L, V, Message, Theme, Renderer> Widget + for PickList<'a, T, L, V, Message, Theme, Renderer> where - T: Clone + ToString + PartialEq + 'static, - [T]: ToOwned>, + T: Clone + ToString + PartialEq + 'a, + L: Borrow<[T]>, + V: Borrow, Message: Clone + 'a, Theme: StyleSheet + scrollable::StyleSheet @@ -209,7 +215,7 @@ where self.text_shaping, self.font, self.placeholder.as_deref(), - &self.options, + self.options.borrow(), ) } @@ -232,8 +238,8 @@ where self.on_select.as_ref(), self.on_open.as_ref(), self.on_close.as_ref(), - self.selected.as_ref(), - &self.options, + self.selected.as_ref().map(Borrow::borrow), + self.options.borrow(), || tree.state.downcast_mut::>(), ) } @@ -271,7 +277,7 @@ where self.text_shaping, font, self.placeholder.as_deref(), - self.selected.as_ref(), + self.selected.as_ref().map(Borrow::borrow), &self.handle, &self.style, || tree.state.downcast_ref::>(), @@ -296,19 +302,20 @@ where self.text_size, self.text_shaping, self.font.unwrap_or_else(|| renderer.default_font()), - &self.options, + self.options.borrow(), &self.on_select, self.style.clone(), ) } } -impl<'a, T: 'a, Message, Theme, Renderer> - From> +impl<'a, T, L, V, Message, Theme, Renderer> + From> for Element<'a, Message, Theme, Renderer> where - T: Clone + ToString + PartialEq + 'static, - [T]: ToOwned>, + T: Clone + ToString + PartialEq + 'a, + L: Borrow<[T]> + 'a, + V: Borrow + 'a, Message: Clone + 'a, Theme: StyleSheet + scrollable::StyleSheet @@ -318,7 +325,9 @@ where ::Style: From<::Style>, Renderer: text::Renderer + 'a, { - fn from(pick_list: PickList<'a, T, Message, Theme, Renderer>) -> Self { + fn from( + pick_list: PickList<'a, T, L, V, Message, Theme, Renderer>, + ) -> Self { Self::new(pick_list) } }