egui_charts/chart/rendering/axes/
currency.rs1use crate::chart::rendering::axes::axis_font;
4use crate::theme::ThemeExt;
5use egui::{Align2, Pos2, Rect, Response, Sense, Stroke, Ui};
6
7pub fn render_axis_currency(
13 ui: &mut Ui,
14 axis: Rect,
15 currency: &str,
16 unit: Option<&str>,
17 choices: &[String],
18) -> (Response, Option<String>) {
19 let theme = ui.active_theme();
20 let header = match (currency.is_empty(), unit.filter(|unit| !unit.is_empty())) {
21 (false, Some(unit)) => format!("{currency} ยท {unit}"),
22 (true, Some(unit)) => unit.to_owned(),
23 _ => currency.to_owned(),
24 };
25 let font = axis_font(ui.ctx());
26 let galley = ui
27 .painter()
28 .layout_no_wrap(header.clone(), font.clone(), theme.chart.axis_text);
29 let width = galley.size().x + 16.0 + if currency.is_empty() { 0.0 } else { 10.0 };
30 let rect = Rect::from_min_max(
31 Pos2::new((axis.right() - width).max(axis.left()), axis.top()),
32 Pos2::new(axis.right(), (axis.top() + 24.0).min(axis.bottom())),
33 );
34 let response = ui.interact(
35 rect,
36 ui.scope_id().with(("axis_currency", axis.top().to_bits())),
37 Sense::click(),
38 );
39 response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, true, &header));
40 let painter = ui.painter().with_clip_rect(axis.intersect(ui.clip_rect()));
41 for offset in 0..18 {
42 let y = rect.bottom() + offset as f32;
43 painter.rect_filled(
44 Rect::from_min_max(Pos2::new(rect.left(), y), Pos2::new(rect.right(), y + 1.0)),
45 0.0,
46 theme.chart.bg.gamma_multiply(1.0 - offset as f32 / 18.0),
47 );
48 }
49 painter.rect_filled(rect, 0.0, theme.chart.bg);
50 painter.text(
51 Pos2::new(rect.left() + 8.0, rect.center().y),
52 Align2::LEFT_CENTER,
53 header,
54 font,
55 theme.chart.axis_text,
56 );
57 if !currency.is_empty() {
58 let x = rect.left() + 8.0 + galley.size().x + 4.0;
59 painter.add(egui::Shape::line(
60 vec![
61 Pos2::new(x, rect.center().y - 1.5),
62 Pos2::new(x + 3.0, rect.center().y + 1.5),
63 Pos2::new(x + 6.0, rect.center().y - 1.5),
64 ],
65 Stroke::new(1.0, theme.chart.axis_text),
66 ));
67 }
68 let mut chosen = None;
69 if !currency.is_empty() {
70 egui::Popup::menu(&response).show(|ui| {
71 let _ = ui.selectable_label(true, currency);
72 for choice in choices.iter().filter(|choice| choice.as_str() != currency) {
73 if ui.selectable_label(false, choice).clicked() {
74 chosen = Some(choice.clone());
75 ui.close();
76 }
77 }
78 });
79 }
80 (response, chosen)
81}