From 672240d7504431ef147c1c33fb7e67ce1d307728 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 26 Jun 2024 19:01:52 +0800 Subject: [PATCH] Fix picker_story to display selected value. --- crates/ui-story/src/picker_story.rs | 40 ++++++++++++++++++++++++----- crates/ui/src/list/list_item.rs | 24 ++++++++++++----- crates/ui/src/picker.rs | 2 +- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/crates/ui-story/src/picker_story.rs b/crates/ui-story/src/picker_story.rs index a9e1cc4c..468f4ddb 100644 --- a/crates/ui-story/src/picker_story.rs +++ b/crates/ui-story/src/picker_story.rs @@ -1,7 +1,7 @@ use gpui::{ - div, prelude::FluentBuilder as _, px, Div, Empty, Entity, InteractiveElement as _, IntoElement, - ParentElement, Render, SharedString, Styled, Task, View, ViewContext, VisualContext as _, - WindowContext, + actions, div, prelude::FluentBuilder as _, px, Div, Empty, Entity, InteractiveElement as _, + IntoElement, ParentElement, Render, SharedString, Styled, Task, View, ViewContext, + VisualContext as _, WeakView, WindowContext, }; use ui::{ @@ -17,7 +17,10 @@ use ui::{ use super::story_case; +actions!(picker_story, [DismissPicker]); + pub struct ListItemDeletegate { + story: WeakView, selected_index: usize, items: Vec, matches: Vec, @@ -42,12 +45,12 @@ impl PickerDelegate for ListItemDeletegate { &self, ix: usize, selected: bool, - cx: &mut ViewContext>, + _cx: &mut ViewContext>, ) -> Option { - let is_selected = ix == self.selected_index; if let Some(item) = self.matches.get(ix) { let list_item = ListItem::new(format!("item-{}", ix)) - .selected(is_selected) + .check_icon(ui::IconName::Check) + .selected(selected) .py_1() .px_3() .child(item.clone()); @@ -73,6 +76,27 @@ impl PickerDelegate for ListItemDeletegate { Task::ready(()) } + + fn dismissed(&mut self, cx: &mut ViewContext>) { + if let Some(story) = self.story.upgrade() { + cx.update_view(&story, |story, cx| { + story.open = false; + cx.notify(); + }); + } + } + + fn confirm(&mut self, _secondary: bool, cx: &mut ViewContext>) { + if let Some(story) = self.story.upgrade() { + cx.update_view(&story, |story, cx| { + if let Some(item) = self.matches.get(self.selected_index) { + story.selected_value = Some(item.clone()); + } + story.open = false; + cx.notify(); + }); + } + } } pub struct PickerStory { @@ -82,7 +106,7 @@ pub struct PickerStory { } impl PickerStory { - pub(crate) fn new(cx: &mut WindowContext) -> Self { + pub(crate) fn new(cx: &mut ViewContext) -> Self { let items = [ "Baguette (France)", "Baklava (Turkey)", @@ -135,11 +159,13 @@ impl PickerStory { "Wiener Schnitzel (Austria)", ]; + let story = cx.view().downgrade(); let picker = cx.new_view(|cx| { let items: Vec = items.iter().map(|s| s.to_string()).collect(); let mut picker = Picker::uniform_list( ListItemDeletegate { + story, selected_index: 0, matches: items.clone(), items, diff --git a/crates/ui/src/list/list_item.rs b/crates/ui/src/list/list_item.rs index ac4e7cf5..c3d3d82d 100644 --- a/crates/ui/src/list/list_item.rs +++ b/crates/ui/src/list/list_item.rs @@ -4,13 +4,14 @@ use gpui::{ StatefulInteractiveElement as _, Style, Styled, WindowContext, }; -use crate::{h_flex, theme::ActiveTheme, Disableable, IconName, Selectable}; +use crate::{h_flex, theme::ActiveTheme, Disableable, Icon, IconName, Selectable}; #[derive(IntoElement)] pub struct ListItem { base: Stateful
, disabled: bool, selected: bool, + check_icon: Option, on_click: Option>, on_secondary_mouse_down: Option>, } @@ -23,9 +24,15 @@ impl ListItem { selected: false, on_click: None, on_secondary_mouse_down: None, + check_icon: None, } } + pub fn check_icon(mut self, icon: IconName) -> Self { + self.check_icon = Some(icon); + self + } + pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self { self.on_click = Some(Box::new(handler)); self @@ -68,7 +75,10 @@ impl ParentElement for ListItem { impl RenderOnce for ListItem { fn render(self, cx: &mut WindowContext) -> impl IntoElement { - self.base + h_flex() + .id("item-group") + .items_center() + .gap_2() .w_full() .relative() .gap_x_2() @@ -85,12 +95,12 @@ impl RenderOnce for ListItem { this.hover(|this| this.bg(cx.theme().accent)) }) .when(self.selected, |this| this.bg(cx.theme().accent)) - .map(|this| { - if self.selected { - this.child(IconName::Check) + .child(self.base.when(self.selected, |this| { + if let Some(icon) = self.check_icon { + this.child(icon) } else { - this.child(div()) + this } - }) + })) } } diff --git a/crates/ui/src/picker.rs b/crates/ui/src/picker.rs index 2c578ff7..719f9202 100644 --- a/crates/ui/src/picker.rs +++ b/crates/ui/src/picker.rs @@ -56,7 +56,7 @@ pub trait PickerDelegate: Sized + 'static { fn confirm(&mut self, secondary: bool, cx: &mut ViewContext>) {} fn dismissed(&mut self, cx: &mut ViewContext>) {} fn should_dismiss(&self) -> bool { - return true; + true } fn render_query(&self, input: &View, _cx: &mut ViewContext>) -> Div { v_flex()