mirror of https://codeberg.org/topola/topola.git
feat(topola-egui): Add zooming to fit
This commit is contained in:
parent
e9778fd653
commit
5f7f8fe14e
|
|
@ -54,6 +54,7 @@ impl App {
|
|||
Board::from_specctra(data.unwrap()),
|
||||
&self.translator,
|
||||
));
|
||||
self.viewport.scheduled_zoom_to_fit = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,18 +43,7 @@ impl Displayer {
|
|||
y: p[1] as f32,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
egui::Stroke::new(20.0 / viewport.scale_factor(), egui::Color32::WHITE),
|
||||
egui::Stroke::new(5.0 / viewport.scale_factor(), egui::Color32::WHITE),
|
||||
);
|
||||
ui.painter().line(
|
||||
vec![
|
||||
Pos2::new(0.0, 0.0),
|
||||
Pos2::new(100.0, 100.0),
|
||||
Pos2::new(100.0, 500.0),
|
||||
],
|
||||
egui::Stroke::new(2.0, egui::Color32::GOLD),
|
||||
);
|
||||
ui.painter()
|
||||
.circle_filled(egui::pos2(0.0, 0.0), 2.0, egui::Color32::RED);
|
||||
//workspace.board.layout().boundary()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,22 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use egui::Pos2;
|
||||
|
||||
use crate::{displayer::Displayer, workspace::Workspace};
|
||||
|
||||
pub struct Viewport {
|
||||
pub scene_rect: egui::Rect,
|
||||
pub ref_scene_rect: egui::Rect,
|
||||
pub scheduled_zoom_to_fit: bool,
|
||||
}
|
||||
|
||||
impl Viewport {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
scene_rect: egui::Rect::from_min_max(
|
||||
egui::pos2(-10000.0, -10000.0),
|
||||
egui::pos2(10000.0, 10000.0),
|
||||
),
|
||||
ref_scene_rect: egui::Rect::from_min_max(
|
||||
egui::pos2(-10000.0, -10000.0),
|
||||
egui::pos2(10000.0, 10000.0),
|
||||
),
|
||||
scene_rect: egui::Rect::from_min_max(egui::pos2(-1.0, -1.0), egui::pos2(1.0, 1.0)),
|
||||
ref_scene_rect: egui::Rect::from_min_max(egui::pos2(-1.0, -1.0), egui::pos2(1.0, 1.0)),
|
||||
scheduled_zoom_to_fit: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -30,16 +28,59 @@ impl Viewport {
|
|||
egui::Scene::new()
|
||||
.zoom_range(0.0001..=10000.0)
|
||||
.show(ui, &mut scene_rect, |ui| {
|
||||
if let Some(workspace) = workspace {
|
||||
if let Some(ref workspace) = workspace {
|
||||
let mut displayer = Displayer::new();
|
||||
displayer.update(ctx, ui, &self, workspace);
|
||||
}
|
||||
});
|
||||
|
||||
self.scene_rect = scene_rect;
|
||||
|
||||
if let Some(workspace) = workspace {
|
||||
self.zoom_to_fit_if_scheduled(workspace);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn zoom_to_fit_if_scheduled(&mut self, workspace: &Workspace) {
|
||||
if self.scheduled_zoom_to_fit {
|
||||
self.scene_rect = Self::boundary_bounding_box(workspace);
|
||||
self.ref_scene_rect = self.scene_rect.clone();
|
||||
}
|
||||
|
||||
self.scheduled_zoom_to_fit = false;
|
||||
}
|
||||
|
||||
fn boundary_bounding_box(workspace: &Workspace) -> egui::Rect {
|
||||
let first = workspace.board.layout().boundary()[0];
|
||||
|
||||
let mut min_x = first[0];
|
||||
let mut max_x = first[0];
|
||||
let mut min_y = first[1];
|
||||
let mut max_y = first[1];
|
||||
|
||||
for point in workspace.board.layout().boundary()[1..].iter() {
|
||||
if point[0] < min_x {
|
||||
min_x = point[0];
|
||||
}
|
||||
if point[0] > max_x {
|
||||
max_x = point[0];
|
||||
}
|
||||
if point[1] < min_y {
|
||||
min_y = point[1];
|
||||
}
|
||||
if point[1] > max_y {
|
||||
max_y = point[1];
|
||||
}
|
||||
}
|
||||
|
||||
egui::Rect::from_min_max(
|
||||
Pos2::new(min_x as f32, min_y as f32),
|
||||
Pos2::new(max_x as f32, max_y as f32),
|
||||
)
|
||||
.scale_from_center(1.05)
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f32 {
|
||||
self.ref_scene_rect.width() / self.scene_rect.width()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue