use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub struct Camera {
pub center: egui::Pos2,
pub zoom: f32,
}
impl Default for Camera {
fn default() -> Self {
Self {
center: egui::Pos2::ZERO,
zoom: 1.0,
}
}
}
impl Camera {
pub fn to_scene_rect(self, viewport: egui::Vec2) -> egui::Rect {
let zoom = if self.zoom > 0.0 { self.zoom } else { 1.0 };
egui::Rect::from_center_size(self.center, viewport / zoom)
}
pub fn from_scene_rect(rect: egui::Rect, viewport: egui::Vec2) -> Self {
let size = rect.size();
let zoom = if size.x > 0.0 && size.y > 0.0 {
(viewport / size).min_elem()
} else {
1.0
};
Self {
center: rect.center(),
zoom,
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct SceneView {
#[serde(default)]
pub camera: Camera,
#[serde(default, serialize_with = "serialize_sorted_layout")]
pub layout: egui_graph::Layout,
}
impl SceneView {
pub fn take_egui(&mut self, viewport: egui::Vec2) -> egui_graph::View {
egui_graph::View {
scene_rect: self.camera.to_scene_rect(viewport),
layout: std::mem::take(&mut self.layout),
}
}
pub fn restore_egui(&mut self, view: egui_graph::View, viewport: egui::Vec2) {
self.camera = Camera::from_scene_rect(view.scene_rect, viewport);
self.layout = view.layout;
}
}
fn serialize_sorted_layout<S: serde::Serializer>(
layout: &egui_graph::Layout,
s: S,
) -> Result<S::Ok, S::Error> {
let sorted: BTreeMap<_, _> = layout.iter().collect();
sorted.serialize(s)
}