Expand description
Interactive map widget and the data types it renders.
Map is an egui::Widget that draws a 2D set of nodes
(objects::MapPoint), the connection lines between them
(objects::MapSegment) and free-floating text labels
(objects::MapLabel). Nodes are indexed in a kd-tree so that only the
ones inside the current viewport are painted each frame.
§Coordinate model
The widget works with two coordinate spaces:
- Map coordinates: the logical position of your nodes, as loaded through
Map::add_hashmap_points. - Screen coordinates: positions inside the widget’s rectangle on screen.
Both are related by the current zoom factor and viewport origin:
screen = map * zoom - origin. Use Map::set_zoom, Map::set_pos and
Map::set_pos_from_nodeid to control the visible region.
§Connecting nodes with lines
Lines are wired up in three steps:
- Create the nodes as a
HashMapkeyed by node id. - For every connection, choose a unique
(usize, usize)id – typically the pair of node ids it joins – and push it intoMapPoint::connectionsof both endpoint nodes. - Load the nodes with
Map::add_hashmap_points, then load aHashMapofMapSegmentkeyed by those same connection ids and add it to the widget withMap::add_hashmap_lines.
use egui_map::map::Map;
use egui_map::map::objects::{MapPoint, MapSegment};
use std::collections::HashMap;
// 1. Create the nodes.
let mut points: HashMap<usize, MapPoint> = HashMap::new();
points.insert(1, MapPoint::new(1, [0.0, 0.0]));
points.insert(2, MapPoint::new(2, [10.0, 10.0]));
// 2. Register the connection id on both endpoints.
for id in [1, 2] {
points.get_mut(&id).unwrap().connections.push((1, 2));
}
let mut map = Map::new();
map.add_hashmap_points(points);
// 3. Provide the line geometry keyed by the same connection id.
let mut lines: HashMap<(usize, usize), MapSegment> = HashMap::new();
lines.insert((1, 2), MapSegment::new((1, 2), [0.0, 0.0], [10.0, 10.0]));
map.add_hashmap_lines(lines);A line is only drawn while the zoom level is above
MapSettings::line_visible_zoom and its bounding box intersects the
viewport. Segments are culled broad-phase with an R-tree built by
Map::add_lines, so long lines crossing the view are drawn even when
both endpoints lie outside of it.
§Custom node rendering
Install a NodeTemplate implementation with Map::set_node_template
to take over the rendering of nodes, selection highlights, notification
animations and markers. Note that this replaces
all built-in node rendering, including the node name labels: draw them
yourself in NodeTemplate::node_ui if you need them.
§Animating nodes and segments
Map::node and Map::segment borrow a node or a segment already
loaded into the widget and return a handle – NodeHandle /
SegmentHandle – with one method per built-in effect. Effects come in
two families: event-driven ones (pulse, flash, …) play once from an
Instant and stop on their own; lasting ones (halo, comet, …) run
until NodeHandle::clear / SegmentHandle::clear and keep the app
repainting the whole time they’re active.
use egui_map::map::Map;
use egui_map::map::objects::{MapPoint, MapSegment};
use std::time::Instant;
let mut map = Map::new();
map.add_points(vec![MapPoint::new(1, [0.0, 0.0])]);
map.add_lines(vec![MapSegment::new((1, 1), [0.0, 0.0], [10.0, 0.0])]);
if let Some(node) = map.node(1) {
node.pulse(Instant::now());
}
if let Some(segment) = map.segment((1, 1)) {
segment.comet();
}To fully replace how an effect looks, install a objects::NodeTemplate /
objects::SegmentTemplate and implement its notification_ui /
segment_notification_ui and marker_ui / segment_state_ui hooks – or
call animation::Animation’s functions directly from either template if
you only want to reuse the built-in look.
Modules§
- animation
- Built-in animation effects for nodes and segments.
- objects
- Data types consumed by the
Mapwidget. - theme
- Color palettes and visual styling for the
Mapwidget.
Structs§
- Map
- An interactive 2D map widget.
- Node
Handle - A borrowed node, obtained from
Map::node, that an animation can be attached to. - Segment
Handle - A borrowed segment, obtained from
Map::segment, that an animation can be attached to.