diff --git a/Cargo.lock b/Cargo.lock index c3a5f60..cea710f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -485,7 +485,7 @@ dependencies = [ [[package]] name = "cofd" version = "0.1.0" -source = "git+https://github.com/m00nwtchr/cofd.git#f02af8c648f530c57cfb90a8fe6c613b297c0fd4" +source = "git+https://github.com/m00nwtchr/cofd.git#f884ea0dda8cfefc2dacc87cb503ab7663becc25" dependencies = [ "cofd-macros", "cofd-schema", @@ -500,7 +500,7 @@ dependencies = [ [[package]] name = "cofd-derive" version = "0.1.0" -source = "git+https://github.com/m00nwtchr/cofd.git#f02af8c648f530c57cfb90a8fe6c613b297c0fd4" +source = "git+https://github.com/m00nwtchr/cofd.git#f884ea0dda8cfefc2dacc87cb503ab7663becc25" dependencies = [ "convert_case 0.6.0", "proc-macro2", @@ -511,7 +511,7 @@ dependencies = [ [[package]] name = "cofd-macros" version = "0.1.0" -source = "git+https://github.com/m00nwtchr/cofd.git#f02af8c648f530c57cfb90a8fe6c613b297c0fd4" +source = "git+https://github.com/m00nwtchr/cofd.git#f884ea0dda8cfefc2dacc87cb503ab7663becc25" dependencies = [ "cofd-schema", "convert_case 0.6.0", @@ -548,7 +548,7 @@ dependencies = [ [[package]] name = "cofd-schema" version = "0.1.0" -source = "git+https://github.com/m00nwtchr/cofd.git#f02af8c648f530c57cfb90a8fe6c613b297c0fd4" +source = "git+https://github.com/m00nwtchr/cofd.git#f884ea0dda8cfefc2dacc87cb503ab7663becc25" dependencies = [ "chrono", "cofd-util", @@ -562,7 +562,7 @@ dependencies = [ [[package]] name = "cofd-util" version = "0.1.0" -source = "git+https://github.com/m00nwtchr/cofd.git#f02af8c648f530c57cfb90a8fe6c613b297c0fd4" +source = "git+https://github.com/m00nwtchr/cofd.git#f884ea0dda8cfefc2dacc87cb503ab7663becc25" dependencies = [ "cofd-derive", ] @@ -1451,7 +1451,7 @@ dependencies = [ "serde", "serde_derive", "thiserror", - "toml 0.8.17", + "toml 0.8.18", "unic-langid", ] @@ -3248,14 +3248,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.17" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a44eede9b727419af8095cb2d72fab15487a541f54647ad4414b34096ee4631" +checksum = "73b98404c41291d0a0fba7148837d26858b42e57f7abe5a4865ff39dc35d1d8c" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.18", + "toml_edit 0.22.19", ] [[package]] @@ -3280,15 +3280,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.18" +version = "0.22.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1490595c74d930da779e944f5ba2ecdf538af67df1a9848cbd156af43c1b7cf0" +checksum = "4866f4796a39e03923b14f9a42e88f223e2e685ee1851041e510c0134850c27f" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.16", + "winnow 0.6.17", ] [[package]] @@ -4163,9 +4163,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.16" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" +checksum = "93b68c91a1b24c7456960ac3290e86a316f3aefcda89c4cad24ae3eda34f4411" dependencies = [ "memchr", ] diff --git a/src/component/info.rs b/src/component/info.rs index 9663d0c..dc48736 100644 --- a/src/component/info.rs +++ b/src/component/info.rs @@ -24,6 +24,10 @@ pub enum Message { XSplatChanged(XSplat), YSplatChanged(YSplat), ZSplatChanged(ZSplat), + + XSplatNameChanged(String), + YSplatNameChanged(String), + ZSplatNameChanged(String), } impl InfoBar { @@ -35,26 +39,45 @@ impl InfoBar { match message { Message::InfoTraitChanged(val, _trait) => *character.info.get_mut(_trait) = val, Message::XSplatChanged(xsplat) => { - if xsplat.name().eq("") { - character.splat.set_xsplat(None); - } else { - character.splat.set_xsplat(Some(xsplat)); - } + character.splat.set_xsplat(Some(xsplat)); character.calc_mod_map(); } Message::YSplatChanged(ysplat) => { - if ysplat.name().eq("") { - character.splat.set_ysplat(None); - } else { - character.splat.set_ysplat(Some(ysplat)); - } + character.splat.set_ysplat(Some(ysplat)); //character.calc_mod_map(); } Message::ZSplatChanged(zsplat) => { - if zsplat.name().eq("") { + character.splat.set_zsplat(Some(zsplat)); + } + + Message::XSplatNameChanged(name) => { + if name.is_empty() { + character.splat.set_xsplat(None); + } else if let Some(mut xsplat) = character.splat.xsplat() { + if let Some(xsplat_name) = xsplat.name_mut() { + *xsplat_name = name; + character.splat.set_xsplat(Some(xsplat)); + } + } + } + Message::YSplatNameChanged(name) => { + if name.is_empty() { + character.splat.set_ysplat(None); + } else if let Some(mut ysplat) = character.splat.ysplat() { + if let Some(ysplat_name) = ysplat.name_mut() { + *ysplat_name = name; + character.splat.set_ysplat(Some(ysplat)); + } + } + } + Message::ZSplatNameChanged(name) => { + if name.is_empty() { character.splat.set_zsplat(None); - } else { - character.splat.set_zsplat(Some(zsplat)); + } else if let Some(mut zsplat) = character.splat.zsplat() { + if let Some(zsplat_name) = zsplat.name_mut() { + *zsplat_name = name; + character.splat.set_zsplat(Some(zsplat)); + } } } } @@ -97,18 +120,11 @@ impl InfoBar { let ysplat = character.splat.ysplat(); let zsplat = character.splat.zsplat(); - let xsplat: Element = if let Some(xsplat) = xsplat.clone() + let xsplat: Element = if let Some(xsplat) = &xsplat && xsplat.is_custom() { text_input("", xsplat.name()) - .on_input({ - let xsplat = xsplat.clone(); - move |val| { - let mut xsplat = xsplat.clone(); - *xsplat.name_mut().unwrap() = val; - Message::XSplatChanged(xsplat) - } - }) + .on_input(Message::XSplatNameChanged) .padding(INPUT_PADDING) .into() } else { @@ -122,18 +138,11 @@ impl InfoBar { .into() }; - let ysplat: Element = if let Some(ysplat) = ysplat.clone() + let ysplat: Element = if let Some(ysplat) = &ysplat && ysplat.is_custom() { text_input("", ysplat.name()) - .on_input({ - let ysplat = ysplat.clone(); - move |val| { - let mut ysplat = ysplat.clone(); - *ysplat.name_mut().unwrap() = val; - Message::YSplatChanged(ysplat) - } - }) + .on_input(Message::YSplatNameChanged) .padding(INPUT_PADDING) .into() } else { @@ -147,18 +156,11 @@ impl InfoBar { .into() }; - let zsplat: Element = if let Some(zsplat) = zsplat.clone() + let zsplat: Element = if let Some(zsplat) = &zsplat && zsplat.is_custom() { text_input("", zsplat.name()) - .on_input({ - let zsplat = zsplat.clone(); - move |val| { - let mut zsplat = zsplat.clone(); - *zsplat.name_mut().unwrap() = val; - Message::ZSplatChanged(zsplat) - } - }) + .on_input(Message::ZSplatNameChanged) .padding(INPUT_PADDING) .into() } else { diff --git a/src/component/mod.rs b/src/component/mod.rs index c3762cd..1162fcd 100644 --- a/src/component/mod.rs +++ b/src/component/mod.rs @@ -5,7 +5,7 @@ pub mod integrity; mod list; pub mod merits; pub mod skills; -mod traits; +pub mod traits; pub use attributes::AttributeBar; pub use forms::FormsComponent; @@ -13,4 +13,4 @@ pub use integrity::IntegrityComponent; pub use list::list; pub use merits::MeritComponent; pub use skills::SkillsComponent; -pub use traits::traits_component; +pub use traits::TraitsComponent; diff --git a/src/component/traits.rs b/src/component/traits.rs index 5303c7c..e6816a4 100644 --- a/src/component/traits.rs +++ b/src/component/traits.rs @@ -1,133 +1,96 @@ -use cofd::{character::ArmorStruct, prelude::*}; +use cofd::prelude::*; +use cofd::traits::DerivedTrait; use iced::{ - widget::{column, component, row, text, text_input, Component}, + widget::{column, row, text, text_input}, Length, }; -use crate::{fl, Element, INPUT_PADDING}; +use crate::{fl, i18n, Element, INPUT_PADDING}; -struct Traits { - size: u16, - speed: u16, - defense: u16, - armor: ArmorStruct, - initiative: u16, - beats: u16, - alternate_beats: u16, - alternate_experience: u16, - experience: u16, - - alt_opt: bool, - splat: String, - // alt_name: Option, -} - -pub struct TraitsComponent { - traits: Traits, - on_change: Box Message>, -} - -pub fn traits_component( - character: &Character, - on_change: impl Fn(u16, Trait) -> Message + 'static, -) -> TraitsComponent { - TraitsComponent::new(character, on_change) -} +#[derive(Debug, Clone)] +pub struct TraitsComponent; #[derive(Clone)] -pub struct Event(u16, Trait); - -impl TraitsComponent { - fn new(character: &Character, on_change: impl Fn(u16, Trait) -> Message + 'static) -> Self { - Self { - traits: Traits { - size: character.size(), - speed: character.speed(), - defense: character.defense(), - initiative: character.initative(), - beats: character.beats, - experience: character.experience(), - alternate_beats: character.alternate_beats, - alternate_experience: character.alternate_experience(), - armor: character.armor(), +pub struct Message(u16, Trait); - // alt_opt: character.splat.alternate_beats_optional(), - alt_opt: true, //TODO: FIX - splat: character.splat.name().to_string(), - // alt_name: character.splat.alternate_beats().map(|el| el.to_string()), - }, - on_change: Box::new(on_change), - } +impl TraitsComponent { + pub fn new() -> Self { + Self } -} -impl Component for TraitsComponent -where - Theme: text::StyleSheet + text_input::StyleSheet + 'static, -{ - type State = (); - type Event = Event; + pub fn update(&mut self, message: Message, character: &mut Character) { + let Message(val, _trait) = message; - fn update(&mut self, _state: &mut Self::State, event: Event) -> Option { - Some((self.on_change)(event.0, event.1)) + match _trait { + Trait::DerivedTrait(DerivedTrait::Size) => { + character.base_size = (val as i16 + - character.get_modifier(Trait::DerivedTrait(DerivedTrait::Size))) + as u16; + } + Trait::Willpower => character.willpower = val, + Trait::Power => character.power = val, + Trait::Fuel => character.fuel = val, + Trait::Integrity => character.integrity = val, + Trait::Beats => character.beats = val, + Trait::AlternateBeats => character.alternate_beats = val, + _ => {} + } } - fn view(&self, _state: &Self::State) -> Element { + pub fn view(&self, character: &Character) -> Element { let beats = row![ text(format!("{}:", fl!("beats"))), - text_input("", &format!("{}", self.traits.beats)) - .on_input(|val| { Event(val.parse().unwrap_or(0), Trait::Beats) }) + text_input("", &format!("{}", character.beats)) + .on_input(|val| { Message(val.parse().unwrap_or(0), Trait::Beats) }) .padding(INPUT_PADDING) ]; - let alternate_beats = if self.traits.alt_opt { + let alternate_beats = if character.splat.alternate_beats_optional() { row![] } else { - // TODO: Fix + let name = i18n::LANGUAGE_LOADER.get(&format!( + "{}-experience", + character.splat.alternate_beats().unwrap() + )); + row![ - // text(format!( - // "{}:", - // flt(&self.traits.splat, Some("beats")).unwrap() - // )), - // text_input("", &format!("{}", self.traits.alternate_beats)) - // .on_input(|val| { Event(val.parse().unwrap_or(0), Trait::AlternateBeats) }) - // .padding(INPUT_PADDING) + text(format!("{name}:")), + text_input("", &format!("{}", character.alternate_beats)) + .on_input(|val| { Message(val.parse().unwrap_or(0), Trait::AlternateBeats) }) + .padding(INPUT_PADDING) ] }; - let alternate_xp = if self.traits.alt_opt { + let alternate_xp = if character.splat.alternate_beats_optional() { row![] } else { - row![ - // text(format!( - // "{}: {}", - // flt(&self.traits.splat, Some("experience")).unwrap(), - // self.traits.alternate_experience - // )), - ] + let name = i18n::LANGUAGE_LOADER.get(&format!( + "{}-beats", + character.splat.alternate_beats().unwrap() + )); + + row![text(format!( + "{name}: {}", + character.alternate_experience() + ))] }; + let armor = character.armor(); column![ row![ - text(format!("{}: {}", fl!("size"), self.traits.size)), + text(format!("{}: {}", fl!("size"), character.size())), // text_input("", &format!("{}", self.traits.size), |val| { // Event(val, Trait::Size) // }) ], - row![ - text(format!("{}: {}", fl!("speed"), self.traits.speed)), - // text(self.traits.speed) - ], - row![ - text(format!("{}: {}", fl!("defense"), self.traits.defense)), - // text(self.traits.defense) - ], + row![text(format!("{}: {}", fl!("speed"), character.speed())),], + row![text(format!("{}: {}", fl!("defense"), character.defense())),], row![ text(format!( "{}: {}/{}", fl!("armor"), - self.traits.armor.general, - self.traits.armor.ballistic + armor.general, + armor.ballistic )), // text_input("", &format!("{}", self.traits.beats), |val| { // // if let Some(val) = val.parse() { @@ -141,15 +104,17 @@ where // // } // }) ], - row![ - text(format!("{}: {}", fl!("initiative"), self.traits.initiative)), - // text(self.traits.initative) - ], + row![text(format!( + "{}: {}", + fl!("initiative"), + character.initiative() + )),], beats, - row![ - text(format!("{}: {}", fl!("experience"), self.traits.experience)), - // text(self.traits.experience) - ], + row![text(format!( + "{}: {}", + fl!("experience"), + character.experience() + )),], alternate_beats, alternate_xp ] @@ -158,13 +123,3 @@ where .into() } } - -impl<'a, Message, Theme> From> for Element<'a, Message, Theme> -where - Message: 'a, - Theme: text::StyleSheet + text_input::StyleSheet + 'static, -{ - fn from(traits_component: TraitsComponent) -> Self { - component(traits_component) - } -} diff --git a/src/view/overview.rs b/src/view/overview.rs index a94dd6d..21ad1f2 100644 --- a/src/view/overview.rs +++ b/src/view/overview.rs @@ -20,8 +20,8 @@ use iced::{ use crate::{ component::{ - attributes, info, info::InfoBar, integrity, list, merits, skills, traits_component, - AttributeBar, IntegrityComponent, MeritComponent, SkillsComponent, + attributes, info, info::InfoBar, integrity, list, merits, skills, traits, AttributeBar, + IntegrityComponent, MeritComponent, SkillsComponent, TraitsComponent, }, fl, i18n, i18n::{Translate, Translated}, @@ -38,12 +38,12 @@ pub struct OverviewTab { attribute_bar: AttributeBar, skills_component: SkillsComponent, merit_component: MeritComponent, + traits_component: TraitsComponent, integrity_component: IntegrityComponent, } #[derive(Clone)] pub enum Message { - TraitChanged(u16, Trait), // InfoTraitChanged(String, InfoTrait), // XSplatChanged(XSplat), // YSplatChanged(YSplat), @@ -53,6 +53,10 @@ pub enum Message { // CustomAbilityChanged(Ability, String), HealthChanged(Wound), + WillpowerChanged(u16), + PowerChanged(u16), + FuelChanged(u16), + // IntegrityDamage(SplatType, Wound), // TouchstoneChanged(usize, String), ConditionChanged(usize, String), @@ -69,6 +73,7 @@ pub enum Message { AttributeBar(attributes::Message), SkillComponent(skills::Message), MeritComponent(merits::Message), + TraitsComponent(traits::Message), IntegrityComponent(integrity::Message), } @@ -88,6 +93,7 @@ impl OverviewTab { attribute_bar: AttributeBar::new(), skills_component: SkillsComponent::new(), merit_component: MeritComponent::new(), + traits_component: TraitsComponent::new(), integrity_component: IntegrityComponent::new(), } } @@ -115,21 +121,12 @@ impl OverviewTab { character.add_ability(ability, 0); } } - Message::TraitChanged(val, _trait) => match _trait { - Trait::DerivedTrait(DerivedTrait::Size) => { - character.base_size = (val as i16 - - character.get_modifier(Trait::DerivedTrait(DerivedTrait::Size))) - as u16; - } - Trait::Willpower => character.willpower = val, - Trait::Power => character.power = val, - Trait::Fuel => character.fuel = val, - Trait::Integrity => character.integrity = val, - Trait::Beats => character.beats = val, - Trait::AlternateBeats => character.alternate_beats = val, - _ => {} - }, + Message::HealthChanged(wound) => character.health_mut().poke(&wound), + Message::WillpowerChanged(willpower) => character.willpower = willpower, + Message::PowerChanged(power) => character.power = power, + Message::FuelChanged(fuel) => character.fuel = fuel, + Message::ConditionChanged(i, val) => { if val.is_empty() { character.conditions.remove(i); @@ -204,6 +201,7 @@ impl OverviewTab { Message::AttributeBar(message) => self.attribute_bar.update(message, character), Message::SkillComponent(message) => self.skills_component.update(message, character), Message::MeritComponent(message) => self.merit_component.update(message, character), + Message::TraitsComponent(message) => self.traits_component.update(message, character), Message::IntegrityComponent(message) => { self.integrity_component.update(message, character); } @@ -237,7 +235,7 @@ impl OverviewTab { character.max_willpower(), Shape::Dots, None, - |val| Message::TraitChanged(val, Trait::Willpower), + Message::WillpowerChanged, ); column![text(fl!("willpower")).size(H3_SIZE), dots] @@ -246,9 +244,14 @@ impl OverviewTab { }; let st = if let Some(st) = character.splat.supernatural_tolerance() { - let dots = SheetDots::new(character.power, 1, 10, Shape::Dots, None, |val| { - Message::TraitChanged(val, Trait::Power) - }); + let dots = SheetDots::new( + character.power, + 1, + 10, + Shape::Dots, + None, + Message::PowerChanged, + ); column![text(st.translated()).size(H3_SIZE), dots] .spacing(TITLE_SPACING) @@ -264,7 +267,7 @@ impl OverviewTab { character.max_fuel(), Shape::Boxes, Some(10), - |val| Message::TraitChanged(val, Trait::Fuel), + Message::FuelChanged, ); column![text(fuel.translated()).size(H3_SIZE), boxes] @@ -410,7 +413,10 @@ impl OverviewTab { .merit_component .view(character) .map(Message::MeritComponent); - let traits = traits_component(character, Message::TraitChanged); + let traits = self + .traits_component + .view(character) + .map(Message::TraitsComponent); let regalia = if let Splat::Changeling(data) = &character.splat { let favoured_regalia = data.seeming.get_favored_regalia(); diff --git a/src/widget/track.rs b/src/widget/track.rs index 9861118..442a528 100644 --- a/src/widget/track.rs +++ b/src/widget/track.rs @@ -70,8 +70,8 @@ where #[allow(clippy::cast_precision_loss)] fn layout( &self, - tree: &mut widget::Tree, - renderer: &Renderer, + _tree: &mut widget::Tree, + _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { let size = Size::new(self.size, self.size);