diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-12-27 00:52:04 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-12-27 01:13:52 +0000 |
| commit | 5f4427c127a862e886f88cbcd35854fd78b10ac5 (patch) | |
| tree | fc0c3fc9ef8dae310e9733201c27bb2d5bb8ab99 /src | |
| parent | dockerize (diff) | |
| download | nodetoy-5f4427c127a862e886f88cbcd35854fd78b10ac5.tar.gz nodetoy-5f4427c127a862e886f88cbcd35854fd78b10ac5.zip | |
auto-recompile
Diffstat (limited to 'src')
| -rw-r--r-- | src/library.rs | 21 | ||||
| -rw-r--r-- | src/main.rs | 116 |
2 files changed, 100 insertions, 37 deletions
diff --git a/src/library.rs b/src/library.rs index ba03dd6..111f365 100644 --- a/src/library.rs +++ b/src/library.rs @@ -478,7 +478,7 @@ impl<T: ScalarValue> Value for T { } trait ValueEditor: Value { - fn show_editor(&mut self, ui: &mut egui::Ui); + fn show_editor(&mut self, ui: &mut egui::Ui) -> egui::Response; } #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -536,9 +536,9 @@ where Constant<T>: ScalarValue<Raw = T>, T: fmt::Display, { - fn show_editor(&mut self, ui: &mut egui::Ui) { + fn show_editor(&mut self, ui: &mut egui::Ui) -> egui::Response { ui.label("value"); - ui.add(Self::make_widget(&mut self.0)); + ui.add(Self::make_widget(&mut self.0)) } } @@ -555,16 +555,19 @@ where Constant<T>: ScalarValue<Raw = T>, T: fmt::Display, { - fn show_editor(&mut self, ui: &mut egui::Ui) { + fn show_editor(&mut self, ui: &mut egui::Ui) -> egui::Response { const LABELS: [&str; 4] = ["x", "y", "z", "w"]; + let mut response = ui.response(); ui.vertical(|ui| { - for i in 0..self.0.len() { + for (val, label) in self.0.iter_mut().zip(LABELS) { ui.horizontal(|ui| { - ui.label(LABELS[i]); - ui.add(Constant::<T>::make_widget(&mut self.0[i])); + ui.label(label); + response |= ui.add(Constant::<T>::make_widget(val)); }); } }); + + response } } @@ -614,8 +617,8 @@ where writeln!(f, "{out_typ} {out_name} = {};", self) } - fn show_body(&mut self, ui: &mut egui::Ui) { - self.show_editor(ui); + fn show_body(&mut self, ui: &mut egui::Ui) -> egui::Response { + self.show_editor(ui) } } diff --git a/src/main.rs b/src/main.rs index 3213501..13096b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -138,7 +138,9 @@ trait ConcreteNode { f: &mut dyn fmt::Write, ) -> fmt::Result; - fn show_body(&mut self, _ui: &mut egui::Ui) {} + fn show_body(&mut self, ui: &mut egui::Ui) -> egui::Response { + ui.response() + } } impl TypeSignature { @@ -199,11 +201,11 @@ impl DemoNode { ) -> fmt::Result { let signature = self.get_node_signature(node, snarl); - let inputs: Vec<String> = (0..self.inputs()) + let inputs: Result<Vec<String>, fmt::Error> = (0..self.inputs()) .map( |input| match &*snarl.in_pin(InPinId { node, input }).remotes { - [] => "?".to_owned(), - [pin] => DemoNode::compile_output(*pin), + [] => Err(fmt::Error), + [pin] => Ok(DemoNode::compile_output(*pin)), _ => unreachable!("cannot connect to multiple inputs"), }, ) @@ -212,7 +214,7 @@ impl DemoNode { .map(|output| DemoNode::compile_output(OutPinId { node, output })) .collect(); - snarl[node].compile(signature, inputs, outputs, f) + snarl[node].compile(signature, inputs?, outputs, f) } pub fn get_node_signature(&self, node: NodeId, snarl: &Snarl<DemoNode>) -> TypeSignature { @@ -230,15 +232,17 @@ impl DemoNode { impl fmt::Display for DemoNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - DemoNode::Constant(x) => fmt::Display::fmt(x, f), - DemoNode::Input(x) => fmt::Display::fmt(x, f), - DemoNode::Builtin(x) => fmt::Display::fmt(x, f), - DemoNode::Output(x) => fmt::Display::fmt(x, f), + Self::Constant(x) => fmt::Display::fmt(x, f), + Self::Input(x) => fmt::Display::fmt(x, f), + Self::Builtin(x) => fmt::Display::fmt(x, f), + Self::Output(x) => fmt::Display::fmt(x, f), } } } -struct DemoViewer; +struct DemoViewer { + dirty: bool, +} impl DemoViewer { fn get_in_type(pin: InPinId, snarl: &Snarl<DemoNode>) -> Option<Type> { @@ -295,6 +299,20 @@ impl SnarlViewer<DemoNode> for DemoViewer { } snarl.connect(from.id, to.id); + self.dirty = true; + } + + fn disconnect(&mut self, from: &OutPin, to: &InPin, snarl: &mut Snarl<DemoNode>) { + snarl.disconnect(from.id, to.id); + self.dirty = true; + } + + fn drop_outputs(&mut self, pin: &OutPin, snarl: &mut Snarl<DemoNode>) { + snarl.drop_outputs(pin.id); + } + + fn drop_inputs(&mut self, pin: &InPin, snarl: &mut Snarl<DemoNode>) { + snarl.drop_inputs(pin.id); } fn title(&mut self, node: &DemoNode) -> String { @@ -349,7 +367,9 @@ impl SnarlViewer<DemoNode> for DemoViewer { ui: &mut Ui, snarl: &mut Snarl<DemoNode>, ) { - snarl[node].show_body(ui); + if snarl[node].show_body(ui).changed() { + self.dirty = true; + } } fn has_graph_menu(&mut self, _pos: egui::Pos2, _snarl: &mut Snarl<DemoNode>) -> bool { @@ -359,9 +379,34 @@ impl SnarlViewer<DemoNode> for DemoViewer { fn show_graph_menu(&mut self, pos: egui::Pos2, ui: &mut Ui, snarl: &mut Snarl<DemoNode>) { ui.label("Add node"); - for node in DemoNode::all() { + ui.menu_button("Constants", |ui| { + for node in library::AnyConstant::all() { + if ui.button(format!("{node}")).clicked() { + snarl.insert_node(pos, DemoNode::from(node)); + ui.close(); + } + } + }); + ui.menu_button("Inputs", |ui| { + for node in library::Input::all() { + if ui.button(format!("{node}")).clicked() { + snarl.insert_node(pos, DemoNode::from(node)); + ui.close(); + } + } + }); + ui.menu_button("Builtins", |ui| { + for node in library::BuiltinFunction::all() { + if ui.button(format!("{node}")).clicked() { + snarl.insert_node(pos, DemoNode::from(node)); + ui.close(); + } + } + }); + + for node in library::Output::all() { if ui.button(format!("{node}")).clicked() { - snarl.insert_node(pos, node); + snarl.insert_node(pos, DemoNode::from(node)); ui.close(); } } @@ -389,6 +434,7 @@ impl SnarlViewer<DemoNode> for DemoViewer { pub struct DemoApp { snarl: Snarl<DemoNode>, + viewer: DemoViewer, preview: preview::Custom3d, } @@ -438,6 +484,7 @@ impl DemoApp { DemoApp { snarl, + viewer: DemoViewer { dirty: true }, preview: preview::Custom3d::new(cx).expect("Failed to init preview"), } } @@ -467,29 +514,42 @@ impl App for DemoApp { }); }); + let mut shader: Option<String> = None; + egui::CentralPanel::default().show(ctx, |ui| { + let response = SnarlWidget::new() + .id(Id::new("snarl-demo")) + .style(default_style()) + .show(&mut self.snarl, &mut self.viewer, ui); + + let _ = response.changed(); + if self.viewer.dirty { + self.viewer.dirty = false; + let mut buf = String::new(); + match DemoViewer::compile(&self.snarl, &mut buf) { + Ok(()) => { + info!("{}", buf); + shader = Some(buf); + } + Err(x) => { + error!("Error compiling: {}", x); + } + } + } + }); + egui::SidePanel::right("preview").show(ctx, |ui| { egui::ScrollArea::vertical().show(ui, |ui| { egui::Frame::canvas(ui.style()).show(ui, |ui| { - let shader = if ui.button("compile").clicked() { - let mut buf = String::new(); - DemoViewer::compile(&self.snarl, &mut buf).expect("compilation"); - info!("{}", buf); - Some(buf) - } else { - None - }; + // let shader = if self.viewer.dirty { + // self.viewer.dirty = false; + // } else { + // None + // }; self.preview.custom_painting(ui, shader); }); }); }); - - egui::CentralPanel::default().show(ctx, |ui| { - SnarlWidget::new() - .id(Id::new("snarl-demo")) - .style(default_style()) - .show(&mut self.snarl, &mut DemoViewer, ui); - }); } fn save(&mut self, storage: &mut dyn eframe::Storage) { |
