use eframe::egui::{self, Align2, Color32, Stroke, Ui, Vec2};
use egui_map::map::Map;
use egui_map::map::objects::{
MapPoint, MarkerContext, NodeContext, NodeTemplate, NotificationContext, SelectionContext,
VisibilitySetting,
};
use std::rc::Rc;
use std::time::Instant;
struct CircleNodes;
impl NodeTemplate for CircleNodes {
fn node_ui(&self, ui: &mut Ui, ctx: NodeContext) {
let radius = 8.0 * ctx.zoom;
let painter = ui.painter();
painter.circle_filled(ctx.position, radius, ctx.color);
painter.text(
ctx.position + Vec2::new(0.0, -radius),
Align2::CENTER_BOTTOM,
ctx.point.get_name(),
egui::FontId::proportional(11.0 * ctx.zoom),
ui.visuals().text_color(),
);
}
fn selection_ui(&self, ui: &mut Ui, ctx: SelectionContext) {
ui.painter().circle_stroke(
ctx.position,
11.0 * ctx.zoom,
Stroke::new(2.0 * ctx.zoom, ctx.color),
);
}
fn notification_ui(&self, ui: &mut Ui, ctx: NotificationContext) -> bool {
let secs = ctx.initial_time.elapsed().as_secs_f32();
let alpha = (1.0 - secs / 2.0).clamp(0.0, 1.0);
let fading = Color32::from_rgba_unmultiplied(
ctx.color.r(),
ctx.color.g(),
ctx.color.b(),
(255.0 * alpha) as u8,
);
ui.painter().circle_stroke(
ctx.position,
(8.0 + 30.0 * secs) * ctx.zoom,
Stroke::new(3.0 * ctx.zoom, fading),
);
ui.ctx().request_repaint(); secs < 2.0 }
fn marker_ui(&self, ui: &mut Ui, ctx: MarkerContext) {
ui.painter().circle_stroke(
ctx.position,
14.0 * ctx.zoom,
Stroke::new(2.0 * ctx.zoom, Color32::LIGHT_GREEN),
);
}
}
fn main() -> eframe::Result<()> {
let mut points = Vec::new();
for (id, name, x, y) in [
(1, "Alpha", 0.0, 0.0),
(2, "Beta", 100.0, 50.0),
(3, "Gamma", 50.0, -80.0),
] {
let mut point = MapPoint::new(id, [x, y]);
point.set_name(name.to_string());
points.push(point);
}
let mut map = Map::new();
map.add_points(points);
map.set_node_template(Rc::new(CircleNodes));
map.settings.node_text_visibility = VisibilitySetting::Hover;
map.update_marker(0, 3);
let mut last_pulse = Instant::now() - std::time::Duration::from_secs(3);
eframe::run_ui_native(
"egui-map: custom template",
eframe::NativeOptions::default(),
move |ui, _frame| {
if last_pulse.elapsed().as_secs() >= 3 {
if let Some(node) = map.node(2) {
node.pulse(Instant::now());
}
last_pulse = Instant::now();
}
ui.add(&mut map);
},
)
}