Add dismiss button to project search

Piotr Osiewicz created

Change summary

crates/search/src/buffer_search.rs  | 42 ++++--------------------------
crates/search/src/project_search.rs | 17 +++++++++++
crates/search/src/search.rs         |  1 
crates/search/src/search_bar.rs     | 34 +++++++++++++++++++++++++
4 files changed, 57 insertions(+), 37 deletions(-)

Detailed changes

crates/search/src/buffer_search.rs 🔗

@@ -222,7 +222,12 @@ impl View for BufferSearchBar {
                     )
                     .flex(1., true),
             )
-            .with_child(self.render_close_button(&theme.search, cx))
+            .with_child(super::search_bar::render_close_button(
+                &theme.search,
+                cx,
+                |_, this, cx| this.dismiss(&Default::default(), cx),
+                Some(Box::new(Dismiss)),
+            ))
             .contained()
             .with_style(theme.search.container)
             .into_any_named("search bar")
@@ -518,41 +523,6 @@ impl BufferSearchBar {
         .into_any()
     }
 
-    fn render_close_button(
-        &self,
-        theme: &theme::Search,
-        cx: &mut ViewContext<Self>,
-    ) -> AnyElement<Self> {
-        let tooltip = "Dismiss Buffer Search";
-        let tooltip_style = theme::current(cx).tooltip.clone();
-
-        enum CloseButton {}
-        MouseEventHandler::<CloseButton, _>::new(0, cx, |state, _| {
-            let style = theme.dismiss_button.style_for(state);
-            Svg::new("icons/x_mark_8.svg")
-                .with_color(style.color)
-                .constrained()
-                .with_width(style.icon_width)
-                .aligned()
-                .constrained()
-                .with_width(style.button_width)
-                .contained()
-                .with_style(style.container)
-        })
-        .on_click(MouseButton::Left, move |_, this, cx| {
-            this.dismiss(&Default::default(), cx)
-        })
-        .with_cursor_style(CursorStyle::PointingHand)
-        .with_tooltip::<CloseButton>(
-            0,
-            tooltip.to_string(),
-            Some(Box::new(Dismiss)),
-            tooltip_style,
-            cx,
-        )
-        .into_any()
-    }
-
     fn deploy(pane: &mut Pane, action: &Deploy, cx: &mut ViewContext<Pane>) {
         let mut propagate_action = true;
         if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {

crates/search/src/project_search.rs 🔗

@@ -362,10 +362,12 @@ impl ProjectSearch {
     }
 }
 
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum ViewEvent {
     UpdateTab,
     Activate,
     EditorEvent(editor::Event),
+    Dismiss,
 }
 
 impl Entity for ProjectSearchView {
@@ -547,7 +549,9 @@ impl Item for ProjectSearchView {
             .then(|| query_text.into())
             .or_else(|| Some("Project Search".into()))
     }
-
+    fn should_close_item_on_event(event: &Self::Event) -> bool {
+        event == &Self::Event::Dismiss
+    }
     fn act_as_type<'a>(
         &'a self,
         type_id: TypeId,
@@ -679,6 +683,7 @@ impl Item for ProjectSearchView {
                 smallvec::smallvec![ItemEvent::UpdateBreadcrumbs, ItemEvent::UpdateTab]
             }
             ViewEvent::EditorEvent(editor_event) => Editor::to_item_events(editor_event),
+            ViewEvent::Dismiss => smallvec::smallvec![ItemEvent::CloseItem],
             _ => SmallVec::new(),
         }
     }
@@ -2010,6 +2015,16 @@ impl View for ProjectSearchBar {
                                 .with_child(self.render_search_mode_button(SearchMode::Text, cx))
                                 .with_children(semantic_index)
                                 .with_child(self.render_search_mode_button(SearchMode::Regex, cx))
+                                .with_child(super::search_bar::render_close_button(
+                                    &theme.search,
+                                    cx,
+                                    |_, this, cx| {
+                                        if let Some(search) = this.active_project_search.as_mut() {
+                                            search.update(cx, |_, cx| cx.emit(ViewEvent::Dismiss))
+                                        }
+                                    },
+                                    None,
+                                ))
                                 .constrained()
                                 .with_height(theme.workspace.toolbar.height)
                                 .contained()

crates/search/src/search.rs 🔗

@@ -7,6 +7,7 @@ use smallvec::SmallVec;
 
 pub mod buffer_search;
 pub mod project_search;
+pub(crate) mod search_bar;
 
 pub fn init(cx: &mut AppContext) {
     buffer_search::init(cx);

crates/search/src/search_bar.rs 🔗

@@ -0,0 +1,34 @@
+use gpui::{
+    elements::{MouseEventHandler, Svg},
+    platform::{CursorStyle, MouseButton},
+    scene::MouseClick,
+    Action, AnyElement, Element, EventContext, View, ViewContext,
+};
+
+pub(super) fn render_close_button<V: View>(
+    theme: &theme::Search,
+    cx: &mut ViewContext<V>,
+    on_click: impl Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
+    dismiss_action: Option<Box<dyn Action>>,
+) -> AnyElement<V> {
+    let tooltip = "Dismiss Buffer Search";
+    let tooltip_style = theme::current(cx).tooltip.clone();
+
+    enum CloseButton {}
+    MouseEventHandler::<CloseButton, _>::new(0, cx, |state, _| {
+        let style = theme.dismiss_button.style_for(state);
+        Svg::new("icons/x_mark_8.svg")
+            .with_color(style.color)
+            .constrained()
+            .with_width(style.icon_width)
+            .aligned()
+            .constrained()
+            .with_width(style.button_width)
+            .contained()
+            .with_style(style.container)
+    })
+    .on_click(MouseButton::Left, on_click)
+    .with_cursor_style(CursorStyle::PointingHand)
+    .with_tooltip::<CloseButton>(0, tooltip.to_string(), dismiss_action, tooltip_style, cx)
+    .into_any()
+}