Newer
Older
use crate::egui::{Align2, Pos2, Stroke, Ui};
use eframe::egui::{Color32, FontFamily, FontId, Shape};
pub stroke: Color32,
pub stroke_width: f32,
pub label: String,
pub font_size: f32,
}
impl Default for Arrow {
fn default() -> Self {
Self {
origin: Pos2::ZERO,
tip: Pos2::new(1.0, 1.0),
stroke: Color32::BLACK,
stroke_width: 6.0,
label: String::new(),
font_size: 40.0,
}
}
}
impl Arrow {
pub fn show(&self, ui: &mut Ui) {
// Based on: https://docs.rs/egui/latest/src/egui/widgets/plot/items/mod.rs.html#977-985
let vector = self.tip - self.origin;
let rot = Rot2::from_angle(std::f32::consts::TAU / 10.0);
let stroke = Stroke::new(self.stroke_width, self.stroke);
.add(Shape::line_segment([self.origin, self.tip], stroke));
ui.painter().add(Shape::line(
vec![
tip - tip_length * (rot.inverse() * dir),
tip,
tip - tip_length * (rot * dir),
],
if !self.label.is_empty() {
let align = match (vector.x.total_cmp(&0.0), vector.y.total_cmp(&0.0)) {
(Ordering::Less, Ordering::Less) => Align2::LEFT_TOP,
(Ordering::Less, Ordering::Equal) => Align2::LEFT_CENTER,
(Ordering::Less, Ordering::Greater) => Align2::LEFT_BOTTOM,
(Ordering::Equal, Ordering::Less) => Align2::CENTER_TOP,
(Ordering::Equal, Ordering::Equal) => Align2::CENTER_CENTER,
(Ordering::Equal, Ordering::Greater) => Align2::CENTER_BOTTOM,
(Ordering::Greater, Ordering::Less) => Align2::RIGHT_TOP,
(Ordering::Greater, Ordering::Equal) => Align2::RIGHT_CENTER,
(Ordering::Greater, Ordering::Greater) => Align2::RIGHT_BOTTOM,
};
ui.painter().text(
self.origin,
align,
self.label.as_str(),
FontId::new(self.font_size, FontFamily::Proportional),
self.stroke,
);
}