Add on_opened and on_closed handlers for PickList

This commit is contained in:
Rinat 2023-12-01 10:34:15 +05:00 committed by Héctor Ramón Jiménez
parent b5b267c31c
commit 6cf7c4645d
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
2 changed files with 33 additions and 2 deletions

View file

@ -271,6 +271,7 @@ pub fn pick_list<'a, Message, Theme, Renderer, T>(
where where
T: ToString + PartialEq + 'static, T: ToString + PartialEq + 'static,
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Message: Clone,
Renderer: core::text::Renderer, Renderer: core::text::Renderer,
Theme: pick_list::StyleSheet Theme: pick_list::StyleSheet
+ scrollable::StyleSheet + scrollable::StyleSheet

View file

@ -35,6 +35,8 @@ pub struct PickList<
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
on_selected: Box<dyn Fn(T) -> Message + 'a>, on_selected: Box<dyn Fn(T) -> Message + 'a>,
on_opened: Option<Message>,
on_closed: Option<Message>,
options: Cow<'a, [T]>, options: Cow<'a, [T]>,
placeholder: Option<String>, placeholder: Option<String>,
selected: Option<T>, selected: Option<T>,
@ -53,6 +55,7 @@ impl<'a, T: 'a, Message, Theme, Renderer>
where where
T: ToString + PartialEq, T: ToString + PartialEq,
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Message: Clone,
Theme: StyleSheet Theme: StyleSheet
+ scrollable::StyleSheet + scrollable::StyleSheet
+ menu::StyleSheet + menu::StyleSheet
@ -72,6 +75,8 @@ where
) -> Self { ) -> Self {
Self { Self {
on_selected: Box::new(on_selected), on_selected: Box::new(on_selected),
on_opened: None,
on_closed: None,
options: options.into(), options: options.into(),
placeholder: None, placeholder: None,
selected, selected,
@ -137,6 +142,18 @@ where
self self
} }
/// Sets the message that will be produced when the [`PickList`] Menu is openned menu.
pub fn on_opened(mut self, msg: Message) -> Self {
self.on_opened = Some(msg);
self
}
/// Sets the message that will be produced when the [`PickList`] Menu is closed menu.
pub fn on_closed(mut self, msg: Message) -> Self {
self.on_closed = Some(msg);
self
}
/// Sets the style of the [`PickList`]. /// Sets the style of the [`PickList`].
pub fn style( pub fn style(
mut self, mut self,
@ -152,7 +169,7 @@ impl<'a, T: 'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
where where
T: Clone + ToString + PartialEq + 'static, T: Clone + ToString + PartialEq + 'static,
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Message: 'a, Message: Clone + 'a,
Theme: StyleSheet Theme: StyleSheet
+ scrollable::StyleSheet + scrollable::StyleSheet
+ menu::StyleSheet + menu::StyleSheet
@ -213,6 +230,8 @@ where
cursor, cursor,
shell, shell,
self.on_selected.as_ref(), self.on_selected.as_ref(),
self.on_opened.as_ref(),
self.on_closed.as_ref(),
self.selected.as_ref(), self.selected.as_ref(),
&self.options, &self.options,
|| tree.state.downcast_mut::<State<Renderer::Paragraph>>(), || tree.state.downcast_mut::<State<Renderer::Paragraph>>(),
@ -290,7 +309,7 @@ impl<'a, T: 'a, Message, Theme, Renderer>
where where
T: Clone + ToString + PartialEq + 'static, T: Clone + ToString + PartialEq + 'static,
[T]: ToOwned<Owned = Vec<T>>, [T]: ToOwned<Owned = Vec<T>>,
Message: 'a, Message: Clone + 'a,
Theme: StyleSheet Theme: StyleSheet
+ scrollable::StyleSheet + scrollable::StyleSheet
+ menu::StyleSheet + menu::StyleSheet
@ -474,6 +493,8 @@ pub fn update<'a, T, P, Message>(
cursor: mouse::Cursor, cursor: mouse::Cursor,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
on_selected: &dyn Fn(T) -> Message, on_selected: &dyn Fn(T) -> Message,
on_opened: Option<&Message>,
on_closed: Option<&Message>,
selected: Option<&T>, selected: Option<&T>,
options: &[T], options: &[T],
state: impl FnOnce() -> &'a mut State<P>, state: impl FnOnce() -> &'a mut State<P>,
@ -481,6 +502,7 @@ pub fn update<'a, T, P, Message>(
where where
T: PartialEq + Clone + 'a, T: PartialEq + Clone + 'a,
P: text::Paragraph + 'a, P: text::Paragraph + 'a,
Message: Clone,
{ {
match event { match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
@ -492,12 +514,20 @@ where
// bounds or on the drop-down, either way we close the overlay. // bounds or on the drop-down, either way we close the overlay.
state.is_open = false; state.is_open = false;
if let Some(on_closed) = on_closed {
shell.publish(on_closed.clone());
}
event::Status::Captured event::Status::Captured
} else if cursor.is_over(layout.bounds()) { } else if cursor.is_over(layout.bounds()) {
state.is_open = true; state.is_open = true;
state.hovered_option = state.hovered_option =
options.iter().position(|option| Some(option) == selected); options.iter().position(|option| Some(option) == selected);
if let Some(on_opened) = on_opened {
shell.publish(on_opened.clone());
}
event::Status::Captured event::Status::Captured
} else { } else {
event::Status::Ignored event::Status::Ignored