1pub struct Tooltip {
2 pub text: crate::ui::text::Text,
3 pub font_size: f32,
4
5 pub bg_color: crate::color::Color,
6 pub text_color: crate::color::Color,
7 pub border_color: crate::color::Color,
8 pub border_size: usize,
9 pub radius: usize,
10 pub padding: usize,
11
12 pub offset_y: isize,
14}
15
16impl Tooltip {
17 pub fn new(text: &str, font: crate::ttf::Font, size: f32) -> Self {
18 Self {
19 text: crate::ui::text::Text::new(text, font),
20 font_size: size,
21 bg_color: crate::color::Color::new(20, 20, 30),
22 text_color: crate::color::Color::new(220, 220, 230),
23 border_color: crate::color::Color::new(70, 70, 90),
24 border_size: 1,
25 radius: 6,
26 padding: 6,
27 offset_y: -8,
28 }
29 }
30
31 pub fn bg_color(mut self, color: crate::color::Color) -> Self {
32 self.bg_color = color;
33 self
34 }
35
36 pub fn text_color(mut self, color: crate::color::Color) -> Self {
37 self.text_color = color;
38 self
39 }
40
41 pub fn border_color(mut self, color: crate::color::Color) -> Self {
42 self.border_color = color;
43 self
44 }
45
46 pub fn border(mut self, size: usize) -> Self {
47 self.border_size = size;
48 self
49 }
50
51 pub fn radius(mut self, radius: usize) -> Self {
52 self.radius = radius;
53 self
54 }
55
56 pub fn padding(mut self, padding: usize) -> Self {
57 self.padding = padding;
58 self
59 }
60
61 pub fn offset_y(mut self, offset: isize) -> Self {
62 self.offset_y = offset;
63 self
64 }
65
66 pub fn draw_if_hovered(
68 &self,
69 window: &mut crate::window::Window,
70 target_x: usize,
71 target_y: usize,
72 target_w: usize,
73 target_h: usize,
74 ) {
75 let mouse = window.get_mouse_state();
76 let mx = mouse.pos_x;
77 let my = mouse.pos_y;
78 let in_target = mx >= target_x as f32
79 && mx < (target_x + target_w) as f32
80 && my >= target_y as f32
81 && my < (target_y + target_h) as f32;
82
83 if !in_target {
84 return;
85 }
86
87 let text_w = self.text.get_width_precise(self.font_size);
88 let lm = self.text.font.font.horizontal_line_metrics(self.font_size).unwrap();
89 let text_h = (lm.ascent - lm.descent).ceil();
90
91 let tip_w = text_w.ceil() as usize + self.padding * 2;
92 let tip_h = text_h as usize + self.padding * 2;
93
94 let tip_x = (target_x + target_w / 2).saturating_sub(tip_w / 2);
96 let tip_y = if self.offset_y < 0 {
97 target_y.saturating_sub(tip_h).saturating_sub((-self.offset_y) as usize)
98 } else {
99 target_y + target_h + self.offset_y as usize
100 };
101
102 window.draw_rect_f(tip_x, tip_y, tip_w, tip_h, self.radius, &self.bg_color, 0);
104
105 for i in 0..self.border_size {
107 window.draw_rect(
108 tip_x + i, tip_y + i,
109 tip_w - i * 2, tip_h - i * 2,
110 self.radius.saturating_sub(i), &self.border_color,
111 );
112 }
113
114 window.draw_text(
116 tip_x + self.padding,
117 tip_y + self.padding,
118 &self.text, self.font_size, &self.text_color,
119 );
120 }
121}