pub trait SegmentTemplate {
// Required methods
fn segment_ui(
&self,
painter: &Painter,
pos_a: Pos2,
pos_b: Pos2,
zoom: f32,
segment: &MapSegment,
);
fn segment_notification_ui(
&self,
painter: &Painter,
pos_a: Pos2,
pos_b: Pos2,
zoom: f32,
initial_time: Instant,
color: Color32,
) -> bool;
fn segment_state_ui(
&self,
painter: &Painter,
pos_a: Pos2,
pos_b: Pos2,
zoom: f32,
time: f32,
color: Color32,
);
}Expand description
Customizes how segments and their visual effects are rendered.
When a template is installed with
Map::set_segment_template, the widget
delegates all segment painting to it instead of using the built-in stroke
and animations.
Unlike NodeTemplate, these methods receive a bare &Painter
rather than &mut Ui. Segments are visited in bulk, every frame, after the
R-tree viewport culling in paint_map_lines; going through Ui would cost
a layout pass per segment, on top of what the culling already had to
discard. Use Painter::ctx to reach the egui::Context — for example
to call request_repaint().
The positions passed to these methods are in screen coordinates: already
scaled by zoom and translated to the viewport origin, same as
NodeTemplate’s. Multiply every size by zoom so your shapes scale
together with the map.
§Examples
A segment drawn as a dashed line, plus a notification that briefly thickens and brightens it:
use egui_map::map::objects::{MapSegment, SegmentTemplate};
use egui::{Color32, Painter, Pos2, Stroke};
use std::time::Instant;
struct DashedRoutes;
impl SegmentTemplate for DashedRoutes {
fn segment_ui(&self, painter: &Painter, a: Pos2, b: Pos2, zoom: f32, _segment: &MapSegment) {
// A crude dash: short strokes along the segment, spaced in screen
// pixels so they don't stretch as the map zooms.
let dir = b - a;
let len = dir.length();
let step = 10.0 * zoom;
let mut travelled = 0.0;
while travelled < len {
let start = a + dir * (travelled / len);
let end = a + dir * ((travelled + step * 0.6).min(len) / len);
painter.line_segment([start, end], Stroke::new(2.0 * zoom, Color32::GRAY));
travelled += step;
}
}
fn segment_notification_ui(
&self,
painter: &Painter,
a: Pos2,
b: Pos2,
zoom: f32,
initial_time: Instant,
color: Color32,
) -> bool {
let secs = Instant::now().duration_since(initial_time).as_secs_f32();
let alpha = (1.0 - secs).clamp(0.0, 1.0);
let fading =
Color32::from_rgba_unmultiplied(color.r(), color.g(), color.b(), (255.0 * alpha) as u8);
painter.line_segment([a, b], Stroke::new(5.0 * zoom, fading));
painter.ctx().request_repaint();
secs < 1.0
}
fn segment_state_ui(&self, painter: &Painter, a: Pos2, b: Pos2, zoom: f32, time: f32, color: Color32) {
let t = (time / 1.6).rem_euclid(1.0);
painter.circle_filled(a + (b - a) * t, 4.0 * zoom, color);
painter.ctx().request_repaint();
}
}Required Methods§
Sourcefn segment_ui(
&self,
painter: &Painter,
pos_a: Pos2,
pos_b: Pos2,
zoom: f32,
segment: &MapSegment,
)
fn segment_ui( &self, painter: &Painter, pos_a: Pos2, pos_b: Pos2, zoom: f32, segment: &MapSegment, )
Draws a segment, replacing the default stroked line.
Called every frame for each segment that survives the R-tree viewport
culling in paint_map_lines.
Sourcefn segment_notification_ui(
&self,
painter: &Painter,
pos_a: Pos2,
pos_b: Pos2,
zoom: f32,
initial_time: Instant,
color: Color32,
) -> bool
fn segment_notification_ui( &self, painter: &Painter, pos_a: Pos2, pos_b: Pos2, zoom: f32, initial_time: Instant, color: Color32, ) -> bool
Draws the notification effect of a segment notified through
Map::segment.
Called every frame for each segment carrying an event-driven effect
(see SegmentHandle). Should return true
while the animation is still playing — remember to call
Painter::ctx().request_repaint() — once it returns false the
notification is discarded.
Sourcefn segment_state_ui(
&self,
painter: &Painter,
pos_a: Pos2,
pos_b: Pos2,
zoom: f32,
time: f32,
color: Color32,
)
fn segment_state_ui( &self, painter: &Painter, pos_a: Pos2, pos_b: Pos2, zoom: f32, time: f32, color: Color32, )
Draws the lasting state effect of a segment (e.g. a travelling dot).
Called every frame for each segment with lasting state set through
Map::segment. time is the frame time in
seconds (ui.input(|i| i.time)), so every element animated this frame
shares one clock. For animated state, remember to call
Painter::ctx().request_repaint().
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".