use crate::theme::{Theme, ThemeExt};
use gpui::prelude::*;
use gpui::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TooltipPlacement {
#[default]
Top,
Bottom,
Left,
Right,
}
pub struct Tooltip {
content: SharedString,
placement: TooltipPlacement,
delay_ms: u32,
}
impl Tooltip {
pub fn new(content: impl Into<SharedString>) -> Self {
Self {
content: content.into(),
placement: TooltipPlacement::default(),
delay_ms: 200,
}
}
pub fn placement(mut self, placement: TooltipPlacement) -> Self {
self.placement = placement;
self
}
pub fn delay(mut self, delay_ms: u32) -> Self {
self.delay_ms = delay_ms;
self
}
pub fn build_with_theme(self, theme: &Theme) -> Div {
let mut tooltip = div()
.absolute()
.px_2()
.py_1()
.bg(theme.background)
.border_1()
.border_color(theme.border)
.rounded(px(4.0))
.shadow_lg()
.text_xs()
.text_color(theme.text_primary)
.whitespace_nowrap();
match self.placement {
TooltipPlacement::Top => {
tooltip = tooltip.bottom_full().left_0().mb_1();
}
TooltipPlacement::Bottom => {
tooltip = tooltip.top_full().left_0().mt_1();
}
TooltipPlacement::Left => {
tooltip = tooltip.right_full().top_0().mr_1();
}
TooltipPlacement::Right => {
tooltip = tooltip.left_full().top_0().ml_1();
}
}
tooltip.child(self.content)
}
}
impl RenderOnce for Tooltip {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let theme = cx.theme();
self.build_with_theme(&theme)
}
}
impl IntoElement for Tooltip {
type Element = gpui::Component<Self>;
fn into_element(self) -> Self::Element {
gpui::Component::new(self)
}
}
pub struct WithTooltip {
child: AnyElement,
tooltip: SharedString,
placement: TooltipPlacement,
show_tooltip: bool,
}
impl WithTooltip {
pub fn new(child: impl IntoElement, tooltip: impl Into<SharedString>) -> Self {
Self {
child: child.into_any_element(),
tooltip: tooltip.into(),
placement: TooltipPlacement::default(),
show_tooltip: false,
}
}
pub fn placement(mut self, placement: TooltipPlacement) -> Self {
self.placement = placement;
self
}
pub fn show(mut self, show: bool) -> Self {
self.show_tooltip = show;
self
}
pub fn build_with_theme(self, theme: &Theme) -> Div {
let mut container = div().relative().child(self.child);
if self.show_tooltip {
container = container.child(
Tooltip::new(self.tooltip)
.placement(self.placement)
.build_with_theme(theme),
);
}
container
}
}
impl RenderOnce for WithTooltip {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let theme = cx.theme();
self.build_with_theme(&theme)
}
}
impl IntoElement for WithTooltip {
type Element = gpui::Component<Self>;
fn into_element(self) -> Self::Element {
gpui::Component::new(self)
}
}