use eframe::egui;
use crate::plot::kind::{evenly_spaced_isovalues, PlotKind, StyleCaps};
use crate::ui::domain_editor::{edit_domain, edit_resolution};
use crate::ui::expr_params::show_expression_params;
use crate::ui::style_editor::{
align_surface_colour_for_lic, edit_plot_style_basic, edit_plot_surface_settings,
};
use crate::App;
use crate::InspectorTab;
impl App {
pub(crate) fn bottom_inspector(&mut self, ui: &mut egui::Ui) {
let doc_idx = self.active_document_idx;
let selected_plot = self.documents[doc_idx].selected_plot;
ui.horizontal(|ui| {
if let Some(index) = selected_plot {
if let Some(plot) = self.documents[doc_idx].plots.get(index) {
let color = self.representative_plot_color(plot);
let (dot_rect, _) =
ui.allocate_exact_size(egui::vec2(12.0, 12.0), egui::Sense::hover());
ui.painter().circle_filled(dot_rect.center(), 5.0, color);
ui.label(egui::RichText::new(&plot.name).strong());
}
} else {
ui.label(egui::RichText::new("No plot selected").weak());
}
ui.separator();
ui.selectable_value(&mut self.inspector_tab, InspectorTab::Domain, "Domain");
ui.selectable_value(&mut self.inspector_tab, InspectorTab::Style, "Style");
ui.selectable_value(&mut self.inspector_tab, InspectorTab::Surface, "Surface");
});
ui.separator();
let Some(index) = selected_plot else {
ui.label("Select a plot to edit its domain, style, and surface settings.");
return;
};
{
let plot_count = self.documents[doc_idx].plots.len();
self.documents[doc_idx]
.sweep_config
.resize_with(plot_count, Default::default);
}
let slider_dragging = &mut self.slider_dragging;
let eq_editor = &mut self.eq_editor;
let inspector_tab = self.inspector_tab;
let doc = &mut self.documents[doc_idx];
let mut selected_dirty = false;
egui::ScrollArea::both()
.auto_shrink([false, false])
.show(ui, |ui| {
let plot = &mut doc.plots[index];
let sweep_map = &mut doc.sweep_config[index];
match inspector_tab {
InspectorTab::Domain => {
ui.horizontal_top(|ui| {
ui.vertical(|ui| {
selected_dirty |=
edit_domain(ui, &mut plot.domain, plot.kind.domain_labels());
ui.add_space(8.0);
let resolution_label = if plot.kind.uses_seed_resolution() {
"Seed Resolution"
} else {
"Resolution"
};
ui.label(resolution_label);
selected_dirty |= edit_resolution(
ui,
&mut plot.resolution,
plot.kind.uses_resolution(),
);
});
ui.separator();
ui.vertical(|ui| {
selected_dirty |= show_expression_params(
ui,
&mut plot.kind,
slider_dragging,
eq_editor,
sweep_map,
);
});
});
}
InspectorTab::Style => {
selected_dirty |=
edit_plot_style_basic(ui, &mut plot.style, plot.kind.style_caps());
if let PlotKind::ContouredSurface {
contour_values,
contour_style,
} = &mut plot.kind
{
ui.add_space(10.0);
ui.separator();
ui.label("Contours");
let mut contour_count = contour_values.len() as u32;
if ui
.add(
egui::Slider::new(&mut contour_count, 1..=20)
.text("Line Count"),
)
.changed()
{
*contour_values = evenly_spaced_isovalues(contour_count as usize);
selected_dirty = true;
}
selected_dirty |= edit_plot_style_basic(
ui,
contour_style,
StyleCaps {
mesh: false,
line: true,
point: false,
glyph: false,
},
);
}
}
InspectorTab::Surface => {
selected_dirty |=
edit_plot_surface_settings(ui, &mut plot.style, plot.kind.style_caps());
selected_dirty |= align_surface_colour_for_lic(&mut plot.style);
}
}
});
if selected_dirty {
doc.mark_dirty();
ui.add_space(6.0);
ui.colored_label(egui::Color32::YELLOW, "Pending scene rebuild");
}
}
pub(crate) fn show_export_modal(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
if !self.export_open {
return;
}
let mut open = self.export_open;
egui::Window::new("Export PNG")
.open(&mut open)
.collapsible(false)
.resizable(false)
.default_width(420.0)
.show(ctx, |ui| {
self.export_controls(ui, frame);
});
self.export_open = open;
}
fn export_controls(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
ui.text_edit_singleline(&mut self.documents[self.active_document_idx].export_path);
ui.horizontal(|ui| {
ui.add(
egui::DragValue::new(&mut self.documents[self.active_document_idx].export_width)
.speed(1)
.range(256..=8192)
.prefix("W "),
);
ui.add(
egui::DragValue::new(&mut self.documents[self.active_document_idx].export_height)
.speed(1)
.range(256..=8192)
.prefix("H "),
);
});
if ui.button("Export PNG").clicked() {
self.rebuild_scene(frame);
self.export_png(frame);
}
if !self.documents[self.active_document_idx]
.export_status
.is_empty()
{
ui.label(&self.documents[self.active_document_idx].export_status);
}
}
}