tooltip.rs

 1use gpui::{Action, AnyView, Div, Render, VisualContext};
 2use settings2::Settings;
 3use theme2::{ActiveTheme, ThemeSettings};
 4
 5use crate::prelude::*;
 6use crate::{h_stack, v_stack, KeyBinding, Label, LabelSize, StyledExt, TextColor};
 7
 8pub struct Tooltip {
 9    title: SharedString,
10    meta: Option<SharedString>,
11    key_binding: Option<KeyBinding>,
12}
13
14impl Tooltip {
15    pub fn text(title: impl Into<SharedString>, cx: &mut WindowContext) -> AnyView {
16        cx.build_view(|cx| Self {
17            title: title.into(),
18            meta: None,
19            key_binding: None,
20        })
21        .into()
22    }
23
24    pub fn for_action(
25        title: impl Into<SharedString>,
26        action: &dyn Action,
27        cx: &mut WindowContext,
28    ) -> AnyView {
29        cx.build_view(|cx| Self {
30            title: title.into(),
31            meta: None,
32            key_binding: KeyBinding::for_action(action, cx),
33        })
34        .into()
35    }
36
37    pub fn with_meta(
38        title: impl Into<SharedString>,
39        action: Option<&dyn Action>,
40        meta: impl Into<SharedString>,
41        cx: &mut WindowContext,
42    ) -> AnyView {
43        cx.build_view(|cx| Self {
44            title: title.into(),
45            meta: Some(meta.into()),
46            key_binding: action.and_then(|action| KeyBinding::for_action(action, cx)),
47        })
48        .into()
49    }
50
51    pub fn new(title: impl Into<SharedString>) -> Self {
52        Self {
53            title: title.into(),
54            meta: None,
55            key_binding: None,
56        }
57    }
58
59    pub fn meta(mut self, meta: impl Into<SharedString>) -> Self {
60        self.meta = Some(meta.into());
61        self
62    }
63
64    pub fn key_binding(mut self, key_binding: impl Into<Option<KeyBinding>>) -> Self {
65        self.key_binding = key_binding.into();
66        self
67    }
68}
69
70impl Render for Tooltip {
71    type Element = Div<Self>;
72
73    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
74        let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
75        v_stack()
76            .elevation_2(cx)
77            .font(ui_font)
78            .text_ui_sm()
79            .text_color(cx.theme().colors().text)
80            .py_1()
81            .px_2()
82            .child(
83                h_stack()
84                    .child(self.title.clone())
85                    .when_some(self.key_binding.clone(), |this, key_binding| {
86                        this.justify_between().child(key_binding)
87                    }),
88            )
89            .when_some(self.meta.clone(), |this, meta| {
90                this.child(
91                    Label::new(meta)
92                        .size(LabelSize::Small)
93                        .color(TextColor::Muted),
94                )
95            })
96    }
97}