Skip to main content

eulumdat_ui/
lib.rs

1//! Shared egui UI components for Eulumdat viewer/editor
2//!
3//! This crate provides reusable egui widgets for visualizing and editing
4//! EULUMDAT (LDT) and IES photometric data. It's designed to be used by:
5//! - Desktop applications (via eframe)
6//! - Web applications (via eframe WASM or embedded in Leptos)
7//!
8//! # Features
9//!
10//! - `3d` - Enable 3D viewer using three-d
11//! - `persistence` - Enable state persistence via serde
12//!
13//! # Example
14//!
15//! ```rust,ignore
16//! use eulumdat::Eulumdat;
17//! use eulumdat_ui::{EulumdatEditor, Theme};
18//!
19//! // In your egui app
20//! fn update(&mut self, ctx: &egui::Context) {
21//!     egui::CentralPanel::default().show(ctx, |ui| {
22//!         self.editor.show(ui, &mut self.ldt);
23//!     });
24//! }
25//! ```
26
27mod theme;
28mod widgets;
29
30#[cfg(feature = "3d")]
31mod viewer_3d;
32
33pub use theme::Theme;
34pub use widgets::{
35    CartesianWidget, DiagramTab, EditorPanel, HeatmapWidget, InfoPanel, PolarWidget,
36    ValidationPanel,
37};
38
39#[cfg(feature = "3d")]
40pub use viewer_3d::Viewer3D;
41
42/// Main editor component that combines all widgets
43pub struct EulumdatEditor {
44    /// Current active tab
45    pub active_tab: DiagramTab,
46    /// Theme settings
47    pub theme: Theme,
48    /// Show validation panel
49    pub show_validation: bool,
50}
51
52impl Default for EulumdatEditor {
53    fn default() -> Self {
54        Self {
55            active_tab: DiagramTab::Polar,
56            theme: Theme::default(),
57            show_validation: true,
58        }
59    }
60}
61
62impl EulumdatEditor {
63    pub fn new() -> Self {
64        Self::default()
65    }
66
67    /// Show the full editor UI
68    pub fn show(&mut self, ui: &mut egui::Ui, ldt: &mut Option<eulumdat::Eulumdat>) {
69        // Top toolbar
70        ui.horizontal(|ui| {
71            ui.selectable_value(&mut self.active_tab, DiagramTab::Info, "Info");
72            ui.selectable_value(&mut self.active_tab, DiagramTab::Polar, "Polar");
73            ui.selectable_value(&mut self.active_tab, DiagramTab::Cartesian, "Cartesian");
74            ui.selectable_value(&mut self.active_tab, DiagramTab::Heatmap, "Heatmap");
75            #[cfg(feature = "3d")]
76            ui.selectable_value(&mut self.active_tab, DiagramTab::Viewer3D, "3D");
77            ui.selectable_value(&mut self.active_tab, DiagramTab::Validation, "Validation");
78        });
79
80        ui.separator();
81
82        // Main content area
83        if let Some(ldt) = ldt {
84            match self.active_tab {
85                DiagramTab::Info => {
86                    InfoPanel::show(ui, ldt);
87                }
88                DiagramTab::Polar => {
89                    PolarWidget::show(ui, ldt, &self.theme);
90                }
91                DiagramTab::Cartesian => {
92                    CartesianWidget::show(ui, ldt, &self.theme);
93                }
94                DiagramTab::Heatmap => {
95                    HeatmapWidget::show(ui, ldt, &self.theme);
96                }
97                #[cfg(feature = "3d")]
98                DiagramTab::Viewer3D => {
99                    Viewer3D::show(ui, ldt, &self.theme);
100                }
101                DiagramTab::Validation => {
102                    ValidationPanel::show(ui, ldt);
103                }
104            }
105        } else {
106            ui.centered_and_justified(|ui| {
107                ui.label("No file loaded. Drag & drop an LDT or IES file, or use File > Open.");
108            });
109        }
110    }
111}