From 471b014c55908fe9de0a362142e265f005428aa3 Mon Sep 17 00:00:00 2001 From: Melody Madeline Lyons Date: Sun, 30 Jun 2024 10:14:30 -0700 Subject: [PATCH] Very destructive commit Not very happy with this because it clones things, which is a waste of memory --- crates/components/src/database_view.rs | 6 +- crates/data/src/rmxp/actor.rs | 2 +- crates/data/src/rmxp/armor.rs | 2 +- crates/data/src/rmxp/class.rs | 4 +- crates/data/src/rmxp/enemy.rs | 4 +- crates/data/src/rmxp/skill.rs | 2 +- crates/data/src/rmxp/state.rs | 2 +- crates/data/src/rmxp/weapon.rs | 2 +- crates/modals/src/sound_picker.rs | 50 ++-- crates/ui/src/windows/actors.rs | 112 +++++---- crates/ui/src/windows/armor.rs | 84 +++---- crates/ui/src/windows/classes.rs | 147 ++++++----- crates/ui/src/windows/enemies.rs | 322 ++++++++++++------------- crates/ui/src/windows/items.rs | 137 +++++------ crates/ui/src/windows/skills.rs | 106 ++++---- crates/ui/src/windows/states.rs | 97 ++++---- crates/ui/src/windows/weapons.rs | 87 ++++--- src/app/top_bar.rs | 16 +- 18 files changed, 568 insertions(+), 614 deletions(-) diff --git a/crates/components/src/database_view.rs b/crates/components/src/database_view.rs index 6ebad57c..c3832dc3 100644 --- a/crates/components/src/database_view.rs +++ b/crates/components/src/database_view.rs @@ -48,11 +48,11 @@ impl DatabaseView { pub fn show( &mut self, ui: &mut egui::Ui, - update_state: &luminol_core::UpdateState<'_>, + update_state: &mut luminol_core::UpdateState<'_>, label: impl Into, vec: &mut Vec, formatter: impl Fn(&T) -> String, - inner: impl FnOnce(&mut egui::Ui, &mut Vec, usize) -> R, + inner: impl FnOnce(&mut egui::Ui, &mut Vec, usize, &mut luminol_core::UpdateState<'_>) -> R, ) -> egui::InnerResponse> where T: luminol_data::rpg::DatabaseEntry, @@ -262,7 +262,7 @@ impl DatabaseView { DatabaseViewResponse { inner: (self.selected_id < vec.len()) - .then(|| inner(ui, vec, self.selected_id)), + .then(|| inner(ui, vec, self.selected_id, update_state)), modified, } }) diff --git a/crates/data/src/rmxp/actor.rs b/crates/data/src/rmxp/actor.rs index 256507a5..14dcd809 100644 --- a/crates/data/src/rmxp/actor.rs +++ b/crates/data/src/rmxp/actor.rs @@ -19,7 +19,7 @@ use crate::{ optional_path_serde, Path, Table2, }; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Actor")] pub struct Actor { diff --git a/crates/data/src/rmxp/armor.rs b/crates/data/src/rmxp/armor.rs index 35413abf..0fd745ce 100644 --- a/crates/data/src/rmxp/armor.rs +++ b/crates/data/src/rmxp/armor.rs @@ -19,7 +19,7 @@ use crate::{ optional_path_alox, optional_path_serde, Path, }; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Armor")] pub struct Armor { diff --git a/crates/data/src/rmxp/class.rs b/crates/data/src/rmxp/class.rs index 667d3859..4ae00d87 100644 --- a/crates/data/src/rmxp/class.rs +++ b/crates/data/src/rmxp/class.rs @@ -16,7 +16,7 @@ // along with Luminol. If not, see . pub use crate::{id_alox, id_serde, id_vec_alox, id_vec_serde, Table1}; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Class")] pub struct Class { @@ -36,7 +36,7 @@ pub struct Class { pub learnings: Vec, } -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Class::Learning")] pub struct Learning { diff --git a/crates/data/src/rmxp/enemy.rs b/crates/data/src/rmxp/enemy.rs index 363cda58..e19269e8 100644 --- a/crates/data/src/rmxp/enemy.rs +++ b/crates/data/src/rmxp/enemy.rs @@ -19,7 +19,7 @@ pub use crate::{ optional_path_serde, Path, Table1, }; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Enemy")] pub struct Enemy { @@ -65,7 +65,7 @@ pub struct Enemy { pub treasure_prob: i32, } -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Enemy::Action")] pub struct Action { diff --git a/crates/data/src/rmxp/skill.rs b/crates/data/src/rmxp/skill.rs index 820e7efd..32daf3aa 100644 --- a/crates/data/src/rmxp/skill.rs +++ b/crates/data/src/rmxp/skill.rs @@ -19,7 +19,7 @@ pub use crate::{ optional_path_alox, optional_path_serde, rpg::AudioFile, Path, }; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Skill")] pub struct Skill { diff --git a/crates/data/src/rmxp/state.rs b/crates/data/src/rmxp/state.rs index ffc4f442..d017ae41 100644 --- a/crates/data/src/rmxp/state.rs +++ b/crates/data/src/rmxp/state.rs @@ -16,7 +16,7 @@ // along with Luminol. If not, see . use crate::{id_alox, id_serde, id_vec_alox, id_vec_serde, optional_id_alox, optional_id_serde}; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::State")] pub struct State { diff --git a/crates/data/src/rmxp/weapon.rs b/crates/data/src/rmxp/weapon.rs index 52774f96..c2dffd31 100644 --- a/crates/data/src/rmxp/weapon.rs +++ b/crates/data/src/rmxp/weapon.rs @@ -19,7 +19,7 @@ pub use crate::{ optional_path_alox, optional_path_serde, rpg::AudioFile, Path, }; -#[derive(Default, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(alox_48::Deserialize, alox_48::Serialize)] #[marshal(class = "RPG::Weapon")] pub struct Weapon { diff --git a/crates/modals/src/sound_picker.rs b/crates/modals/src/sound_picker.rs index 57054d20..217cd108 100644 --- a/crates/modals/src/sound_picker.rs +++ b/crates/modals/src/sound_picker.rs @@ -24,18 +24,23 @@ use luminol_core::prelude::*; pub struct Modal { - tab: luminol_components::SoundTab, - open: bool, + state: State, + id_source: egui::Id, + source: Source, +} + +enum State { + Closed, + Open { tab: luminol_components::SoundTab }, } impl Modal { - pub fn new( - filesystem: &impl FileSystem, - source: Source, - selected_track: luminol_data::rpg::AudioFile, - ) -> Self { - let tab = luminol_components::SoundTab::new(filesystem, source, selected_track); - Self { tab, open: false } + pub fn new(source: Source, id_source: impl Into) -> Self { + Self { + state: State::Closed, + id_source: id_source.into(), + source, + } } } @@ -48,8 +53,8 @@ impl luminol_core::Modal for Modal { update_state: &'m mut luminol_core::UpdateState<'_>, ) -> impl egui::Widget + 'm { |ui: &mut egui::Ui| { - let button_text = if let Some(track) = &self.tab.audio_file.name { - format!("Audio/{}/{}", self.tab.source, track) + let button_text = if let Some(track) = &data.name { + format!("Audio/{}/{}", self.source, track) } else { "(None)".to_string() }; @@ -57,7 +62,12 @@ impl luminol_core::Modal for Modal { let mut button_response = ui.button(button_text); if button_response.clicked() { - self.open = true; + let tab = luminol_components::SoundTab::new( + update_state.filesystem, + self.source, + data.clone(), + ); + self.state = State::Open { tab }; } if self.show_window(update_state, ui.ctx(), data) { button_response.mark_changed() @@ -68,7 +78,7 @@ impl luminol_core::Modal for Modal { } fn reset(&mut self) { - self.open = false; + self.state = State::Closed; } } @@ -79,24 +89,30 @@ impl Modal { ctx: &egui::Context, data: &mut luminol_data::rpg::AudioFile, ) -> bool { - let mut win_open = self.open; + let mut win_open = true; let mut keep_open = true; let mut needs_save = false; + let State::Open { tab } = &mut self.state else { + return false; + }; + egui::Window::new("Graphic Picker") .open(&mut win_open) .show(ctx, |ui| { - self.tab.ui(ui, update_state); + tab.ui(ui, update_state); ui.separator(); luminol_components::close_options_ui(ui, &mut keep_open, &mut needs_save); }); if needs_save { - *data = self.tab.audio_file.clone(); + *data = tab.audio_file.clone(); } - self.open = win_open && keep_open; + if !(win_open && keep_open) { + self.state = State::Closed; + } needs_save } } diff --git a/crates/ui/src/windows/actors.rs b/crates/ui/src/windows/actors.rs index dbe35e03..bbd460da 100644 --- a/crates/ui/src/windows/actors.rs +++ b/crates/ui/src/windows/actors.rs @@ -27,8 +27,8 @@ use luminol_components::UiExt; use luminol_data::rpg::armor::Kind; -#[derive(Default)] pub struct Window { + actors: Vec, selected_actor_name: Option, previous_actor: Option, @@ -39,8 +39,16 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let actors = update_state.data.actors(); + Self { + actors: actors.data.clone(), + selected_actor_name: None, + previous_actor: None, + exp_view_is_total: false, + exp_view_is_depersisted: false, + view: luminol_components::DatabaseView::new(), + } } } @@ -222,13 +230,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut actors = update_state.data.actors(); - let mut classes = update_state.data.classes(); - let weapons = update_state.data.weapons(); - let armors = update_state.data.armors(); - - let mut modified = false; - self.selected_actor_name = None; let response = egui::Window::new(self.name()) @@ -240,40 +241,42 @@ impl luminol_core::Window for Window { ui, update_state, "Actors", - &mut actors.data, + &mut self.actors, |actor| format!("{:0>4}: {}", actor.id + 1, actor.name), - |ui, actors, id| { + |ui, actors, id, update_state| { let actor = &mut actors[id]; self.selected_actor_name = Some(actor.name.clone()); + let mut classes = update_state.data.classes(); + let weapons = update_state.data.weapons(); + let armors = update_state.data.armors(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut actor.name) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut actor.name) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Class", - luminol_components::OptionalIdComboBox::new( - update_state, - (actor.id, "class"), - &mut actor.class_id, - 0..classes.data.len(), - |id| { - classes.data.get(id).map_or_else( - || "".into(), - |c| format!("{:0>4}: {}", id + 1, c.name), - ) - }, - ), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Class", + luminol_components::OptionalIdComboBox::new( + update_state, + (actor.id, "class"), + &mut actor.class_id, + 0..classes.data.len(), + |id| { + classes.data.get(id).map_or_else( + || "".into(), + |c| format!("{:0>4}: {}", id + 1, c.name), + ) + }, + ), + )) + .changed(); }); if let Some(class) = classes.data.get_mut(actor.class_id) { @@ -293,7 +296,7 @@ impl luminol_core::Window for Window { egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add( luminol_components::OptionalIdComboBox::new( update_state, @@ -325,7 +328,7 @@ impl luminol_core::Window for Window { ), ) .changed(); - modified |= columns[1] + columns[1] .checkbox(&mut actor.weapon_fix, "Fixed") .changed(); }); @@ -342,7 +345,7 @@ impl luminol_core::Window for Window { egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add( luminol_components::OptionalIdComboBox::new( update_state, @@ -381,7 +384,7 @@ impl luminol_core::Window for Window { ), ) .changed(); - modified |= columns[1] + columns[1] .checkbox(&mut actor.armor1_fix, "Fixed") .changed(); }); @@ -398,7 +401,7 @@ impl luminol_core::Window for Window { egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add( luminol_components::OptionalIdComboBox::new( update_state, @@ -437,7 +440,7 @@ impl luminol_core::Window for Window { ), ) .changed(); - modified |= columns[1] + columns[1] .checkbox(&mut actor.armor2_fix, "Fixed") .changed(); }); @@ -454,7 +457,7 @@ impl luminol_core::Window for Window { egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add( luminol_components::OptionalIdComboBox::new( update_state, @@ -493,7 +496,7 @@ impl luminol_core::Window for Window { ), ) .changed(); - modified |= columns[1] + columns[1] .checkbox(&mut actor.armor3_fix, "Fixed") .changed(); }); @@ -510,7 +513,7 @@ impl luminol_core::Window for Window { egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add( luminol_components::OptionalIdComboBox::new( update_state, @@ -549,7 +552,7 @@ impl luminol_core::Window for Window { ), ) .changed(); - modified |= columns[1] + columns[1] .checkbox(&mut actor.armor4_fix, "Fixed") .changed(); }); @@ -561,14 +564,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Initial Level", egui::Slider::new(&mut actor.initial_level, 1..=99), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Final Level", egui::Slider::new( @@ -610,14 +613,14 @@ impl luminol_core::Window for Window { }); ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "EXP Curve Basis", egui::Slider::new(&mut actor.exp_basis, 10..=50), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "EXP Curve Inflation", egui::Slider::new(&mut actor.exp_inflation, 10..=50), @@ -721,13 +724,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - actors.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/crates/ui/src/windows/armor.rs b/crates/ui/src/windows/armor.rs index e1d0eb50..61ef5498 100644 --- a/crates/ui/src/windows/armor.rs +++ b/crates/ui/src/windows/armor.rs @@ -24,8 +24,8 @@ use luminol_components::UiExt; -#[derive(Default)] pub struct Window { + armors: Vec, selected_armor_name: Option, previous_armor: Option, @@ -33,8 +33,14 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let armors = update_state.data.armors(); + Self { + armors: armors.data.clone(), + selected_armor_name: None, + previous_armor: None, + view: luminol_components::DatabaseView::new(), + } } } @@ -61,12 +67,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut armors = update_state.data.armors(); - let system = update_state.data.system(); - let states = update_state.data.states(); - - let mut modified = false; - self.selected_armor_name = None; let response = egui::Window::new(self.name()) @@ -78,33 +78,34 @@ impl luminol_core::Window for Window { ui, update_state, "Armor", - &mut armors.data, + &mut self.armors, |armor| format!("{:0>4}: {}", armor.id + 1, armor.name), - |ui, armors, id| { + |ui, armors, id, update_state| { let armor = &mut armors[id]; self.selected_armor_name = Some(armor.name.clone()); + let system = update_state.data.system(); + let states = update_state.data.states(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut armor.name) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut armor.name) + .desired_width(f32::INFINITY), + )) + .changed(); - modified |= ui - .add(luminol_components::Field::new( - "Description", - egui::TextEdit::multiline(&mut armor.description) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Description", + egui::TextEdit::multiline(&mut armor.description) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Kind", luminol_components::EnumComboBox::new( @@ -114,7 +115,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Auto State", luminol_components::OptionalIdComboBox::new( @@ -136,7 +137,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Price", egui::DragValue::new(&mut armor.price) @@ -144,7 +145,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "EVA", egui::DragValue::new(&mut armor.eva) @@ -152,7 +153,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "PDEF", egui::DragValue::new(&mut armor.pdef) @@ -160,7 +161,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "MDEF", egui::DragValue::new(&mut armor.mdef) @@ -172,28 +173,28 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "STR+", egui::DragValue::new(&mut armor.str_plus), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "DEX+", egui::DragValue::new(&mut armor.dex_plus), )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "AGI+", egui::DragValue::new(&mut armor.agi_plus), )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "INT+", egui::DragValue::new(&mut armor.int_plus), @@ -219,7 +220,7 @@ impl luminol_core::Window for Window { if self.previous_armor != Some(armor.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Element Defense", selection, @@ -241,7 +242,7 @@ impl luminol_core::Window for Window { if self.previous_armor != Some(armor.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("States", selection)) .changed(); }); @@ -252,13 +253,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - armors.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/crates/ui/src/windows/classes.rs b/crates/ui/src/windows/classes.rs index 835b575a..da70b4b0 100644 --- a/crates/ui/src/windows/classes.rs +++ b/crates/ui/src/windows/classes.rs @@ -24,8 +24,8 @@ use luminol_components::UiExt; -#[derive(Default)] pub struct Window { + classes: Vec, selected_class_name: Option, previous_class: Option, @@ -34,8 +34,16 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let classes = update_state.data.classes(); + + Self { + classes: classes.data.clone(), + selected_class_name: None, + previous_class: None, + collapsing_view: luminol_components::CollapsingView::new(), + view: luminol_components::DatabaseView::new(), + } } fn show_learning_header( @@ -58,19 +66,18 @@ impl Window { learning: (usize, &mut luminol_data::rpg::class::Learning), ) -> egui::Response { let (learning_index, learning) = learning; - let mut modified = false; - let mut response = egui::Frame::none() + egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Level", egui::Slider::new(&mut learning.level, 1..=99), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Skill", luminol_components::OptionalIdComboBox::new( @@ -89,12 +96,7 @@ impl Window { .changed(); }); }) - .response; - - if modified { - response.mark_changed(); - } - response + .response } } @@ -121,15 +123,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut classes = update_state.data.classes(); - let system = update_state.data.system(); - let states = update_state.data.states(); - let skills = update_state.data.skills(); - let weapons = update_state.data.weapons(); - let armors = update_state.data.armors(); - - let mut modified = false; - self.selected_class_name = None; let response = egui::Window::new(self.name()) @@ -141,62 +134,65 @@ impl luminol_core::Window for Window { ui, update_state, "Classes", - &mut classes.data, + &mut self.classes, |class| format!("{:0>3}: {}", class.id + 1, class.name), - |ui, classes, id| { + |ui, classes, id, update_state| { let class = &mut classes[id]; self.selected_class_name = Some(class.name.clone()); + let system = update_state.data.system(); + let states = update_state.data.states(); + let skills = update_state.data.skills(); + let weapons = update_state.data.weapons(); + let armors = update_state.data.armors(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut class.name) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut class.name) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Position", - luminol_components::EnumComboBox::new( - (class.id, "position"), - &mut class.position, - ), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Position", + luminol_components::EnumComboBox::new( + (class.id, "position"), + &mut class.position, + ), + )) + .changed(); }); ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Skills", - |ui: &mut egui::Ui| { - if self.previous_class != Some(class.id) { - self.collapsing_view.clear_animations(); - } - self.collapsing_view.show( - ui, - class.id, - &mut class.learnings, - |ui, _i, learning| { - Self::show_learning_header(ui, &skills, learning) - }, - |ui, i, learning| { - Self::show_learning_body( - ui, - update_state, - &skills, - class.id, - (i, learning), - ) - }, - ) - }, - )) - .changed(); + ui.add(luminol_components::Field::new( + "Skills", + |ui: &mut egui::Ui| { + if self.previous_class != Some(class.id) { + self.collapsing_view.clear_animations(); + } + self.collapsing_view.show( + ui, + class.id, + &mut class.learnings, + |ui, _i, learning| { + Self::show_learning_header(ui, &skills, learning) + }, + |ui, i, learning| { + Self::show_learning_body( + ui, + update_state, + &skills, + class.id, + (i, learning), + ) + }, + ) + }, + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { @@ -216,7 +212,7 @@ impl luminol_core::Window for Window { if self.previous_class != Some(class.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Equippable Weapons", selection, @@ -238,7 +234,7 @@ impl luminol_core::Window for Window { if self.previous_class != Some(class.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Equippable Armor", selection, @@ -266,7 +262,7 @@ impl luminol_core::Window for Window { if self.previous_class != Some(class.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new("Elements", selection)) .changed(); @@ -287,7 +283,7 @@ impl luminol_core::Window for Window { if self.previous_class != Some(class.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("States", selection)) .changed(); }); @@ -298,13 +294,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - classes.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/crates/ui/src/windows/enemies.rs b/crates/ui/src/windows/enemies.rs index 08e0c9e4..836a754f 100644 --- a/crates/ui/src/windows/enemies.rs +++ b/crates/ui/src/windows/enemies.rs @@ -35,8 +35,8 @@ pub enum TreasureType { Armor, } -#[derive(Default)] pub struct Window { + enemies: Vec, selected_enemy_name: Option, previous_enemy: Option, @@ -45,8 +45,15 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let enimies = update_state.data.enemies(); + Self { + enemies: enimies.data.clone(), + selected_enemy_name: None, + previous_enemy: None, + collapsing_view: luminol_components::CollapsingView::new(), + view: luminol_components::DatabaseView::new(), + } } fn show_action_header( @@ -109,12 +116,11 @@ impl Window { action: (usize, &mut luminol_data::rpg::enemy::Action), ) -> egui::Response { let (action_index, action) = action; - let mut modified = false; - let mut response = egui::Frame::none() + egui::Frame::none() .show(ui, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Turn Offset", egui::DragValue::new(&mut action.condition_turn_a) @@ -122,7 +128,7 @@ impl Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Turn Interval", egui::DragValue::new(&mut action.condition_turn_b) @@ -132,14 +138,14 @@ impl Window { }); ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Max HP %", egui::Slider::new(&mut action.condition_hp, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Min Level", egui::Slider::new(&mut action.condition_level, 1..=99), @@ -147,26 +153,25 @@ impl Window { .changed(); }); - modified |= ui - .add(luminol_components::Field::new( - "Switch", - luminol_components::OptionalIdComboBox::new( - update_state, - (enemy_id, action_index, "condition_switch_id"), - &mut action.condition_switch_id, - 0..system.switches.len(), - |id| { - system - .switches - .get(id) - .map_or_else(|| "".into(), |s| format!("{:0>4}: {}", id + 1, s)) - }, - ), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Switch", + luminol_components::OptionalIdComboBox::new( + update_state, + (enemy_id, action_index, "condition_switch_id"), + &mut action.condition_switch_id, + 0..system.switches.len(), + |id| { + system + .switches + .get(id) + .map_or_else(|| "".into(), |s| format!("{:0>4}: {}", id + 1, s)) + }, + ), + )) + .changed(); ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Kind", luminol_components::EnumComboBox::new( @@ -178,7 +183,7 @@ impl Window { match action.kind { luminol_data::rpg::enemy::Kind::Basic => { - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Basic Type", luminol_components::EnumComboBox::new( @@ -189,7 +194,7 @@ impl Window { .changed(); } luminol_data::rpg::enemy::Kind::Skill => { - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Skill", luminol_components::OptionalIdComboBox::new( @@ -210,19 +215,13 @@ impl Window { } }); - modified |= ui - .add(luminol_components::Field::new( - "Rating", - egui::Slider::new(&mut action.rating, 1..=10), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Rating", + egui::Slider::new(&mut action.rating, 1..=10), + )) + .changed(); }) - .response; - - if modified { - response.mark_changed(); - } - response + .response } } @@ -249,17 +248,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut enemies = update_state.data.enemies(); - let animations = update_state.data.animations(); - let system = update_state.data.system(); - let states = update_state.data.states(); - let skills = update_state.data.skills(); - let items = update_state.data.items(); - let weapons = update_state.data.weapons(); - let armors = update_state.data.armors(); - - let mut modified = false; - self.selected_enemy_name = None; let response = egui::Window::new(self.name()) @@ -271,25 +259,32 @@ impl luminol_core::Window for Window { ui, update_state, "Enemies", - &mut enemies.data, + &mut self.enemies, |enemy| format!("{:0>4}: {}", enemy.id + 1, enemy.name), - |ui, enemies, id| { + |ui, enemies, id, update_state| { let enemy = &mut enemies[id]; self.selected_enemy_name = Some(enemy.name.clone()); + let animations = update_state.data.animations(); + let system = update_state.data.system(); + let states = update_state.data.states(); + let skills = update_state.data.skills(); + let items = update_state.data.items(); + let weapons = update_state.data.weapons(); + let armors = update_state.data.armors(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut enemy.name) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut enemy.name) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Attacker Animation", luminol_components::OptionalIdComboBox::new( @@ -307,7 +302,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Target Animation", luminol_components::OptionalIdComboBox::new( @@ -329,7 +324,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "EXP", egui::DragValue::new(&mut enemy.exp) @@ -337,7 +332,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Gold", egui::DragValue::new(&mut enemy.gold) @@ -345,7 +340,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "Max HP", egui::DragValue::new(&mut enemy.maxhp) @@ -353,7 +348,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "Max SP", egui::DragValue::new(&mut enemy.maxsp) @@ -365,7 +360,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "STR", egui::DragValue::new(&mut enemy.str) @@ -373,7 +368,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "DEX", egui::DragValue::new(&mut enemy.dex) @@ -381,7 +376,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "AGI", egui::DragValue::new(&mut enemy.agi) @@ -389,7 +384,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "INT", egui::DragValue::new(&mut enemy.int) @@ -401,7 +396,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "ATK", egui::DragValue::new(&mut enemy.atk) @@ -409,7 +404,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "EVA", egui::DragValue::new(&mut enemy.eva) @@ -417,7 +412,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "PDEF", egui::DragValue::new(&mut enemy.pdef) @@ -425,7 +420,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "MDEF", egui::DragValue::new(&mut enemy.mdef) @@ -447,7 +442,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Treasure Type", luminol_components::EnumComboBox::new( @@ -457,7 +452,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Treasure Probability", egui::Slider::new(&mut enemy.treasure_prob, 0..=100) @@ -479,24 +474,23 @@ impl luminol_core::Window for Window { if enemy.item_id.is_none() { enemy.item_id = Some(0); } - modified |= ui - .add(luminol_components::Field::new( - "Treasure", - luminol_components::OptionalIdComboBox::new( - update_state, - (enemy.id, "item_id"), - &mut enemy.item_id, - 0..items.data.len(), - |id| { - items.data.get(id).map_or_else( - || "".into(), - |i| format!("{:0>4}: {}", id + 1, i.name), - ) - }, - ) - .allow_none(false), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Treasure", + luminol_components::OptionalIdComboBox::new( + update_state, + (enemy.id, "item_id"), + &mut enemy.item_id, + 0..items.data.len(), + |id| { + items.data.get(id).map_or_else( + || "".into(), + |i| format!("{:0>4}: {}", id + 1, i.name), + ) + }, + ) + .allow_none(false), + )) + .changed(); } TreasureType::Weapon => { @@ -505,24 +499,23 @@ impl luminol_core::Window for Window { if enemy.weapon_id.is_none() { enemy.weapon_id = Some(0); } - modified |= ui - .add(luminol_components::Field::new( - "Treasure", - luminol_components::OptionalIdComboBox::new( - update_state, - (enemy.id, "weapon_id"), - &mut enemy.weapon_id, - 0..weapons.data.len(), - |id| { - weapons.data.get(id).map_or_else( - || "".into(), - |w| format!("{:0>4}: {}", id + 1, w.name), - ) - }, - ) - .allow_none(false), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Treasure", + luminol_components::OptionalIdComboBox::new( + update_state, + (enemy.id, "weapon_id"), + &mut enemy.weapon_id, + 0..weapons.data.len(), + |id| { + weapons.data.get(id).map_or_else( + || "".into(), + |w| format!("{:0>4}: {}", id + 1, w.name), + ) + }, + ) + .allow_none(false), + )) + .changed(); } TreasureType::Armor => { @@ -531,57 +524,55 @@ impl luminol_core::Window for Window { if enemy.armor_id.is_none() { enemy.armor_id = Some(0); } - modified |= ui - .add(luminol_components::Field::new( - "Treasure", - luminol_components::OptionalIdComboBox::new( - update_state, - (enemy.id, "armor_id"), - &mut enemy.armor_id, - 0..armors.data.len(), - |id| { - armors.data.get(id).map_or_else( - || "".into(), - |a| format!("{:0>4}: {}", id + 1, a.name), - ) - }, - ) - .allow_none(false), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Treasure", + luminol_components::OptionalIdComboBox::new( + update_state, + (enemy.id, "armor_id"), + &mut enemy.armor_id, + 0..armors.data.len(), + |id| { + armors.data.get(id).map_or_else( + || "".into(), + |a| format!("{:0>4}: {}", id + 1, a.name), + ) + }, + ) + .allow_none(false), + )) + .changed(); } }; }); ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Actions", - |ui: &mut egui::Ui| { - if self.previous_enemy != Some(enemy.id) { - self.collapsing_view.clear_animations(); - } - self.collapsing_view.show( - ui, - enemy.id, - &mut enemy.actions, - |ui, _i, action| { - Self::show_action_header(ui, &skills, action) - }, - |ui, i, action| { - Self::show_action_body( - ui, - update_state, - &system, - &skills, - enemy.id, - (i, action), - ) - }, - ) - }, - )) - .changed(); + ui.add(luminol_components::Field::new( + "Actions", + |ui: &mut egui::Ui| { + if self.previous_enemy != Some(enemy.id) { + self.collapsing_view.clear_animations(); + } + self.collapsing_view.show( + ui, + enemy.id, + &mut enemy.actions, + |ui, _i, action| { + Self::show_action_header(ui, &skills, action) + }, + |ui, i, action| { + Self::show_action_body( + ui, + update_state, + &system, + &skills, + enemy.id, + (i, action), + ) + }, + ) + }, + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { @@ -603,7 +594,7 @@ impl luminol_core::Window for Window { if self.previous_enemy != Some(enemy.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new("Elements", selection)) .changed(); @@ -624,7 +615,7 @@ impl luminol_core::Window for Window { if self.previous_enemy != Some(enemy.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("States", selection)) .changed(); }); @@ -635,13 +626,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - enemies.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/crates/ui/src/windows/items.rs b/crates/ui/src/windows/items.rs index a1c3981b..9a6d21c6 100644 --- a/crates/ui/src/windows/items.rs +++ b/crates/ui/src/windows/items.rs @@ -23,18 +23,15 @@ // Program grant you additional permission to convey the resulting work. use luminol_components::UiExt; +use luminol_core::Modal; /// Database - Items management window. -#[derive(Default)] pub struct Window { - // ? Items ? + items: Vec, selected_item_name: Option, - // ? Icon Graphic Picker ? - _icon_picker: Option, - // ? Menu Sound Effect Picker ? - _menu_se_picker: Option, + menu_se_picker: luminol_modals::sound_picker::Modal, previous_item: Option, @@ -42,8 +39,18 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let items = update_state.data.items(); + Self { + items: items.data.clone(), + selected_item_name: None, + menu_se_picker: luminol_modals::sound_picker::Modal::new( + luminol_audio::Source::SE, + "item_editor_sound_picker", + ), + previous_item: None, + view: luminol_components::DatabaseView::new(), + } } } @@ -70,17 +77,9 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut items = update_state.data.items(); - let animations = update_state.data.animations(); - let common_events = update_state.data.common_events(); - let system = update_state.data.system(); - let states = update_state.data.states(); - - let mut modified = false; - self.selected_item_name = None; - let response = egui::Window::new(self.name()) + egui::Window::new(self.name()) .id(self.id()) .default_width(500.) .open(open) @@ -89,33 +88,31 @@ impl luminol_core::Window for Window { ui, update_state, "Items", - &mut items.data, + &mut self.items, |item| format!("{:0>4}: {}", item.id + 1, item.name), - |ui, items, id| { + |ui, items, id, update_state| { let item = &mut items[id]; self.selected_item_name = Some(item.name.clone()); ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut item.name) - .desired_width(f32::INFINITY), - )) - .changed(); - - modified |= ui - .add(luminol_components::Field::new( - "Description", - egui::TextEdit::multiline(&mut item.description) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut item.name) + .desired_width(f32::INFINITY), + )) + .changed(); + + ui.add(luminol_components::Field::new( + "Description", + egui::TextEdit::multiline(&mut item.description) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Scope", luminol_components::EnumComboBox::new( @@ -125,7 +122,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Occasion", luminol_components::EnumComboBox::new( @@ -138,8 +135,9 @@ impl luminol_core::Window for Window { }); ui.with_padded_stripe(false, |ui| { + let animations = update_state.data.animations(); ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "User Animation", luminol_components::OptionalIdComboBox::new( @@ -157,7 +155,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Target Animation", luminol_components::OptionalIdComboBox::new( @@ -179,14 +177,15 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Menu Use SE", - egui::Label::new("TODO"), + self.menu_se_picker.button(&mut item.menu_se, update_state), )) .changed(); - modified |= columns[1] + let common_events = update_state.data.common_events(); + columns[1] .add(luminol_components::Field::new( "Common Event", luminol_components::OptionalIdComboBox::new( @@ -208,7 +207,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Price", egui::DragValue::new(&mut item.price) @@ -216,7 +215,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Consumable", egui::Checkbox::without_text(&mut item.consumable), @@ -227,18 +226,17 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { if item.parameter_type.is_none() { - modified |= ui - .add(luminol_components::Field::new( - "Parameter", - luminol_components::EnumComboBox::new( - "parameter_type", - &mut item.parameter_type, - ), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Parameter", + luminol_components::EnumComboBox::new( + "parameter_type", + &mut item.parameter_type, + ), + )) + .changed(); } else { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Parameter", luminol_components::EnumComboBox::new( @@ -248,7 +246,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Parameter Increment", egui::DragValue::new(&mut item.parameter_points) @@ -261,7 +259,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Recover HP %", egui::Slider::new(&mut item.recover_hp_rate, 0..=100) @@ -269,7 +267,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Recover HP Points", egui::DragValue::new(&mut item.recover_hp) @@ -281,7 +279,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Recover SP %", egui::Slider::new(&mut item.recover_sp_rate, 0..=100) @@ -289,7 +287,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Recover SP Points", egui::DragValue::new(&mut item.recover_sp) @@ -301,14 +299,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Hit Rate", egui::Slider::new(&mut item.hit, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Variance", egui::Slider::new(&mut item.variance, 0..=100).suffix("%"), @@ -319,14 +317,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "PDEF-F", egui::Slider::new(&mut item.pdef_f, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "MDEF-F", egui::Slider::new(&mut item.mdef_f, 0..=100).suffix("%"), @@ -336,6 +334,8 @@ impl luminol_core::Window for Window { }); ui.with_padded_stripe(false, |ui| { + let system = update_state.data.system(); + let states = update_state.data.states(); ui.columns(2, |columns| { let mut selection = luminol_components::IdVecSelection::new( update_state, @@ -352,7 +352,7 @@ impl luminol_core::Window for Window { if self.previous_item != Some(item.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new("Elements", selection)) .changed(); @@ -373,7 +373,7 @@ impl luminol_core::Window for Window { if self.previous_item != Some(item.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("State Change", selection)) .changed(); }); @@ -383,14 +383,5 @@ impl luminol_core::Window for Window { }, ) }); - - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - items.modified = true; - } } } diff --git a/crates/ui/src/windows/skills.rs b/crates/ui/src/windows/skills.rs index 0d194751..58a8694a 100644 --- a/crates/ui/src/windows/skills.rs +++ b/crates/ui/src/windows/skills.rs @@ -24,8 +24,8 @@ use luminol_components::UiExt; -#[derive(Default)] pub struct Window { + skills: Vec, selected_skill_name: Option, previous_skill: Option, @@ -33,8 +33,14 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let skills = update_state.data.skills(); + Self { + skills: skills.data.clone(), + selected_skill_name: None, + previous_skill: None, + view: luminol_components::DatabaseView::new(), + } } } @@ -61,14 +67,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut skills = update_state.data.skills(); - let animations = update_state.data.animations(); - let common_events = update_state.data.common_events(); - let system = update_state.data.system(); - let states = update_state.data.states(); - - let mut modified = false; - self.selected_skill_name = None; let response = egui::Window::new(self.name()) @@ -80,33 +78,36 @@ impl luminol_core::Window for Window { ui, update_state, "Skills", - &mut skills.data, + &mut self.skills, |skill| format!("{:0>4}: {}", skill.id + 1, skill.name), - |ui, skills, id| { + |ui, skills, id, update_state| { let skill = &mut skills[id]; self.selected_skill_name = Some(skill.name.clone()); + let animations = update_state.data.animations(); + let common_events = update_state.data.common_events(); + let system = update_state.data.system(); + let states = update_state.data.states(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut skill.name) - .desired_width(f32::INFINITY), - )) - .changed(); - - modified |= ui - .add(luminol_components::Field::new( - "Description", - egui::TextEdit::multiline(&mut skill.description) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut skill.name) + .desired_width(f32::INFINITY), + )) + .changed(); + + ui.add(luminol_components::Field::new( + "Description", + egui::TextEdit::multiline(&mut skill.description) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Scope", luminol_components::EnumComboBox::new( @@ -116,7 +117,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Occasion", luminol_components::EnumComboBox::new( @@ -130,7 +131,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "User Animation", luminol_components::OptionalIdComboBox::new( @@ -148,7 +149,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Target Animation", luminol_components::OptionalIdComboBox::new( @@ -170,14 +171,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Menu Use SE", egui::Label::new("TODO"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Common Event", luminol_components::OptionalIdComboBox::new( @@ -199,7 +200,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "SP Cost", egui::DragValue::new(&mut skill.sp_cost) @@ -207,7 +208,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Power", egui::DragValue::new(&mut skill.power), @@ -218,14 +219,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "ATK-F", egui::Slider::new(&mut skill.atk_f, 0..=200).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "EVA-F", egui::Slider::new(&mut skill.eva_f, 0..=100).suffix("%"), @@ -236,14 +237,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "STR-F", egui::Slider::new(&mut skill.str_f, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "DEX-F", egui::Slider::new(&mut skill.dex_f, 0..=100).suffix("%"), @@ -254,14 +255,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "AGI-F", egui::Slider::new(&mut skill.agi_f, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "INT-F", egui::Slider::new(&mut skill.int_f, 0..=100).suffix("%"), @@ -272,14 +273,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Hit Rate", egui::Slider::new(&mut skill.hit, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Variance", egui::Slider::new(&mut skill.variance, 0..=100).suffix("%"), @@ -290,14 +291,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "PDEF-F", egui::Slider::new(&mut skill.pdef_f, 0..=100).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "MDEF-F", egui::Slider::new(&mut skill.mdef_f, 0..=100).suffix("%"), @@ -323,7 +324,7 @@ impl luminol_core::Window for Window { if self.previous_skill != Some(skill.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new("Elements", selection)) .changed(); @@ -344,7 +345,7 @@ impl luminol_core::Window for Window { if self.previous_skill != Some(skill.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("State Change", selection)) .changed(); }); @@ -355,13 +356,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - skills.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/crates/ui/src/windows/states.rs b/crates/ui/src/windows/states.rs index 08862cdd..d578cb83 100644 --- a/crates/ui/src/windows/states.rs +++ b/crates/ui/src/windows/states.rs @@ -24,8 +24,8 @@ use luminol_components::UiExt; -#[derive(Default)] pub struct Window { + states: Vec, selected_state_name: Option, previous_state: Option, @@ -33,8 +33,14 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let states = update_state.data.states(); + Self { + states: states.data.clone(), + selected_state_name: None, + previous_state: None, + view: luminol_components::DatabaseView::new(), + } } } @@ -61,12 +67,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut states = update_state.data.states(); - let animations = update_state.data.animations(); - let system = update_state.data.system(); - - let mut modified = false; - self.selected_state_name = None; let response = egui::Window::new(self.name()) @@ -78,25 +78,27 @@ impl luminol_core::Window for Window { ui, update_state, "States", - &mut states.data, + &mut self.states, |state| format!("{:0>4}: {}", state.id + 1, state.name), - |ui, states, id| { + |ui, states, id, update_state| { let state = &mut states[id]; self.selected_state_name = Some(state.name.clone()); + let animations = update_state.data.animations(); + let system = update_state.data.system(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut state.name) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut state.name) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Animation", luminol_components::OptionalIdComboBox::new( @@ -114,7 +116,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Restriction", luminol_components::EnumComboBox::new( @@ -128,14 +130,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Nonresistance", egui::Checkbox::without_text(&mut state.nonresistance), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Count as 0 HP", egui::Checkbox::without_text(&mut state.zero_hp), @@ -146,21 +148,21 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(3, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Can't Get EXP", egui::Checkbox::without_text(&mut state.cant_get_exp), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Can't Evade", egui::Checkbox::without_text(&mut state.cant_evade), )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "Slip Damage", egui::Checkbox::without_text(&mut state.slip_damage), @@ -171,14 +173,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Rating", egui::DragValue::new(&mut state.rating).clamp_range(0..=10), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "EVA", egui::DragValue::new(&mut state.eva), @@ -189,7 +191,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Max HP %", egui::Slider::new(&mut state.maxhp_rate, 0..=200) @@ -197,7 +199,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Max SP %", egui::Slider::new(&mut state.maxsp_rate, 0..=200) @@ -209,14 +211,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "STR %", egui::Slider::new(&mut state.str_rate, 0..=200).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "DEX %", egui::Slider::new(&mut state.dex_rate, 0..=200).suffix("%"), @@ -227,14 +229,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "AGI %", egui::Slider::new(&mut state.agi_rate, 0..=200).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "INT %", egui::Slider::new(&mut state.int_rate, 0..=200).suffix("%"), @@ -245,14 +247,14 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Hit Rate %", egui::Slider::new(&mut state.hit_rate, 0..=200).suffix("%"), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "ATK %", egui::Slider::new(&mut state.atk_rate, 0..=200).suffix("%"), @@ -263,7 +265,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "PDEF %", egui::Slider::new(&mut state.pdef_rate, 0..=200) @@ -271,7 +273,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "MDEF %", egui::Slider::new(&mut state.mdef_rate, 0..=200) @@ -283,7 +285,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Auto Release Probability", egui::Slider::new(&mut state.auto_release_prob, 0..=100) @@ -291,7 +293,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Auto Release Interval", egui::DragValue::new(&mut state.hold_turn) @@ -303,7 +305,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Damage Release Probability", egui::Slider::new(&mut state.shock_release_prob, 0..=100) @@ -311,7 +313,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Battle Only", egui::Checkbox::without_text(&mut state.battle_only), @@ -338,7 +340,7 @@ impl luminol_core::Window for Window { if self.previous_state != Some(state.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Element Defense", selection, @@ -366,7 +368,7 @@ impl luminol_core::Window for Window { if self.previous_state != Some(state.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("State Change", selection)) .changed(); }); @@ -378,13 +380,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - states.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/crates/ui/src/windows/weapons.rs b/crates/ui/src/windows/weapons.rs index b75ce381..9c2fb819 100644 --- a/crates/ui/src/windows/weapons.rs +++ b/crates/ui/src/windows/weapons.rs @@ -24,8 +24,8 @@ use luminol_components::UiExt; -#[derive(Default)] pub struct Window { + weapons: Vec, selected_weapon_name: Option, previous_weapon: Option, @@ -33,8 +33,15 @@ pub struct Window { } impl Window { - pub fn new() -> Self { - Default::default() + pub fn new(update_state: &luminol_core::UpdateState<'_>) -> Self { + let weapons = update_state.data.weapons(); + Self { + weapons: weapons.data.clone(), + selected_weapon_name: None, + previous_weapon: None, + + view: luminol_components::DatabaseView::new(), + } } } @@ -61,13 +68,6 @@ impl luminol_core::Window for Window { open: &mut bool, update_state: &mut luminol_core::UpdateState<'_>, ) { - let mut weapons = update_state.data.weapons(); - let animations = update_state.data.animations(); - let system = update_state.data.system(); - let states = update_state.data.states(); - - let mut modified = false; - self.selected_weapon_name = None; let response = egui::Window::new(self.name()) @@ -79,33 +79,35 @@ impl luminol_core::Window for Window { ui, update_state, "Weapons", - &mut weapons.data, + &mut self.weapons, |weapon| format!("{:0>4}: {}", weapon.id + 1, weapon.name), - |ui, weapons, id| { + |ui, weapons, id, update_state| { let weapon = &mut weapons[id]; self.selected_weapon_name = Some(weapon.name.clone()); + let animations = update_state.data.animations(); + let system = update_state.data.system(); + let states = update_state.data.states(); + ui.with_padded_stripe(false, |ui| { - modified |= ui - .add(luminol_components::Field::new( - "Name", - egui::TextEdit::singleline(&mut weapon.name) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Name", + egui::TextEdit::singleline(&mut weapon.name) + .desired_width(f32::INFINITY), + )) + .changed(); - modified |= ui - .add(luminol_components::Field::new( - "Description", - egui::TextEdit::multiline(&mut weapon.description) - .desired_width(f32::INFINITY), - )) - .changed(); + ui.add(luminol_components::Field::new( + "Description", + egui::TextEdit::multiline(&mut weapon.description) + .desired_width(f32::INFINITY), + )) + .changed(); }); ui.with_padded_stripe(true, |ui| { ui.columns(2, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "User Animation", luminol_components::OptionalIdComboBox::new( @@ -123,7 +125,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "Target Animation", luminol_components::OptionalIdComboBox::new( @@ -145,7 +147,7 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(false, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "Price", egui::DragValue::new(&mut weapon.price) @@ -153,7 +155,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "ATK", egui::DragValue::new(&mut weapon.atk) @@ -161,7 +163,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "PDEF", egui::DragValue::new(&mut weapon.pdef) @@ -169,7 +171,7 @@ impl luminol_core::Window for Window { )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "MDEF", egui::DragValue::new(&mut weapon.mdef) @@ -181,28 +183,28 @@ impl luminol_core::Window for Window { ui.with_padded_stripe(true, |ui| { ui.columns(4, |columns| { - modified |= columns[0] + columns[0] .add(luminol_components::Field::new( "STR+", egui::DragValue::new(&mut weapon.str_plus), )) .changed(); - modified |= columns[1] + columns[1] .add(luminol_components::Field::new( "DEX+", egui::DragValue::new(&mut weapon.dex_plus), )) .changed(); - modified |= columns[2] + columns[2] .add(luminol_components::Field::new( "AGI+", egui::DragValue::new(&mut weapon.agi_plus), )) .changed(); - modified |= columns[3] + columns[3] .add(luminol_components::Field::new( "INT+", egui::DragValue::new(&mut weapon.int_plus), @@ -228,7 +230,7 @@ impl luminol_core::Window for Window { if self.previous_weapon != Some(weapon.id) { selection.clear_search(); } - modified |= columns[0] + columns[0] .add(luminol_components::Field::new("Elements", selection)) .changed(); @@ -249,7 +251,7 @@ impl luminol_core::Window for Window { if self.previous_weapon != Some(weapon.id) { selection.clear_search(); } - modified |= columns[1] + columns[1] .add(luminol_components::Field::new("State Change", selection)) .changed(); }); @@ -260,13 +262,6 @@ impl luminol_core::Window for Window { ) }); - if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) { - modified = true; - } - - if modified { - update_state.modified.set(true); - weapons.modified = true; - } + if response.is_some_and(|ir| ir.inner.is_some_and(|ir| ir.inner.modified)) {} } } diff --git a/src/app/top_bar.rs b/src/app/top_bar.rs index f820ecb0..2aa1a006 100644 --- a/src/app/top_bar.rs +++ b/src/app/top_bar.rs @@ -211,31 +211,31 @@ impl TopBar { if ui.button("Items").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::items::Window::new()); + .add_window(luminol_ui::windows::items::Window::new(update_state)); } if ui.button("Skills").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::skills::Window::new()); + .add_window(luminol_ui::windows::skills::Window::new(update_state)); } if ui.button("Weapons").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::weapons::Window::new()); + .add_window(luminol_ui::windows::weapons::Window::new(update_state)); } if ui.button("Armor").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::armor::Window::new()); + .add_window(luminol_ui::windows::armor::Window::new(update_state)); } if ui.button("States").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::states::Window::new()); + .add_window(luminol_ui::windows::states::Window::new(update_state)); } ui.separator(); @@ -243,19 +243,19 @@ impl TopBar { if ui.button("Actors").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::actors::Window::new()); + .add_window(luminol_ui::windows::actors::Window::new(update_state)); } if ui.button("Classes").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::classes::Window::new()); + .add_window(luminol_ui::windows::classes::Window::new(update_state)); } if ui.button("Enemies").clicked() { update_state .edit_windows - .add_window(luminol_ui::windows::enemies::Window::new()); + .add_window(luminol_ui::windows::enemies::Window::new(update_state)); } ui.add_enabled_ui(false, |ui| {