tool_selector.rs

 1use std::sync::Arc;
 2
 3use assistant_tool::{ToolSource, ToolWorkingSet};
 4use gpui::Entity;
 5use ui::{prelude::*, ContextMenu, IconButtonShape, PopoverMenu, Tooltip};
 6
 7pub struct ToolSelector {
 8    tools: Arc<ToolWorkingSet>,
 9}
10
11impl ToolSelector {
12    pub fn new(tools: Arc<ToolWorkingSet>, _cx: &mut Context<Self>) -> Self {
13        Self { tools }
14    }
15
16    fn build_context_menu(
17        &self,
18        window: &mut Window,
19        cx: &mut Context<Self>,
20    ) -> Entity<ContextMenu> {
21        ContextMenu::build(window, cx, |mut menu, _window, cx| {
22            let tools_by_source = self.tools.tools_by_source(cx);
23
24            for (source, tools) in tools_by_source {
25                menu = match source {
26                    ToolSource::Native => menu.header("Zed"),
27                    ToolSource::ContextServer { id } => menu.separator().header(id),
28                };
29
30                for tool in tools {
31                    let source = tool.source();
32                    let name = tool.name().into();
33                    let is_enabled = self.tools.is_enabled(&source, &name);
34
35                    menu =
36                        menu.toggleable_entry(tool.name(), is_enabled, IconPosition::End, None, {
37                            let tools = self.tools.clone();
38                            move |_window, _cx| {
39                                if is_enabled {
40                                    tools.disable(source.clone(), &[name.clone()]);
41                                } else {
42                                    tools.enable(source.clone(), &[name.clone()]);
43                                }
44                            }
45                        });
46                }
47            }
48
49            menu
50        })
51    }
52}
53
54impl Render for ToolSelector {
55    fn render(&mut self, _window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement {
56        let this = cx.entity().clone();
57        PopoverMenu::new("tool-selector")
58            .menu(move |window, cx| {
59                Some(this.update(cx, |this, cx| this.build_context_menu(window, cx)))
60            })
61            .trigger_with_tooltip(
62                IconButton::new("tool-selector-button", IconName::SettingsAlt)
63                    .shape(IconButtonShape::Square)
64                    .icon_size(IconSize::Small)
65                    .icon_color(Color::Muted),
66                Tooltip::text("Customize Tools"),
67            )
68            .anchor(gpui::Corner::BottomLeft)
69    }
70}