diff --git a/SatisfactorySaveEditor/Converter/SaveNodeItemToStringConverter.cs b/SatisfactorySaveEditor/Converter/SaveNodeItemToStringConverter.cs index bd4498f..d6e5bdc 100644 --- a/SatisfactorySaveEditor/Converter/SaveNodeItemToStringConverter.cs +++ b/SatisfactorySaveEditor/Converter/SaveNodeItemToStringConverter.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Windows.Data; using SatisfactorySaveEditor.Model; @@ -11,21 +13,46 @@ public object Convert(object value, Type targetType, object parameter, CultureIn { if (!(value is SaveObjectModel saveNodeItem)) return string.Empty; + var totalCount = Traverse(saveNodeItem.Items, obj => obj.Items).Count(obj => obj.Items.Count == 0); var count = saveNodeItem.Items.Count; + string formatString; + switch (count) { case 0: return $"{saveNodeItem.Title}"; case 1: - return $"{saveNodeItem.Title} (1 entry)"; + formatString = $"{saveNodeItem.Title} (1 entry, "; + break; + default: + formatString = $"{saveNodeItem.Title} ({count} entries, "; + break; } - return $"{saveNodeItem.Title} ({count} entries)"; + switch (totalCount) + { + case 1: + return formatString + $"{totalCount} object)"; + default: + return formatString + $"{totalCount} objects)"; + } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } + + public static IEnumerable Traverse(IEnumerable items, Func> childSelector) + { + var stack = new Stack(items); + + while (stack.Any()) + { + var next = stack.Pop(); + yield return next; + foreach (var child in childSelector(next)) stack.Push(child); + } + } } } diff --git a/SatisfactorySaveEditor/Converter/SerializablePropertyToTypeStringConverter.cs b/SatisfactorySaveEditor/Converter/SerializablePropertyToTypeStringConverter.cs index 9cfd4c6..fab2b73 100644 --- a/SatisfactorySaveEditor/Converter/SerializablePropertyToTypeStringConverter.cs +++ b/SatisfactorySaveEditor/Converter/SerializablePropertyToTypeStringConverter.cs @@ -2,6 +2,7 @@ using System.Globalization; using System.Windows.Data; using SatisfactorySaveEditor.ViewModel; +using SatisfactorySaveEditor.ViewModel.Property; using SatisfactorySaveParser.PropertyTypes; namespace SatisfactorySaveEditor.Converter @@ -12,29 +13,29 @@ public object Convert(object value, Type targetType, object parameter, CultureIn { switch (value) { - case ArrayProperty arp: + case ArrayPropertyViewModel arp: return $"Array ({AddViewModel.FromStringType(arp.Type)})"; - case BoolProperty bop: + case BoolPropertyViewModel bop: return "Boolean"; - case ByteProperty byp: + case BytePropertyViewModel byp: return "Byte"; - case EnumProperty enp: + case EnumPropertyViewModel enp: return "Enum"; - case FloatProperty flp: + case FloatPropertyViewModel flp: return "Float"; - case IntProperty inp: + case IntPropertyViewModel inp: return "Int"; - case MapProperty map: // heh + case MapPropertyViewModel map: // heh return "Map"; - case NameProperty nap: // THESE NAMES KEEP GETTING BETTER + case NamePropertyViewModel nap: // THESE NAMES KEEP GETTING BETTER return "Name"; - case ObjectProperty obp: + case ObjectPropertyViewModel obp: return "Object"; - case StrProperty strip: + case StrPropertyViewModel strip: return "String"; - case StructProperty strup: + case StructPropertyViewModel strup: return "Struct"; - case TextProperty tep: + case TextPropertyViewModel tep: return "text"; default: throw new ArgumentOutOfRangeException(nameof(value), value, null); diff --git a/SatisfactorySaveEditor/Model/SaveObjectModel.cs b/SatisfactorySaveEditor/Model/SaveObjectModel.cs index ade6265..0f1ec21 100644 --- a/SatisfactorySaveEditor/Model/SaveObjectModel.cs +++ b/SatisfactorySaveEditor/Model/SaveObjectModel.cs @@ -1,7 +1,9 @@ using System.Collections.ObjectModel; +using System.Linq; using GalaSoft.MvvmLight; +using SatisfactorySaveEditor.Util; +using SatisfactorySaveEditor.ViewModel.Property; using SatisfactorySaveParser; -using SatisfactorySaveParser.PropertyTypes; namespace SatisfactorySaveEditor.Model { @@ -13,7 +15,8 @@ public class SaveObjectModel : ObservableObject private bool isExpanded; public ObservableCollection Items { get; } = new ObservableCollection(); - public ObservableCollection Fields => Model.DataFields; + + public ObservableCollection Fields { get; } public string Title { @@ -46,6 +49,8 @@ public SaveObjectModel(SaveObject model) Model = model; Title = model.InstanceName; RootObject = model.RootObject; + + Fields = new ObservableCollection(Model.DataFields.Select(PropertyViewModelMapper.Convert)); } public SaveObjectModel(string title) @@ -92,6 +97,16 @@ public virtual void ApplyChanges() { item.ApplyChanges(); } + + // This is because the named only (pink) nodes aren't actually a valid object in the game + if (Model == null) return; + + Model.DataFields.Clear(); + foreach (var field in Fields) + { + field.ApplyChanges(); + Model.DataFields.Add(field.Model); + } } } } diff --git a/SatisfactorySaveEditor/SatisfactorySaveEditor.csproj b/SatisfactorySaveEditor/SatisfactorySaveEditor.csproj index b84416e..97b0a34 100644 --- a/SatisfactorySaveEditor/SatisfactorySaveEditor.csproj +++ b/SatisfactorySaveEditor/SatisfactorySaveEditor.csproj @@ -81,8 +81,22 @@ + + + + + + + + + + + + + + PropertiesControl.xaml diff --git a/SatisfactorySaveEditor/Util/PropertyViewModelMapper.cs b/SatisfactorySaveEditor/Util/PropertyViewModelMapper.cs new file mode 100644 index 0000000..8cccd5d --- /dev/null +++ b/SatisfactorySaveEditor/Util/PropertyViewModelMapper.cs @@ -0,0 +1,42 @@ +using System; +using SatisfactorySaveEditor.ViewModel.Property; +using SatisfactorySaveParser.PropertyTypes; + +namespace SatisfactorySaveEditor.Util +{ + public static class PropertyViewModelMapper + { + public static SerializedPropertyViewModel Convert(SerializedProperty property) + { + switch (property) + { + case ArrayProperty arp: + return new ArrayPropertyViewModel(arp); + case BoolProperty bop: + return new BoolPropertyViewModel(bop); + case ByteProperty byp: + return new BytePropertyViewModel(byp); + case EnumProperty enp: + return new EnumPropertyViewModel(enp); + case FloatProperty flp: + return new FloatPropertyViewModel(flp); + case IntProperty inp: + return new IntPropertyViewModel(inp); + case MapProperty map: + return new MapPropertyViewModel(map); + case NameProperty nap: + return new NamePropertyViewModel(nap); + case ObjectProperty obp: + return new ObjectPropertyViewModel(obp); + case StrProperty strip: + return new StrPropertyViewModel(strip); + case StructProperty strup: + return new StructPropertyViewModel(strup); + case TextProperty tep: + return new TextPropertyViewModel(tep); + default: + throw new ArgumentOutOfRangeException(nameof(property), property, null); + } + } + } +} diff --git a/SatisfactorySaveEditor/View/MainWindow.xaml b/SatisfactorySaveEditor/View/MainWindow.xaml index e6bb032..67ebf67 100644 --- a/SatisfactorySaveEditor/View/MainWindow.xaml +++ b/SatisfactorySaveEditor/View/MainWindow.xaml @@ -20,8 +20,16 @@ - - + + + False + + + + + True + + @@ -130,23 +138,23 @@ - - - - - - - - - + + + + + + + + + - - - + + + diff --git a/SatisfactorySaveEditor/View/PropertiesControl.xaml.cs b/SatisfactorySaveEditor/View/PropertiesControl.xaml.cs index 5a7c234..484d08d 100644 --- a/SatisfactorySaveEditor/View/PropertiesControl.xaml.cs +++ b/SatisfactorySaveEditor/View/PropertiesControl.xaml.cs @@ -2,7 +2,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; -using SatisfactorySaveParser.PropertyTypes; +using SatisfactorySaveEditor.ViewModel.Property; namespace SatisfactorySaveEditor.View { @@ -22,13 +22,13 @@ public ICommand AddPropertyCommand set => SetValue(AddPropertyCommandProperty, value); } - public ObservableCollection Properties + public ObservableCollection Properties { - get => (ObservableCollection)GetValue(PropertiesProperty); + get => (ObservableCollection)GetValue(PropertiesProperty); set => SetValue(PropertiesProperty, value); } public static readonly DependencyProperty AddPropertyCommandProperty = DependencyProperty.Register("AddPropertyCommand", typeof(ICommand), typeof(PropertiesControl)); - public static readonly DependencyProperty PropertiesProperty = DependencyProperty.Register("Properties", typeof(ObservableCollection), typeof(PropertiesControl)); + public static readonly DependencyProperty PropertiesProperty = DependencyProperty.Register("Properties", typeof(ObservableCollection), typeof(PropertiesControl)); } } diff --git a/SatisfactorySaveEditor/View/PropertyTemplateDictionary.xaml b/SatisfactorySaveEditor/View/PropertyTemplateDictionary.xaml index 786ab5d..e570e8b 100644 --- a/SatisfactorySaveEditor/View/PropertyTemplateDictionary.xaml +++ b/SatisfactorySaveEditor/View/PropertyTemplateDictionary.xaml @@ -1,9 +1,8 @@  - + xmlns:property="clr-namespace:SatisfactorySaveEditor.ViewModel.Property"> + @@ -18,31 +17,31 @@ -