diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index 700e82d..0f6a9a8 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -202,7 +202,7 @@ impl eframe::App for App { ctx, &self.translator, &self.viewport, - viewport_rect, + &viewport_rect, &self.maybe_execute, ); diff --git a/src/bin/topola-egui/bottom.rs b/src/bin/topola-egui/bottom.rs index 9a1e705..0b3dd34 100644 --- a/src/bin/topola-egui/bottom.rs +++ b/src/bin/topola-egui/bottom.rs @@ -14,14 +14,13 @@ impl Bottom { ctx: &egui::Context, tr: &Translator, viewport: &Viewport, - viewport_rect: egui::Rect, + viewport_rect: &egui::Rect, maybe_execute: &Option, ) { egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { - let transform = egui::emath::RectTransform::from_to(viewport.from_rect, viewport_rect); - let latest_pos = transform - .inverse() - .transform_pos(ctx.input(|i| i.pointer.latest_pos().unwrap_or_default())); + let latest_pos = viewport.transform.inverse() + * ctx.input(|i| i.pointer.latest_pos().unwrap_or_default()) + - viewport_rect.size() / 2.0; let mut message = String::from(""); diff --git a/src/bin/topola-egui/painter.rs b/src/bin/topola-egui/painter.rs index fa400b6..2a13563 100644 --- a/src/bin/topola-egui/painter.rs +++ b/src/bin/topola-egui/painter.rs @@ -6,14 +6,14 @@ use topola::{ pub struct Painter<'a> { ui: &'a mut egui::Ui, - transform: egui::emath::RectTransform, + transform: egui::emath::TSTransform, paint_bboxes: bool, } impl<'a> Painter<'a> { pub fn new( ui: &'a mut egui::Ui, - transform: egui::emath::RectTransform, + transform: egui::emath::TSTransform, paint_bboxes: bool, ) -> Self { Self { @@ -29,11 +29,11 @@ impl<'a> Painter<'a> { PrimitiveShape::Seg(seg) => egui::Shape::line_segment( [ self.transform - .transform_pos([seg.from.x() as f32, -seg.from.y() as f32].into()), + .mul_pos([seg.from.x() as f32, -seg.from.y() as f32].into()), self.transform - .transform_pos([seg.to.x() as f32, -seg.to.y() as f32].into()), + .mul_pos([seg.to.x() as f32, -seg.to.y() as f32].into()), ], - egui::Stroke::new(seg.width as f32 * self.transform.scale().x, color), + egui::Stroke::new(seg.width as f32 * self.transform.scaling, color), ), PrimitiveShape::Bend(bend) => { let circle = bend.circle(); @@ -46,12 +46,12 @@ impl<'a> Painter<'a> { for i in 0..=100 { let x = circle.pos.x() + circle.r * (angle_from + i as f64 * angle_step).cos(); let y = circle.pos.y() + circle.r * (angle_from + i as f64 * angle_step).sin(); - points.push(self.transform.transform_pos([x as f32, -y as f32].into())); + points.push(self.transform.mul_pos([x as f32, -y as f32].into())); } egui::Shape::line( points, - egui::Stroke::new(bend.width as f32 * self.transform.scale().x, color), + egui::Stroke::new(bend.width as f32 * self.transform.scaling, color), ) } }; @@ -65,7 +65,7 @@ impl<'a> Painter<'a> { max: [bbox.upper()[0] as f32, -bbox.lower()[1] as f32].into(), }; self.ui.painter().add(egui::Shape::rect_stroke( - self.transform.transform_rect(rect), + self.transform.mul_rect(rect), egui::Rounding::ZERO, egui::Stroke::new(1.0, egui::Color32::GRAY), )); @@ -80,8 +80,8 @@ impl<'a> Painter<'a> { fn dot_shape(&mut self, circle: Circle, color: egui::epaint::Color32) -> egui::Shape { egui::Shape::circle_filled( self.transform - .transform_pos([circle.pos.x() as f32, -circle.pos.y() as f32].into()), - circle.r as f32 * self.transform.scale().x, + .mul_pos([circle.pos.x() as f32, -circle.pos.y() as f32].into()), + circle.r as f32 * self.transform.scaling, color, ) } @@ -92,7 +92,7 @@ impl<'a> Painter<'a> { .exterior_coords_iter() .map(|coords| { self.transform - .transform_pos([coords.x as f32, -coords.y as f32].into()) + .mul_pos([coords.x as f32, -coords.y as f32].into()) }) .collect(), color, @@ -104,9 +104,9 @@ impl<'a> Painter<'a> { self.ui.painter().add(egui::Shape::line_segment( [ self.transform - .transform_pos([from.x() as f32, -from.y() as f32].into()), + .mul_pos([from.x() as f32, -from.y() as f32].into()), self.transform - .transform_pos([to.x() as f32, -to.y() as f32].into()), + .mul_pos([to.x() as f32, -to.y() as f32].into()), ], stroke, )); diff --git a/src/bin/topola-egui/viewport.rs b/src/bin/topola-egui/viewport.rs index 2966751..e1b9b5c 100644 --- a/src/bin/topola-egui/viewport.rs +++ b/src/bin/topola-egui/viewport.rs @@ -22,13 +22,14 @@ use topola::{ use crate::{app::execute, layers::Layers, overlay::Overlay, painter::Painter, top::Top}; pub struct Viewport { - pub from_rect: egui::emath::Rect, + pub transform: egui::emath::TSTransform, } impl Viewport { pub fn new() -> Self { Self { - from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0), + //from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0), + transform: egui::emath::TSTransform::new([0.0, 0.0].into(), 0.01), } } @@ -45,32 +46,16 @@ impl Viewport { egui::Frame::canvas(ui.style()).show(ui, |ui| { ui.ctx().request_repaint(); - let desired_size = ui.available_width() * egui::vec2(1.0, 0.5); - let (_id, viewport_rect) = ui.allocate_space(desired_size); + let (_id, viewport_rect) = ui.allocate_space(ui.available_size()); + let latest_pos = self.transform.inverse() * (ctx.input(|i| i.pointer.latest_pos().unwrap_or_default())); - let old_transform = - egui::emath::RectTransform::from_to(self.from_rect, viewport_rect); - let latest_pos = old_transform - .inverse() - .transform_pos(ctx.input(|i| i.pointer.latest_pos().unwrap_or_default())); + let old_scaling = self.transform.scaling; + self.transform.scaling *= ctx.input(|i| i.zoom_delta()); - let old_scale = old_transform.scale().x; - self.from_rect = self.from_rect / ctx.input(|i| i.zoom_delta()); + self.transform.translation += latest_pos.to_vec2() * (old_scaling - self.transform.scaling); + self.transform.translation += ctx.input(|i| i.smooth_scroll_delta); - let new_scale = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect) - .scale() - .x; - - self.from_rect = self.from_rect.translate( - ctx.input(|i| latest_pos.to_vec2() * (new_scale - old_scale) / new_scale), - ); - - self.from_rect = self - .from_rect - .translate(ctx.input(|i| -i.raw_scroll_delta / new_scale)); - - let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect); - let mut painter = Painter::new(ui, transform, top.show_bboxes); + let mut painter = Painter::new(ui, self.transform, top.show_bboxes); if let Some(ref mut invoker) = maybe_invoker { if ctx.input(|i| i.pointer.any_click()) { diff --git a/src/router/router.rs b/src/router/router.rs index f8fef1e..c232f76 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -1,5 +1,3 @@ -use std::convert::Infallible; - use geo::EuclideanDistance; use petgraph::{data::DataMap, visit::EdgeRef}; use serde::{Deserialize, Serialize}; @@ -16,7 +14,7 @@ use crate::{ Collision, DrawingException, Infringement, }, geometry::{ - primitive::{AccessPrimitiveShape, PrimitiveShape}, + primitive::PrimitiveShape, shape::{AccessShape, MeasureLength}, }, graph::{GetPetgraphIndex, MakeRef},