contacts_status_item.rs

 1mod contacts_popover;
 2
 3use contacts_popover::ContactsPopover;
 4use gpui::{
 5    actions,
 6    color::Color,
 7    elements::*,
 8    geometry::{rect::RectF, vector::vec2f},
 9    Appearance, Entity, MouseButton, MutableAppContext, RenderContext, View, ViewContext,
10    ViewHandle, WindowKind,
11};
12
13actions!(contacts_status_item, [ToggleContactsPopover]);
14
15pub fn init(cx: &mut MutableAppContext) {
16    cx.add_action(ContactsStatusItem::toggle_contacts_popover);
17}
18
19pub struct ContactsStatusItem {
20    popover: Option<ViewHandle<ContactsPopover>>,
21}
22
23impl Entity for ContactsStatusItem {
24    type Event = ();
25}
26
27impl View for ContactsStatusItem {
28    fn ui_name() -> &'static str {
29        "ContactsStatusItem"
30    }
31
32    fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
33        let color = match cx.appearance {
34            Appearance::Light | Appearance::VibrantLight => Color::black(),
35            Appearance::Dark | Appearance::VibrantDark => Color::white(),
36        };
37        MouseEventHandler::<Self>::new(0, cx, |_, _| {
38            Svg::new("icons/zed_22.svg")
39                .with_color(color)
40                .aligned()
41                .boxed()
42        })
43        .on_click(MouseButton::Left, |_, cx| {
44            cx.dispatch_action(ToggleContactsPopover);
45        })
46        .boxed()
47    }
48}
49
50impl ContactsStatusItem {
51    pub fn new() -> Self {
52        Self { popover: None }
53    }
54
55    fn toggle_contacts_popover(&mut self, _: &ToggleContactsPopover, cx: &mut ViewContext<Self>) {
56        match self.popover.take() {
57            Some(popover) => {
58                cx.remove_window(popover.window_id());
59            }
60            None => {
61                let window_bounds = cx.window_bounds();
62                let size = vec2f(360., 460.);
63                let origin = window_bounds.lower_left()
64                    + vec2f(window_bounds.width() / 2. - size.x() / 2., 0.);
65                let (_, popover) = cx.add_window(
66                    gpui::WindowOptions {
67                        bounds: gpui::WindowBounds::Fixed(RectF::new(origin, size)),
68                        titlebar: None,
69                        center: false,
70                        kind: WindowKind::PopUp,
71                        is_movable: false,
72                    },
73                    |cx| ContactsPopover::new(cx),
74                );
75                cx.subscribe(&popover, Self::on_popover_event).detach();
76                self.popover = Some(popover);
77            }
78        }
79    }
80
81    fn on_popover_event(
82        &mut self,
83        popover: ViewHandle<ContactsPopover>,
84        event: &contacts_popover::Event,
85        cx: &mut ViewContext<Self>,
86    ) {
87        match event {
88            contacts_popover::Event::Deactivated => {
89                self.popover.take();
90                cx.remove_window(popover.window_id());
91            }
92        }
93    }
94}