diff --git a/crates/data/src/shared/event.rs b/crates/data/src/shared/event.rs index dc4fb030..b8de59c0 100644 --- a/crates/data/src/shared/event.rs +++ b/crates/data/src/shared/event.rs @@ -133,7 +133,7 @@ impl RawEventPage { } let desc = command_db.get(command.code); - let mut child = parent.append_value(command, commands); + let current = parent.append_value(command, commands); if let Some(desc) = desc { match &desc.kind { CommandKind::Branch { @@ -141,22 +141,30 @@ impl RawEventPage { branches, terminator, command_contains_branch, - } => loop { - let next = iter.next().unwrap(); - - if next.code == terminator.code { - break; + } => { + let mut branch = None; + if *command_contains_branch { + branch = Some(current.append_value(EventPage::ROOT_NODE, commands)) } + loop { + let next = iter.next().unwrap(); - if branches.iter().any(|branch| branch.code == next.code) { - child = parent.append_value(next, commands); - continue; - } + if next.code == terminator.code { + break; + } + + if branches.iter().any(|branch| branch.code == next.code) { + branch = Some(current.append_value(next, commands)); + continue; + } - Self::parse_command_under(child, next, commands, iter, command_db); - }, + if let Some(branch) = branch { + Self::parse_command_under(branch, next, commands, iter, command_db); + } + } + } CommandKind::Multi(cont) => { - let command = commands[child].get_mut(); + let command = commands[current].get_mut(); let text = command.parameters[0].as_string_mut().unwrap(); while let Some(next) = iter.next_if(|next| next.code == *cont) { let next_line = next.parameters[0].as_string().unwrap(); diff --git a/crates/ui/src/components/command_view/mod.rs b/crates/ui/src/components/command_view/mod.rs index 791cf517..daaae63c 100644 --- a/crates/ui/src/components/command_view/mod.rs +++ b/crates/ui/src/components/command_view/mod.rs @@ -22,7 +22,7 @@ // terms of the Steamworks API by Valve Corporation, the licensors of this // Program grant you additional permission to convey the resulting work. -use luminol_data::rpg; +use luminol_data::{commands::CommandKind, rpg}; pub struct CommandView {} @@ -37,11 +37,100 @@ impl CommandView { CommandView {} } - pub fn ui(&mut self, ui: &mut egui::Ui, commands: &mut [rpg::EventCommand]) { - egui::ScrollArea::both().show(ui, |ui| { - for command in commands { - ui.label(format!("{:#?}", command)); + fn display_insert(&mut self, ui: &mut egui::Ui) { + ui.label(">"); + } + + fn ui_for_command( + &mut self, + ui: &mut egui::Ui, + command_db: &luminol_data::CommandDB, + commands: &indextree::Arena, + node_id: indextree::NodeId, + ) { + let command = commands[node_id].get(); + match command_db.get(command.code) { + Some(desc) => match &desc.kind { + CommandKind::Branch { + parameters, + branches, + terminator, + command_contains_branch, + } => { + let id = egui::Id::new("event_edit_branch").with(node_id); + let header = egui::collapsing_header::CollapsingState::load_with_default_open( + ui.ctx(), + id, + true, + ); + let mut children = node_id.children(commands); + header + .show_header(ui, |ui| { + ui.label(egui::RichText::new(&desc.name).color(desc.color)); + }) + .body(|ui| { + if *command_contains_branch { + let branch = children.next().unwrap(); + for child in branch.children(commands) { + self.ui_for_command(ui, command_db, commands, child); + } + self.display_insert(ui); + } + }); + for branch in children { + let code = commands[branch].get().code; + let branch_desc = branches.iter().find(|b| b.code == code).unwrap(); + let id = egui::Id::new("event_edit_branch").with(branch); + let header = + egui::collapsing_header::CollapsingState::load_with_default_open( + ui.ctx(), + id, + true, + ); + header + .show_header(ui, |ui| { + ui.label(egui::RichText::new(&branch_desc.name).color(desc.color)); + }) + .body(|ui| { + for child in branch.children(commands) { + self.ui_for_command(ui, command_db, commands, child); + } + self.display_insert(ui); + }); + } + } + CommandKind::Multi(_) => { + ui.label(egui::RichText::new(&desc.name).color(desc.color)); + let text = command.parameters[0].as_string().unwrap(); + ui.label(text); + } + CommandKind::Regular { parameters } => todo!(), + CommandKind::MoveRoute(_) => todo!(), + CommandKind::Blank => todo!(), + }, + None => { + let text = egui::RichText::new(format!("🔥 Unrecognized command {}", command.code)) + .color(egui::Color32::RED); + ui.label(text); } - }); + } + } + + // maybe take a Ctx parameter instead? + pub fn ui( + &mut self, + ui: &mut egui::Ui, + command_db: &luminol_data::CommandDB, + commands: &mut indextree::Arena, + root_node: indextree::NodeId, + ) { + egui::ScrollArea::both() + .auto_shrink([false, true]) + .show(ui, |ui| { + for child in root_node.children(commands) { + self.ui_for_command(ui, command_db, commands, child); + } + self.display_insert(ui); + }); } } diff --git a/crates/ui/src/windows/event_edit.rs b/crates/ui/src/windows/event_edit.rs index 2d50bb09..5032890e 100644 --- a/crates/ui/src/windows/event_edit.rs +++ b/crates/ui/src/windows/event_edit.rs @@ -286,6 +286,15 @@ impl luminol_core::Window for Window { egui::CentralPanel::default().show_inside(ui, |ui| { ui.label("Commands"); + + let project_config = update_state.project_config.as_ref().unwrap(); + let mut view = crate::components::CommandView::new(); + view.ui( + ui, + &project_config.command_db, + &mut page.commands, + page.root, + ); }); });