use egui::{Response, Ui};
use egui_wgpu::RenderState;
use crate::core::scene3d::interaction::window_to_ndc;
use crate::render::gpu_scene3d::Scene3dId;
use crate::widget::scalar_field_properties::ScalarFieldProperties;
use crate::widget::scalar_field_view::ScalarFieldView;
use crate::widget::scene_position_info::ScenePositionInfo;
use crate::widget::scene_widget::viewpoint_menu;
const PROPERTIES_WIDTH: f32 = 200.0;
pub struct SceneWindow {
view: ScalarFieldView,
properties: ScalarFieldProperties,
show_properties: bool,
position_info: ScenePositionInfo,
}
impl SceneWindow {
pub fn new(render_state: &RenderState, id: Scene3dId) -> Self {
Self {
view: ScalarFieldView::new(render_state, id),
properties: ScalarFieldProperties::new(),
show_properties: true,
position_info: ScenePositionInfo::new(),
}
}
pub fn view(&self) -> &ScalarFieldView {
&self.view
}
pub fn view_mut(&mut self) -> &mut ScalarFieldView {
&mut self.view
}
pub fn properties_mut(&mut self) -> &mut ScalarFieldProperties {
&mut self.properties
}
pub fn position_info(&self) -> &ScenePositionInfo {
&self.position_info
}
pub fn properties_visible(&self) -> bool {
self.show_properties
}
pub fn set_properties_visible(&mut self, visible: bool) {
self.show_properties = visible;
}
pub fn show(&mut self, ui: &mut Ui, render_state: &RenderState) -> Response {
egui::Panel::top(ui.id().with("scene_window_toolbar")).show_inside(ui, |ui| {
ui.horizontal(|ui| {
viewpoint_menu(ui, self.view.scene_mut());
ui.checkbox(&mut self.show_properties, "Properties");
});
});
if self.show_properties {
egui::Panel::left(ui.id().with("scene_window_properties"))
.default_size(PROPERTIES_WIDTH)
.show_inside(ui, |ui| {
self.properties.ui(ui, &mut self.view, render_state);
});
}
egui::Panel::bottom(ui.id().with("scene_window_position_info")).show_inside(ui, |ui| {
self.position_info.ui(ui);
});
let response = egui::CentralPanel::default()
.show_inside(ui, |ui| self.view.show(ui))
.inner;
if let Some(pos) = response.hover_pos() {
let rect = response.rect;
let ppp = ui.ctx().pixels_per_point();
let local = ((pos.x - rect.min.x) * ppp, (pos.y - rect.min.y) * ppp);
let size_px = (
(rect.width() * ppp).max(1.0),
(rect.height() * ppp).max(1.0),
);
let ndc = window_to_ndc(local, size_px);
self.position_info.set(self.view.pick(ndc));
} else {
self.position_info.clear();
}
response
}
}