From fa433743b352f9a27e0669d4da41f645db8b04cb Mon Sep 17 00:00:00 2001 From: Jon Pacheco Date: Sat, 22 May 2021 19:28:17 +0100 Subject: feat: add placeholders to pick_list see issue #726 --- graphics/src/widget/pick_list.rs | 3 ++- native/src/widget/pick_list.rs | 32 +++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs index 32dfbdf9..a7fe3e93 100644 --- a/graphics/src/widget/pick_list.rs +++ b/graphics/src/widget/pick_list.rs @@ -31,6 +31,7 @@ where bounds: Rectangle, cursor_position: Point, selected: Option, + placeholder: Option, padding: Padding, text_size: u16, font: Font, @@ -68,7 +69,7 @@ where ( Primitive::Group { - primitives: if let Some(label) = selected { + primitives: if let Some(label) = selected.or(placeholder) { let label = Primitive::Text { content: label, size: f32::from(text_size), diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 92c183f3..f83a2e8d 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -25,6 +25,7 @@ where last_selection: &'a mut Option, on_selected: Box Message>, options: Cow<'a, [T]>, + placeholder: Option, selected: Option, width: Length, padding: Padding, @@ -82,6 +83,7 @@ where last_selection, on_selected: Box::new(on_selected), options: options.into(), + placeholder: None, selected, width: Length::Shrink, text_size: None, @@ -91,6 +93,12 @@ where } } + /// Sets the placeholder of the [`PickList`]. + pub fn placeholder(mut self, placeholder: impl Into) -> Self { + self.placeholder = Some(placeholder.into()); + self + } + /// Sets the width of the [`PickList`]. pub fn width(mut self, width: Length) -> Self { self.width = width; @@ -158,8 +166,7 @@ where let max_width = match self.width { Length::Shrink => { let labels = self.options.iter().map(ToString::to_string); - - labels + let labels_width = labels .map(|label| { let (width, _) = renderer.measure( &label, @@ -171,7 +178,24 @@ where width.round() as u32 }) .max() - .unwrap_or(100) + .unwrap_or(100); + + let placeholder_width = self + .placeholder + .as_ref() + .map(|placeholder| { + let (width, _) = renderer.measure( + placeholder, + text_size, + self.font, + Size::new(f32::INFINITY, f32::INFINITY), + ); + + width.round() as u32 + }) + .unwrap_or(100); + + labels_width.max(placeholder_width) } _ => 0, }; @@ -265,6 +289,7 @@ where layout.bounds(), cursor_position, self.selected.as_ref().map(ToString::to_string), + self.placeholder.clone(), self.padding, self.text_size.unwrap_or(renderer.default_size()), self.font, @@ -325,6 +350,7 @@ pub trait Renderer: text::Renderer + menu::Renderer { bounds: Rectangle, cursor_position: Point, selected: Option, + placeholder: Option, padding: Padding, text_size: u16, font: Self::Font, -- cgit From 9c75ddcb3370c0e2caefdb0a3c1f30ea877faf02 Mon Sep 17 00:00:00 2001 From: Jon Pacheco Date: Sat, 22 May 2021 19:28:27 +0100 Subject: feat: add placeholder to pick_list example --- examples/pick_list/src/main.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/pick_list/src/main.rs b/examples/pick_list/src/main.rs index 68662602..1eec9791 100644 --- a/examples/pick_list/src/main.rs +++ b/examples/pick_list/src/main.rs @@ -11,7 +11,7 @@ pub fn main() -> iced::Result { struct Example { scroll: scrollable::State, pick_list: pick_list::State, - selected_language: Language, + selected_language: Option, } #[derive(Debug, Clone, Copy)] @@ -33,7 +33,7 @@ impl Sandbox for Example { fn update(&mut self, message: Message) { match message { Message::LanguageSelected(language) => { - self.selected_language = language; + self.selected_language = Some(language); } } } @@ -42,9 +42,10 @@ impl Sandbox for Example { let pick_list = PickList::new( &mut self.pick_list, &Language::ALL[..], - Some(self.selected_language), + self.selected_language, Message::LanguageSelected, - ); + ) + .placeholder("Choose a language..."); let mut content = Scrollable::new(&mut self.scroll) .width(Length::Fill) -- cgit From 45bd685f7c12ccb4c03a756b3d694672948c1a03 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 22 Jul 2021 18:55:55 +0700 Subject: Hash `placeholder` in `hash_layout` implementation for `PickList` --- native/src/widget/pick_list.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index f83a2e8d..fbc091ad 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -219,6 +219,8 @@ where match self.width { Length::Shrink => { + self.placeholder.hash(state); + self.options .iter() .map(ToString::to_string) -- cgit From 26b2a824a930b8f98f4510aa2d2f3aaef7b669b9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 22 Jul 2021 20:09:13 +0700 Subject: Remove duplication of measuring logic in `PickList` --- native/src/widget/pick_list.rs | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index fbc091ad..21c0c153 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -162,37 +162,31 @@ where .pad(self.padding); let text_size = self.text_size.unwrap_or(renderer.default_size()); + let font = self.font; let max_width = match self.width { Length::Shrink => { + let measure = |label: &str| -> u32 { + let (width, _) = renderer.measure( + label, + text_size, + font, + Size::new(f32::INFINITY, f32::INFINITY), + ); + + width.round() as u32 + }; + let labels = self.options.iter().map(ToString::to_string); - let labels_width = labels - .map(|label| { - let (width, _) = renderer.measure( - &label, - text_size, - self.font, - Size::new(f32::INFINITY, f32::INFINITY), - ); - - width.round() as u32 - }) - .max() - .unwrap_or(100); + + let labels_width = + labels.map(|label| measure(&label)).max().unwrap_or(100); let placeholder_width = self .placeholder .as_ref() - .map(|placeholder| { - let (width, _) = renderer.measure( - placeholder, - text_size, - self.font, - Size::new(f32::INFINITY, f32::INFINITY), - ); - - width.round() as u32 - }) + .map(String::as_str) + .map(measure) .unwrap_or(100); labels_width.max(placeholder_width) -- cgit From 1b3606884747374f1e5599e3c783f36a2f2cac6f Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 22 Jul 2021 20:13:14 +0700 Subject: Introduce `placeholder_color` to `pick_list::Style` --- examples/game_of_life/src/style.rs | 1 + graphics/src/widget/pick_list.rs | 5 ++++- style/src/pick_list.rs | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/game_of_life/src/style.rs b/examples/game_of_life/src/style.rs index 6605826f..be9a0e96 100644 --- a/examples/game_of_life/src/style.rs +++ b/examples/game_of_life/src/style.rs @@ -171,6 +171,7 @@ impl pick_list::StyleSheet for PickList { }, border_radius: 2.0, icon_size: 0.5, + ..pick_list::Style::default() } } diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs index a7fe3e93..01283bd5 100644 --- a/graphics/src/widget/pick_list.rs +++ b/graphics/src/widget/pick_list.rs @@ -38,6 +38,7 @@ where style: &Box, ) -> Self::Output { let is_mouse_over = bounds.contains(cursor_position); + let is_selected = selected.is_some(); let style = if is_mouse_over { style.hovered() @@ -74,7 +75,9 @@ where content: label, size: f32::from(text_size), font, - color: style.text_color, + color: is_selected + .then(|| style.text_color) + .unwrap_or(style.placeholder_color), bounds: Rectangle { x: bounds.x + f32::from(padding.left), y: bounds.center_y(), diff --git a/style/src/pick_list.rs b/style/src/pick_list.rs index a757ba98..d1801e5f 100644 --- a/style/src/pick_list.rs +++ b/style/src/pick_list.rs @@ -5,6 +5,7 @@ use iced_core::{Background, Color}; #[derive(Debug, Clone, Copy)] pub struct Style { pub text_color: Color, + pub placeholder_color: Color, pub background: Background, pub border_radius: f32, pub border_width: f32, @@ -16,6 +17,7 @@ impl std::default::Default for Style { fn default() -> Self { Self { text_color: Color::BLACK, + placeholder_color: [0.4, 0.4, 0.4].into(), background: Background::Color([0.87, 0.87, 0.87].into()), border_radius: 0.0, border_width: 1.0, -- cgit From a866f8742e4ddf5714455519790fed0f961fad66 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 22 Jul 2021 20:16:53 +0700 Subject: Avoid cloning `placeholder` for `PickList` unnecessarily during `draw` --- graphics/src/widget/pick_list.rs | 6 ++++-- native/src/widget/pick_list.rs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs index 01283bd5..88a590b5 100644 --- a/graphics/src/widget/pick_list.rs +++ b/graphics/src/widget/pick_list.rs @@ -31,7 +31,7 @@ where bounds: Rectangle, cursor_position: Point, selected: Option, - placeholder: Option, + placeholder: Option<&str>, padding: Padding, text_size: u16, font: Font, @@ -70,7 +70,9 @@ where ( Primitive::Group { - primitives: if let Some(label) = selected.or(placeholder) { + primitives: if let Some(label) = + selected.or_else(|| placeholder.map(str::to_string)) + { let label = Primitive::Text { content: label, size: f32::from(text_size), diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 21c0c153..4f4e751e 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -285,7 +285,7 @@ where layout.bounds(), cursor_position, self.selected.as_ref().map(ToString::to_string), - self.placeholder.clone(), + self.placeholder.as_ref().map(String::as_str), self.padding, self.text_size.unwrap_or(renderer.default_size()), self.font, @@ -346,7 +346,7 @@ pub trait Renderer: text::Renderer + menu::Renderer { bounds: Rectangle, cursor_position: Point, selected: Option, - placeholder: Option, + placeholder: Option<&str>, padding: Padding, text_size: u16, font: Self::Font, -- cgit