diff --git a/examples/cosmic/src/window/demo.rs b/examples/cosmic/src/window/demo.rs index f161117..ee04b41 100644 --- a/examples/cosmic/src/window/demo.rs +++ b/examples/cosmic/src/window/demo.rs @@ -5,7 +5,7 @@ use cosmic::{ cosmic_theme, iced::widget::{checkbox, column, pick_list, progress_bar, radio, slider, text, text_input}, iced::{id, Alignment, Length}, - theme::{self, Button as ButtonTheme, ThemeType}, + theme::ThemeType, widget::{ button, cosmic_container::container, icon, segmented_button, segmented_selection, settings, spin_button, toggler, view_switcher, @@ -472,6 +472,7 @@ impl State { .id(INPUT_ID.clone()) .into(), cosmic::widget::text_input("test", &self.entry_value) + .on_clear(Message::InputChanged("".to_string())) .width(Length::Fill) .on_input(Message::InputChanged) .into(), @@ -480,51 +481,36 @@ impl State { .padding(32) .on_input(Message::InputChanged) .into(), - cosmic::widget::search_input( - "test", - &self.entry_value, - Some(Message::InputChanged("".to_string())), - ) - .width(Length::Fill) - .on_input(Message::InputChanged) - .into(), + cosmic::widget::search_input("test", &self.entry_value) + .on_clear(Message::InputChanged("".to_string())) + .width(Length::Fill) + .on_input(Message::InputChanged) + .into(), cosmic::widget::text_input("test", &self.entry_value) .width(Length::Fixed(600.0)) .on_input(Message::InputChanged) .into(), - cosmic::widget::search_input( - "test", - &self.entry_value, - Some(Message::InputChanged("".to_string())), - ) - .width(Length::Fixed(100.0)) - .on_input(Message::InputChanged) - .into(), - cosmic::widget::search_input( - "test", - &self.entry_value, - Some(Message::InputChanged("".to_string())), - ) - .padding([24, 48]) - .width(Length::Fixed(400.0)) - .on_input(Message::InputChanged) - .into(), - cosmic::widget::search_input( - "test", - &self.entry_value, - Some(Message::InputChanged("".to_string())), - ) - .width(Length::Fixed(400.0)) - .on_input(Message::InputChanged) - .into(), - cosmic::widget::search_input( - "test", - &self.entry_value, - Some(Message::InputChanged("".to_string())), - ) - .width(Length::Fixed(800.0)) - .on_input(Message::InputChanged) - .into(), + cosmic::widget::search_input("test", &self.entry_value) + .on_clear(Message::InputChanged("".to_string())) + .width(Length::Fixed(100.0)) + .on_input(Message::InputChanged) + .into(), + cosmic::widget::search_input("test", &self.entry_value) + .on_clear(Message::InputChanged("".to_string())) + .padding([24, 48]) + .width(Length::Fixed(400.0)) + .on_input(Message::InputChanged) + .into(), + cosmic::widget::search_input("test", &self.entry_value) + .on_clear(Message::InputChanged("".to_string())) + .width(Length::Fixed(400.0)) + .on_input(Message::InputChanged) + .into(), + cosmic::widget::search_input("test", &self.entry_value) + .on_clear(Message::InputChanged("".to_string())) + .width(Length::Fixed(800.0)) + .on_input(Message::InputChanged) + .into(), ]) .into() } diff --git a/src/widget/text_input/input.rs b/src/widget/text_input/input.rs index 7225d86..308a83f 100644 --- a/src/widget/text_input/input.rs +++ b/src/widget/text_input/input.rs @@ -49,7 +49,7 @@ use sctk::reexports::client::protocol::wl_data_device_manager::DndAction; /// [`TextInput`]: widget::TextInput pub fn text_input<'a, Message>(placeholder: &str, value: &str) -> TextInput<'a, Message> where - Message: Clone, + Message: Clone + 'static, { TextInput::new(placeholder, value) } @@ -57,16 +57,13 @@ where /// Creates a new search [`TextInput`]. /// /// [`TextInput`]: widget::TextInput -pub fn search_input<'a, Message>( - placeholder: &str, - value: &str, - on_clear: Option, -) -> TextInput<'a, Message> +pub fn search_input<'a, Message>(placeholder: &str, value: &str) -> TextInput<'a, Message> where Message: Clone + 'static, { let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs()); - let input = TextInput::new(placeholder, value) + + TextInput::new(placeholder, value) .padding([0, spacing, 0, spacing]) .style(crate::theme::TextInput::Search) .leading_icon( @@ -75,23 +72,7 @@ where .apply(crate::widget::container) .padding([spacing, spacing, spacing, spacing]) .into(), - ); - - if let Some(msg) = on_clear { - input.trailing_icon( - crate::widget::icon::from_name("edit-clear-symbolic") - .size(16) - .apply(crate::widget::button) - .style(crate::theme::Button::Icon) - .width(32) - .height(32) - .on_press(msg) - .padding([spacing, spacing, spacing, spacing]) - .into(), ) - } else { - input - } } /// Creates a new search [`TextInput`]. /// @@ -139,7 +120,7 @@ where /// [`TextInput`]: widget::TextInput pub fn inline_input<'a, Message>(value: &str) -> TextInput<'a, Message> where - Message: Clone, + Message: Clone + 'static, { let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs()); @@ -217,7 +198,7 @@ pub struct TextInput<'a, Message> { impl<'a, Message> TextInput<'a, Message> where - Message: Clone, + Message: Clone + 'static, { /// Creates a new [`TextInput`]. /// @@ -447,6 +428,22 @@ where self } + pub fn on_clear(self, on_clear: Message) -> Self { + let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs()); + + self.trailing_icon( + crate::widget::icon::from_name("edit-clear-symbolic") + .size(16) + .apply(crate::widget::button) + .style(crate::theme::Button::Icon) + .width(32) + .height(32) + .on_press(on_clear) + .padding([spacing, spacing, spacing, spacing]) + .into(), + ) + } + /// Get the layout node of the actual text input fn text_layout<'b>(&'a self, layout: Layout<'b>) -> Layout<'b> { if self.dnd_icon { @@ -463,7 +460,7 @@ where impl<'a, Message> Widget for TextInput<'a, Message> where - Message: Clone, + Message: Clone + 'static, { fn tag(&self) -> tree::Tag { tree::Tag::of::() @@ -571,8 +568,10 @@ where viewport: &Rectangle, ) -> event::Status { let text_layout = self.text_layout(layout); - let mut child_state = tree.children.iter_mut(); - if let (Some(leading_icon), Some(tree)) = (self.leading_icon.as_mut(), child_state.next()) { + let mut index = 0; + if let (Some(leading_icon), Some(tree)) = + (self.leading_icon.as_mut(), tree.children.get_mut(index)) + { let mut children = text_layout.children(); children.next(); let leading_icon_layout = children.next().unwrap(); @@ -589,12 +588,16 @@ where viewport, ); } + index += 1; } - if let (Some(trailing_icon), Some(tree)) = (self.trailing_icon.as_mut(), child_state.next()) + if let (Some(trailing_icon), Some(tree)) = + (self.trailing_icon.as_mut(), tree.children.get_mut(index)) { let mut children = text_layout.children(); children.next(); - children.next(); + if self.leading_icon.is_some() { + children.next(); + } let trailing_icon_layout = children.next().unwrap(); if cursor_position.is_over(trailing_icon_layout.bounds()) { @@ -705,7 +708,10 @@ where { let mut children = layout.children(); children.next(); - children.next(); + // skip if there is no leading icon + if self.leading_icon.is_some() { + children.next(); + } let trailing_icon_layout = children.next().unwrap(); if cursor_position.is_over(trailing_icon_layout.bounds()) { @@ -726,7 +732,7 @@ where impl<'a, Message> From> for Element<'a, Message, crate::Renderer> where - Message: 'a + Clone, + Message: 'static + Clone, { fn from(text_input: TextInput<'a, Message>) -> Element<'a, Message, crate::Renderer> { Element::new(text_input)