Skip to main content

egui_components/
hover_card.rs

1//! `HoverCard` — a richer [`Tooltip`](crate::tooltip::Tooltip) that shows
2//! arbitrary content on hover.
3//!
4//! ```ignore
5//! let r = ui.add(sc::Link::new("@ada"));
6//! sc::HoverCard::new().max_width(260.0).show(&r, |ui| {
7//!     ui.horizontal(|ui| {
8//!         ui.add(sc::Avatar::from_name("Ada Lovelace").small());
9//!         ui.add(sc::Label::new("Ada Lovelace").strong());
10//!     });
11//!     ui.add(sc::Label::new("First programmer.").muted());
12//! });
13//! ```
14
15use egui::{Response, Ui};
16
17pub struct HoverCard {
18    max_width: f32,
19    at_pointer: bool,
20}
21
22impl Default for HoverCard {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28impl HoverCard {
29    pub fn new() -> Self {
30        Self {
31            max_width: 300.0,
32            at_pointer: false,
33        }
34    }
35    pub fn max_width(mut self, w: f32) -> Self {
36        self.max_width = w;
37        self
38    }
39    /// Anchor to the pointer instead of the widget.
40    pub fn at_pointer(mut self) -> Self {
41        self.at_pointer = true;
42        self
43    }
44
45    /// Show `content` while `response` is hovered. Returns the (possibly
46    /// updated) [`Response`].
47    pub fn show(self, response: &Response, content: impl FnOnce(&mut Ui)) -> Response {
48        let max_width = self.max_width;
49        let add = move |ui: &mut Ui| {
50            ui.set_max_width(max_width);
51            content(ui);
52        };
53        if self.at_pointer {
54            response.clone().on_hover_ui_at_pointer(add)
55        } else {
56            response.clone().on_hover_ui(add)
57        }
58    }
59}