diff --git a/crates/story/src/dropdown_story.rs b/crates/story/src/dropdown_story.rs index 360b8435..d6a56949 100644 --- a/crates/story/src/dropdown_story.rs +++ b/crates/story/src/dropdown_story.rs @@ -6,7 +6,7 @@ use gpui::{ }; use ui::{ - dropdown::{Dropdown, DropdownItem}, + dropdown::{Dropdown, DropdownEvent, DropdownItem}, h_flex, theme::ActiveTheme, v_flex, Selection, @@ -40,7 +40,7 @@ impl DropdownItem for Country { pub struct DropdownStory { country_dropdown: View>>, - furit_dropdown: View>>, + fruit_dropdown: View>>, simple_dropdown1: View>>, simple_dropdown2: View>>, } @@ -61,13 +61,10 @@ impl DropdownStory { Country::new("Ecuador", "EC"), ]; - let country_dropdown = cx.new_view(|cx| { - Dropdown::new("dropdown-country", countries, Some(6), cx).on_change(|value, _cx| { - println!("Country changed: {:?}", value); - }) - }); + let country_dropdown = + cx.new_view(|cx| Dropdown::new("dropdown-country", countries, Some(6), cx)); - let furits = vec![ + let fruits = vec![ "Apple", "Orange", "Banana", @@ -76,37 +73,39 @@ impl DropdownStory { "Watermelon", "Avocado", ]; - let furit_dropdown = cx.new_view(|cx| { - Dropdown::string_list("dropdown-furits", furits, None, cx).on_change(|value, _cx| { - println!("Furit changed: {:?}", value); - }) - }); + let fruit_dropdown = + cx.new_view(|cx| Dropdown::string_list("dropdown-fruits", fruits, None, cx)); - cx.new_view(|cx| Self { - country_dropdown, - furit_dropdown, - simple_dropdown1: cx.new_view(|cx| { - Dropdown::string_list( - "string-list1", - vec!["QPUI", "Iced", "QT", "Cocoa"], - Some(0), - cx, - ) - .size(ui::Size::Small) - .placeholder("UI") - .title_prefix("UI: ") - }), - simple_dropdown2: cx.new_view(|cx| { - Dropdown::string_list( - "string-list2", - vec!["Rust", "Go", "C++", "JavaScript"], - None, - cx, - ) - .size(ui::Size::Small) - .placeholder("Language") - .title_prefix("Language: ") - }), + cx.new_view(|cx| { + cx.subscribe(&country_dropdown, Self::on_dropdown_event) + .detach(); + + Self { + country_dropdown, + fruit_dropdown, + simple_dropdown1: cx.new_view(|cx| { + Dropdown::string_list( + "string-list1", + vec!["QPUI", "Iced", "QT", "Cocoa"], + Some(0), + cx, + ) + .size(ui::Size::Small) + .placeholder("UI") + .title_prefix("UI: ") + }), + simple_dropdown2: cx.new_view(|cx| { + Dropdown::string_list( + "string-list2", + vec!["Rust", "Go", "C++", "JavaScript"], + None, + cx, + ) + .size(ui::Size::Small) + .placeholder("Language") + .title_prefix("Language: ") + }), + } }) } @@ -114,6 +113,17 @@ impl DropdownStory { fn on_click(sel: &Selection, cx: &mut WindowContext) { println!("Check value changed: {}", sel); } + + fn on_dropdown_event( + &mut self, + _: View>>, + event: &DropdownEvent>, + _cx: &mut ViewContext, + ) { + match event { + DropdownEvent::Confirm(value) => println!("Selected country: {:?}", value), + } + } } impl Render for DropdownStory { @@ -128,7 +138,7 @@ impl Render for DropdownStory { .items_center() .gap_4() .child(self.country_dropdown.clone()) - .child(self.furit_dropdown.clone()), + .child(self.fruit_dropdown.clone()), ) .child( v_flex() @@ -145,8 +155,8 @@ impl Render for DropdownStory { self.country_dropdown.read(cx).selected_value() )) .child(format!( - "Furit: {:?}", - self.furit_dropdown.read(cx).selected_value() + "fruit: {:?}", + self.fruit_dropdown.read(cx).selected_value() )) .child(format!( "UI: {:?}", diff --git a/crates/ui/src/dropdown.rs b/crates/ui/src/dropdown.rs index e5efecf4..0b0ba324 100644 --- a/crates/ui/src/dropdown.rs +++ b/crates/ui/src/dropdown.rs @@ -159,10 +159,7 @@ where .selected_index .and_then(|ix| self.delegate.get(ix)) .map(|item| item.value().clone()); - - if let Some(on_change) = &view.on_change { - on_change(&selected_value, cx); - } + cx.emit(DropdownEvent::Confirm(selected_value.clone())); view.selected_value = selected_value; view.open = false; }); @@ -174,6 +171,10 @@ where } } +pub enum DropdownEvent { + Confirm(Option<::Value>), +} + pub struct Dropdown { id: ElementId, focus_handle: FocusHandle, @@ -184,9 +185,6 @@ pub struct Dropdown { placeholder: SharedString, title_prefix: Option, selected_value: Option<::Value>, - on_change: Option< - Box::Value>, &mut WindowContext) + 'static>, - >, } impl Dropdown @@ -216,7 +214,6 @@ where open: false, cleanable: true, title_prefix: None, - on_change: None, }; this.update_selected_value(cx); this @@ -249,14 +246,6 @@ where self } - pub fn on_change( - mut self, - on_change: impl Fn(&Option<::Value>, &mut WindowContext) + 'static, - ) -> Self { - self.on_change = Some(Box::new(on_change)); - self - } - pub fn set_selected_index( &mut self, selected_index: Option, @@ -390,6 +379,7 @@ impl Dropdown> { } } +impl EventEmitter> for Dropdown where D: DropdownDelegate + 'static {} impl EventEmitter for Dropdown where D: DropdownDelegate + 'static {} impl FocusableView for Dropdown where