XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

SpaceEngineersModDev/SpaceEngineersBlueprintEditorInWinUI

完成蓝图属性编辑

a6a074c
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

11 个文件 +243 -113
Added SpaceEngineersBlueprintEditor/Model/BlueprintGroupList.cs +6 -0
@@ -0,0 +1,6 @@
1 namespace SpaceEngineersBlueprintEditor.Model;
2
3 public partial class BlueprintGroupList(IEnumerable<BlueprintPropertyViewData> collection) : List<BlueprintPropertyViewData>(collection)
4 {
5 public required string GroupName { get; set; }
6 }
Modified SpaceEngineersBlueprintEditor/Model/BlueprintPropertyViewData.cs +39 -4
@@ -2,6 +2,7 @@
2 2 using Microsoft.UI.Xaml.Media;
3 3 using SpaceEngineersBlueprintEditor.ViewModels;
4 4 using System.Collections;
5 using System.Reflection;
5 6 using XFEExtension.NetCore.XFETransform;
6 7
7 8 namespace SpaceEngineersBlueprintEditor.Model;
@@ -12,15 +13,49 @@ public partial class BlueprintPropertyViewData : ViewModelBase
12 13 private object? value;
13 14 [ObservableProperty]
14 15 private string? valueInString;
16 [ObservableProperty]
17 private object? customData;
15 18 public Type? Type { get; set; }
16 19 public string? Name { get; set; }
17 public string? CustomName { get; set; }
20 public string[] EnumValues => Type is not null ? Type.IsEnum ? Enum.GetNames(Type) : ["True", "False"] : [];
18 21 public BlueprintPropertyViewData? Parent { get; set; }
19 22 public ImageSource? CubeImage { get; set; }
20 23 public List<BlueprintPropertyViewData> Children { get; set; } = [];
21 24 public bool IsEnumerable => Type is not null && Type.IsAssignableTo(typeof(IEnumerable)) && Type != typeof(string);
22 public bool IsBasicType => Type is not null && (XFEConverter.IsBasicType(Type) || Type.IsAssignableTo(typeof(Enum)));
23 public bool IsNotBasicType => !IsBasicType;
25 public bool IsMultiEnum => Type is not null && Type.IsDefined(typeof(FlagsAttribute), false);
26 public bool IsBasicType => Type is not null && (XFEConverter.IsBasicType(Type) || Type.IsEnum);
27
28 partial void OnValueChanged(object? value)
29 {
30 try
31 {
32 ValueInString = Value?.ToString();
33 if (Type is null || value is null)
34 return;
35 if (Type.IsEnum && ValueInString is not null)
36 SetValue(this, Enum.Parse(Type, ValueInString));
37 else
38 SetValue(this, Convert.ChangeType(value, Type));
39 }
40 catch { }
41 }
24 42
25 partial void OnValueChanged(object? value) => ValueInString = string.IsNullOrEmpty(Value?.ToString()) ? "值为空" : Value?.ToString();
43 private static void SetValue(BlueprintPropertyViewData blueprintPropertyViewData, object? targetValue)
44 {
45 if (blueprintPropertyViewData.Parent is not null && blueprintPropertyViewData.Name is not null && blueprintPropertyViewData.Parent.Type is not null)
46 {
47 var memberInfoList = blueprintPropertyViewData.Parent.Type.GetMember(blueprintPropertyViewData.Name);
48 foreach (var memberInfo in memberInfoList)
49 {
50 if (memberInfo is FieldInfo fieldInfo)
51 {
52 fieldInfo.SetValue(blueprintPropertyViewData.Parent.Value, targetValue);
53 }
54 else if (memberInfo is PropertyInfo propertyInfo)
55 {
56 propertyInfo.SetValue(blueprintPropertyViewData.Parent.Value, targetValue);
57 }
58 }
59 }
60 }
26 61 }
Added SpaceEngineersBlueprintEditor/Utilities/Converter/BaseTypeConverter.cs +19 -0
@@ -0,0 +1,19 @@
1 using Microsoft.UI.Xaml.Data;
2
3 namespace SpaceEngineersBlueprintEditor.Utilities.Converter;
4
5 public partial class BaseTypeConverter : IValueConverter
6 {
7 public object? Convert(object value, Type targetType, object parameter, string language)
8 {
9 if (value is null)
10 return null;
11 else if (value.GetType().IsEnum)
12 return value.ToString();
13 else if (value.GetType() == typeof(bool))
14 return value.ToString();
15 return System.Convert.ChangeType(value?.ToString(), targetType);
16 }
17
18 public object? ConvertBack(object value, Type targetType, object parameter, string language) => value;
19 }
Modified SpaceEngineersBlueprintEditor/Utilities/Helpers/SpaceEngineersHelper.cs +34 -6
@@ -1,4 +1,5 @@
1 using Microsoft.UI.Xaml.Media.Imaging;
1 using Microsoft.UI.Xaml.Controls;
2 using Microsoft.UI.Xaml.Media.Imaging;
2 3 using Microsoft.Win32;
3 4 using Sandbox.Definitions;
4 5 using SpaceEngineersBlueprintEditor.Model;
@@ -35,25 +36,29 @@ public static class SpaceEngineersHelper
35 36 {
36 37 type = fieldInfo.FieldType;
37 38 var value = fieldInfo.GetValue(blueprintPropertyViewData.Value);
38 blueprintPropertyViewData.Children.Add(new()
39 var child = new BlueprintPropertyViewData()
39 40 {
40 41 Type = type,
41 42 Name = fieldInfo.Name,
42 43 Value = value,
43 44 Parent = blueprintPropertyViewData
44 });
45 };
46 SetDetail(child, value);
47 blueprintPropertyViewData.Children.Add(child);
45 48 }
46 49 else if (member is PropertyInfo propertyInfo && !exceptedName.Contains(propertyInfo.Name) && propertyInfo.CanWrite && propertyInfo.IsMemberPublic())
47 50 {
48 51 type = propertyInfo.PropertyType;
49 52 var value = propertyInfo.GetValue(blueprintPropertyViewData.Value);
50 blueprintPropertyViewData.Children.Add(new()
53 var child = new BlueprintPropertyViewData()
51 54 {
52 55 Type = type,
53 56 Name = propertyInfo.Name,
54 57 Value = value,
55 58 Parent = blueprintPropertyViewData
56 });
59 };
60 SetDetail(child, value);
61 blueprintPropertyViewData.Children.Add(child);
57 62 }
58 63 }
59 64 catch (Exception ex)
@@ -116,12 +121,35 @@ public static class SpaceEngineersHelper
116 121 var cubeBlock = MyDefinitionManager.Static.GetCubeBlockDefinition(myObjectBuilder_CubeBlock);
117 122 blueprintPropertyViewData.Name = cubeBlock.DisplayNameText;
118 123 blueprintPropertyViewData.CubeImage = new BitmapImage(new(@$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(cubeBlock.Icons[0], "png")}"));
119 blueprintPropertyViewData.CustomName = value is MyObjectBuilder_TerminalBlock myObjectBuilder_TerminalBlock ? myObjectBuilder_TerminalBlock.CustomName : string.Empty;
124 blueprintPropertyViewData.CustomData = value is MyObjectBuilder_TerminalBlock myObjectBuilder_TerminalBlock ? myObjectBuilder_TerminalBlock.CustomName : string.Empty;
120 125 }
121 126 else if (value is MyObjectBuilder_CubeGrid myObjectBuilder_CubeGrid)
122 127 {
123 128 blueprintPropertyViewData.Name = myObjectBuilder_CubeGrid.DisplayName;
124 129 }
130 else if (blueprintPropertyViewData.IsMultiEnum)
131 {
132 var stackPanel = new StackPanel
133 {
134 DataContext = blueprintPropertyViewData
135 };
136 foreach (var enumItem in blueprintPropertyViewData.EnumValues)
137 {
138 stackPanel.Children.Add(new CheckBox
139 {
140 Content = enumItem,
141 IsChecked = blueprintPropertyViewData.Value?.ToString()?.Contains(enumItem)
142 });
143 }
144 blueprintPropertyViewData.CustomData = stackPanel;
145 }
146 else if (value is not null && value.GetType().IsAssignableTo(typeof(IEnumerable)))
147 {
148 var count = 0;
149 foreach (var item in (IEnumerable)value)
150 count++;
151 blueprintPropertyViewData.CustomData = $"数量:{count}";
152 }
125 153 }
126 154
127 155 public static async Task LoadDefinitionViewDataListAsync()
Modified SpaceEngineersBlueprintEditor/Utilities/Selector/ShipBlueprintItemTemplateSelector.cs +17 -2
@@ -10,14 +10,29 @@ public partial class ShipBlueprintItemTemplateSelector : DataTemplateSelector
10 10 public DataTemplate? GridItemTemplate { get; set; }
11 11 public DataTemplate? ObjectItemTemplate { get; set; }
12 12 public DataTemplate? EnumerableTemplate { get; set; }
13 public DataTemplate? ValueItemTemplate { get; set; }
13 public DataTemplate? StringValueItemTemplate { get; set; }
14 public DataTemplate? NumberValueItemTemplate { get; set; }
15 public DataTemplate? EnumValueItemTemplate { get; set; }
16 public DataTemplate? MultiEnumValueItemTemplate { get; set; }
17 public DataTemplate? BooleanValueItemTemplate { get; set; }
14 18
15 19 protected override DataTemplate? SelectTemplateCore(object item)
16 20 {
17 21 if (item is TreeViewNode treeViewNode && treeViewNode.Content is BlueprintPropertyViewData blueprintPropertyViewData)
18 22 {
19 23 if (blueprintPropertyViewData.IsBasicType)
20 return ValueItemTemplate;
24 {
25 if (blueprintPropertyViewData.Type == typeof(string))
26 return StringValueItemTemplate;
27 if (blueprintPropertyViewData.Type == typeof(bool))
28 return BooleanValueItemTemplate;
29 else if (blueprintPropertyViewData.IsMultiEnum)
30 return MultiEnumValueItemTemplate;
31 else if (blueprintPropertyViewData.Type is not null && blueprintPropertyViewData.Type.IsEnum)
32 return EnumValueItemTemplate;
33 else
34 return NumberValueItemTemplate;
35 }
21 36 else if (blueprintPropertyViewData.IsEnumerable)
22 37 return EnumerableTemplate;
23 38 else if (blueprintPropertyViewData.Type is not null)
Modified SpaceEngineersBlueprintEditor/ViewModels/BlueprintDetailPageViewModel.cs +6 -4
@@ -46,7 +46,12 @@ public partial class BlueprintDetailPageViewModel : ViewModelBase
46 46 private async void NavigationParameterService_ParameterChange(object? sender, BlueprintInfoViewData e)
47 47 {
48 48 if (navigationViewService is not null) navigationViewService.Header = e.Name;
49 if (currentBlueprintInfoViewData == e) return;
49 await Helper.Wait(() => SpaceEngineersHelper.IsLoadComplete);
50 if (currentBlueprintInfoViewData != e)
51 {
52 currentBlueprintInfoViewData = e;
53 await LoadBlueprintAsync();
54 }
50 55 AuthorName = "蓝图作者:加载中...";
51 56 BlueprintFileSize = "蓝图大小:加载中...";
52 57 BlueprintPath = "蓝图路径:加载中...";
@@ -58,7 +63,6 @@ public partial class BlueprintDetailPageViewModel : ViewModelBase
58 63 CubeGridList.Clear();
59 64 ComponentList.Clear();
60 65 IsProgressRingVisible = true;
61 currentBlueprintInfoViewData = e;
62 66 if (e.NoBlueprint)
63 67 {
64 68 messageService?.ShowMessage("该蓝图不包含蓝图文件(bp.sbc)", "警告", InfoBarSeverity.Warning);
@@ -67,8 +71,6 @@ public partial class BlueprintDetailPageViewModel : ViewModelBase
67 71 IsProgressRingVisible = false;
68 72 return;
69 73 }
70 await Helper.Wait(() => SpaceEngineersHelper.IsLoadComplete);
71 await LoadBlueprintAsync();
72 74 if (currentBlueprint is not null)
73 75 {
74 76 AuthorName = $"蓝图作者:{currentBlueprint.DisplayName}(Steam ID: {currentBlueprint.OwnerSteamId})";
Modified SpaceEngineersBlueprintEditor/ViewModels/BlueprintEditPageViewModel.cs +15 -66
@@ -18,19 +18,25 @@ public partial class BlueprintEditPageViewModel : ViewModelBase
18 18 [ObservableProperty]
19 19 private string? editValueText;
20 20 [ObservableProperty]
21 private string? selectedEditEnum;
22 [ObservableProperty]
21 23 private TreeViewNode? selectedTreeViewNode;
22 24 private BlueprintModel? currentParameter;
23 25 private MyObjectBuilder_Definitions? currentDefinitions;
24 26 private MyObjectBuilder_ShipBlueprintDefinition? currentShipBlueprint;
25 27 private readonly IMessageService? messageService = GlobalServiceManager.GetService<IMessageService>();
26 28 private readonly INavigationViewService? navigationViewService = GlobalServiceManager.GetService<INavigationViewService>();
27 public ObservableCollection<TreeViewNode> BlueprintPropertyNodeList { get; set; } = [];
28 public ObservableCollection<BlueprintPropertyViewData> ShipGridPropertyList { get; set; } = [];
29 public ObservableCollection<string> EditValueEnumList { get; set; } = [];
29 30 public IBackgroundImageService? BackgroundImageService { get; set; } = GlobalServiceManager.GetService<IBackgroundImageService>();
30 31 public INavigationParameterService<BlueprintModel> NavigationParameterService { get; set; } = new NavigationParameterService<BlueprintModel>();
31 32 public IDialogService DialogService { get; set; } = new DialogService();
32 33 public BlueprintEditPageViewModel() => NavigationParameterService.ParameterChange += NavigationParameterService_ParameterChange;
33 34
35 partial void OnSelectedTreeViewNodeChanged(TreeViewNode? value)
36 {
37
38 }
39
34 40 private void NavigationParameterService_ParameterChange(object? sender, BlueprintModel e)
35 41 {
36 42 if (e.BlueprintDefinitions is not null)
@@ -41,57 +47,24 @@ public partial class BlueprintEditPageViewModel : ViewModelBase
41 47 if (currentDefinitions.ShipBlueprints is not null && currentDefinitions.ShipBlueprints.Length > 0)
42 48 {
43 49 currentShipBlueprint = currentDefinitions.ShipBlueprints[0];
44 var memberInfoList = currentShipBlueprint.GetType().GetMembers();
45 50 var parent = new BlueprintPropertyViewData
46 51 {
47 52 Value = currentShipBlueprint,
48 53 Name = "飞船蓝图",
49 54 Type = currentShipBlueprint.GetType()
50 55 };
51 foreach (var memberInfo in memberInfoList)
56 SpaceEngineersHelper.AnalyzeBlueprint(parent);
57 foreach (var child in parent.Children)
52 58 {
53 if (memberInfo is FieldInfo fieldInfo && fieldInfo.IsPublic)
54 {
55 var blueprintPropertyViewData = new BlueprintPropertyViewData()
56 {
57 Type = fieldInfo.FieldType,
58 Name = memberInfo.Name,
59 Parent = parent,
60 Value = fieldInfo.GetValue(currentShipBlueprint)
61 };
62 var node = new TreeViewNode
63 {
64 Content = blueprintPropertyViewData,
65 HasUnrealizedChildren = blueprintPropertyViewData.IsNotBasicType
66 };
67 BlueprintEditPage.Current?.propertyTreeView.RootNodes.Add(node);
68 }
69 else if (memberInfo is PropertyInfo propertyInfo && propertyInfo.CanWrite && propertyInfo.IsMemberPublic())
59 BlueprintEditPage.Current?.propertyTreeView.RootNodes.Add(new TreeViewNode
70 60 {
71 var blueprintPropertyViewData = new BlueprintPropertyViewData()
72 {
73 Type = propertyInfo.PropertyType,
74 Name = memberInfo.Name,
75 Parent = parent,
76 Value = propertyInfo.GetValue(currentShipBlueprint)
77 };
78 var node = new TreeViewNode
79 {
80 Content = blueprintPropertyViewData,
81 HasUnrealizedChildren = blueprintPropertyViewData.IsNotBasicType
82 };
83 BlueprintEditPage.Current?.propertyTreeView.RootNodes.Add(node);
84 }
61 Content = child,
62 HasUnrealizedChildren = !child.IsBasicType
63 });
85 64 }
86 65 foreach (var grid in currentShipBlueprint.CubeGrids)
87 66 {
88 67 var type = grid.GetType();
89 ShipGridPropertyList.Add(new()
90 {
91 Type = type,
92 Name = grid.DisplayName,
93 Value = grid
94 });
95 68 }
96 69 }
97 70 else
@@ -143,30 +116,6 @@ public partial class BlueprintEditPageViewModel : ViewModelBase
143 116 default:
144 117 break;
145 118 }
146 }
147
148 [RelayCommand]
149 void Add()
150 {
151
152 }
153
154 [RelayCommand]
155 async Task Edit()
156 {
157 if (SelectedTreeViewNode is not null && SelectedTreeViewNode.Content is BlueprintPropertyViewData blueprintPropertyViewData)
158 {
159 EditValueText = blueprintPropertyViewData.ValueInString;
160 if (blueprintPropertyViewData.Parent is not null && blueprintPropertyViewData.Name is not null && blueprintPropertyViewData.Parent.Type is not null && await DialogService.ShowDialog("editValueContentDialog") == ContentDialogResult.Primary)
161 {
162 blueprintPropertyViewData.Parent.Type.GetMember(blueprintPropertyViewData.Name)
163 }
164 }
165 }
166
167 [RelayCommand]
168 void Delete()
169 {
170
119 messageService?.ShowMessage("转换完成", "完成", InfoBarSeverity.Success);
171 120 }
172 121 }
Modified SpaceEngineersBlueprintEditor/ViewModels/BlueprintsViewPageViewModel.cs +1 -5
@@ -48,11 +48,7 @@ public partial class BlueprintsViewPageViewModel : ViewModelBase
48 48
49 49 private void LoadCurrentBlueprints() => LoadBlueprints(GetCurrentBlueprints(currentParameter));
50 50
51 private void LoadBlueprints(List<BlueprintInfo> blueprintInfoList)
52 {
53 foreach (var info in blueprintInfoList)
54 BlueprintInfoViewDataList.Add(info.ToBlueprintInfoViewData());
55 }
51 private void LoadBlueprints(List<BlueprintInfo> blueprintInfoList) => blueprintInfoList.ForEach(info => BlueprintInfoViewDataList.Add(info.ToBlueprintInfoViewData()));
56 52
57 53 private async void NavigationParameterService_ParameterChange(object? sender, object e)
58 54 {
Modified SpaceEngineersBlueprintEditor/ViewModels/GameDefinitionsViewPageViewModel.cs +3 -4
@@ -7,6 +7,7 @@ using SpaceEngineersBlueprintEditor.Model;
7 7 using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
8 8 using SpaceEngineersBlueprintEditor.Utilities;
9 9 using System.Collections.ObjectModel;
10 using System.Linq;
10 11 using VRage.Game;
11 12
12 13 namespace SpaceEngineersBlueprintEditor.ViewModels;
@@ -105,14 +106,12 @@ public partial class GameDefinitionsViewPageViewModel : ViewModelBase
105 106 partial void OnSearchTextChanged(string value)
106 107 {
107 108 Definitions.Clear();
108 foreach (var definition in SearchDefinitions(value))
109 Definitions.Add(definition);
109 SearchDefinitions(value).ForEach(Definitions.Add);
110 110 }
111 111
112 112 partial void OnPropertiesSearchTextChanged(string value)
113 113 {
114 114 PropertiesInfo.Clear();
115 foreach (var property in SearchProperties(value))
116 PropertiesInfo.Add(property);
115 SearchProperties(value).ForEach(PropertiesInfo.Add);
117 116 }
118 117 }
Modified SpaceEngineersBlueprintEditor/Views/BlueprintEditPage.xaml +82 -21
@@ -5,11 +5,13 @@
5 5 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6 6 xmlns:local="using:SpaceEngineersBlueprintEditor.Views"
7 7 xmlns:model="using:SpaceEngineersBlueprintEditor.Model"
8 xmlns:converter="using:SpaceEngineersBlueprintEditor.Utilities.Converter"
8 9 xmlns:selector="using:SpaceEngineersBlueprintEditor.Utilities.Selector"
9 10 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
10 11 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
11 12 mc:Ignorable="d">
12 13 <Page.Resources>
14 <converter:BaseTypeConverter x:Key="BaseTypeConverter"/>
13 15 <DataTemplate x:Key="TreeViewItemDataTemplate" x:DataType="TreeViewNode">
14 16 <Grid Padding="0,0,5,0" Height="44">
15 17 <Grid.ColumnDefinitions>
@@ -24,10 +26,17 @@
24 26 </Grid>
25 27 </DataTemplate>
26 28 <DataTemplate x:Key="EnumerableItemDataTemplate" x:DataType="TreeViewNode">
27 <StackPanel Orientation="Horizontal" Height="44" Spacing="20">
28 <FontIcon VerticalAlignment="Center" Glyph="&#xE8FD;"/>
29 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
30 </StackPanel>
29 <Grid Padding="0,0,5,0" Height="44">
30 <Grid.ColumnDefinitions>
31 <ColumnDefinition Width="*"/>
32 <ColumnDefinition Width="Auto"/>
33 </Grid.ColumnDefinitions>
34 <StackPanel Orientation="Horizontal" Spacing="20">
35 <FontIcon VerticalAlignment="Center" Glyph="&#xE8FD;"/>
36 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
37 </StackPanel>
38 <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).CustomData, Mode=OneWay}" Grid.Column="1" Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
39 </Grid>
31 40 </DataTemplate>
32 41 <DataTemplate x:Key="GridItemDataTemplate" x:DataType="TreeViewNode">
33 42 <StackPanel Orientation="Horizontal" Height="44" Spacing="20">
@@ -41,17 +50,73 @@
41 50 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
42 51 </StackPanel>
43 52 </DataTemplate>
44 <DataTemplate x:Key="ValueItemDataTemplate" x:DataType="TreeViewNode">
53 <DataTemplate x:Key="StringValueItemDataTemplate" x:DataType="TreeViewNode">
45 54 <Grid Padding="0,0,5,0" Height="44">
46 55 <Grid.ColumnDefinitions>
47 56 <ColumnDefinition Width="*"/>
48 <ColumnDefinition Width="150"/>
57 <ColumnDefinition Width="120"/>
49 58 </Grid.ColumnDefinitions>
50 59 <StackPanel Orientation="Horizontal" Spacing="20">
51 60 <FontIcon VerticalAlignment="Center" Glyph="&#xE90F;"/>
52 61 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
53 62 </StackPanel>
54 <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" TextTrimming="CharacterEllipsis" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).ValueInString, Mode=OneWay}" Grid.Column="1" Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
63 <TextBox VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Value, Converter={StaticResource BaseTypeConverter}, Mode=TwoWay}" Grid.Column="1"/>
64 </Grid>
65 </DataTemplate>
66 <DataTemplate x:Key="NumberValueItemDataTemplate" x:DataType="TreeViewNode">
67 <Grid Padding="0,0,5,0" Height="44">
68 <Grid.ColumnDefinitions>
69 <ColumnDefinition Width="*"/>
70 <ColumnDefinition Width="120"/>
71 </Grid.ColumnDefinitions>
72 <StackPanel Orientation="Horizontal" Spacing="20">
73 <FontIcon VerticalAlignment="Center" Glyph="&#xE90F;"/>
74 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
75 </StackPanel>
76 <NumberBox VerticalAlignment="Center" HorizontalAlignment="Stretch" DataContext="{x:Bind Content}" SpinButtonPlacementMode="Compact" Value="{x:Bind ((model:BlueprintPropertyViewData)Content).Value, Converter={StaticResource BaseTypeConverter}}" ValueChanged="NumberBox_ValueChanged" Grid.Column="1"/>
77 </Grid>
78 </DataTemplate>
79 <DataTemplate x:Key="EnumValueItemDataTemplate" x:DataType="TreeViewNode">
80 <Grid Padding="0,0,5,0" Height="44">
81 <Grid.ColumnDefinitions>
82 <ColumnDefinition Width="*"/>
83 <ColumnDefinition Width="120"/>
84 </Grid.ColumnDefinitions>
85 <StackPanel Orientation="Horizontal" Spacing="20">
86 <FontIcon VerticalAlignment="Center" Glyph="&#xE90F;"/>
87 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
88 </StackPanel>
89 <ComboBox VerticalAlignment="Center" HorizontalAlignment="Stretch" DataContext="{x:Bind Content}" SelectedItem="{x:Bind ((model:BlueprintPropertyViewData)Content).Value.ToString()}" SelectionChanged="ComboBox_SelectionChanged" ItemsSource="{x:Bind ((model:BlueprintPropertyViewData)Content).EnumValues, Mode=OneWay}" Grid.Column="1"/>
90 </Grid>
91 </DataTemplate>
92 <DataTemplate x:Key="MultiEnumValueItemDataTemplate" x:DataType="TreeViewNode">
93 <Grid Padding="0,0,5,0" Height="44">
94 <Grid.ColumnDefinitions>
95 <ColumnDefinition Width="*"/>
96 <ColumnDefinition Width="120"/>
97 </Grid.ColumnDefinitions>
98 <StackPanel Orientation="Horizontal" Spacing="20">
99 <FontIcon VerticalAlignment="Center" Glyph="&#xE90F;"/>
100 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
101 </StackPanel>
102 <SplitButton VerticalAlignment="Center" HorizontalAlignment="Stretch" Grid.Column="1" Content="{x:Bind ((model:BlueprintPropertyViewData)Content).Value.ToString(), Mode=OneWay}">
103 <SplitButton.Flyout>
104 <Flyout Content="{x:Bind (StackPanel)((model:BlueprintPropertyViewData)Content).CustomData, Mode=OneWay}" Closed="Flyout_Closed"/>
105 </SplitButton.Flyout>
106 </SplitButton>
107 </Grid>
108 </DataTemplate>
109 <DataTemplate x:Key="BooleanValueItemDataTemplate" x:DataType="TreeViewNode">
110 <Grid Padding="0,0,5,0" Height="44">
111 <Grid.ColumnDefinitions>
112 <ColumnDefinition Width="*"/>
113 <ColumnDefinition Width="120"/>
114 </Grid.ColumnDefinitions>
115 <StackPanel Orientation="Horizontal" Spacing="20">
116 <FontIcon VerticalAlignment="Center" Glyph="&#xE90F;"/>
117 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
118 </StackPanel>
119 <ComboBox VerticalAlignment="Center" HorizontalAlignment="Stretch" DataContext="{x:Bind Content}" SelectedItem="{x:Bind ((model:BlueprintPropertyViewData)Content).Value.ToString()}" ItemsSource="{x:Bind ((model:BlueprintPropertyViewData)Content).EnumValues}" SelectionChanged="ComboBox_SelectionChanged" Grid.Column="1"/>
55 120 </Grid>
56 121 </DataTemplate>
57 122 <DataTemplate x:Key="CubeItemDataTemplate" x:DataType="TreeViewNode">
@@ -64,16 +129,19 @@
64 129 <Image Source="{x:Bind ((model:BlueprintPropertyViewData)Content).CubeImage}" Stretch="Uniform"/>
65 130 <TextBlock VerticalAlignment="Center" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).Name, Mode=OneWay}"/>
66 131 </StackPanel>
67 <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" TextTrimming="CharacterEllipsis" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).CustomName, Mode=OneWay}" Grid.Column="1" Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
132 <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" TextTrimming="CharacterEllipsis" Text="{x:Bind ((model:BlueprintPropertyViewData)Content).CustomData, Mode=OneWay}" Grid.Column="1" Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
68 133 </Grid>
69 134 </DataTemplate>
70 <selector:ShipBlueprintItemTemplateSelector x:Key="ShipBlueprintItemTemplateSelector" DefaultTemplate="{StaticResource TreeViewItemDataTemplate}" EnumerableTemplate="{StaticResource EnumerableItemDataTemplate}" GridItemTemplate="{StaticResource GridItemDataTemplate}" ObjectItemTemplate="{StaticResource ObjectItemDataTemplate}" ValueItemTemplate="{StaticResource ValueItemDataTemplate}" CubeItemTemplate="{StaticResource CubeItemDataTemplate}"/>
135 <selector:ShipBlueprintItemTemplateSelector x:Key="ShipBlueprintItemTemplateSelector" DefaultTemplate="{StaticResource TreeViewItemDataTemplate}" CubeItemTemplate="{StaticResource CubeItemDataTemplate}" GridItemTemplate="{StaticResource GridItemDataTemplate}" ObjectItemTemplate="{StaticResource ObjectItemDataTemplate}" EnumerableTemplate="{StaticResource EnumerableItemDataTemplate}" StringValueItemTemplate="{StaticResource StringValueItemDataTemplate}" NumberValueItemTemplate="{StaticResource NumberValueItemDataTemplate}" EnumValueItemTemplate="{StaticResource EnumValueItemDataTemplate}" MultiEnumValueItemTemplate="{StaticResource MultiEnumValueItemDataTemplate}" BooleanValueItemTemplate="{StaticResource BooleanValueItemDataTemplate}"/>
71 136 </Page.Resources>
72 137
73 138 <Grid>
74 <ContentDialog x:Name="editValueContentDialog" IsPrimaryButtonEnabled="True" IsSecondaryButtonEnabled="True" PrimaryButtonText="Edit" SecondaryButtonText="Cancel">
139 <ContentDialog x:Name="editValueContentDialog" IsPrimaryButtonEnabled="True" IsSecondaryButtonEnabled="True" PrimaryButtonText="Edit" SecondaryButtonText="Cancel" DefaultButton="Primary" Title="Edit value">
75 140 <TextBox Text="{x:Bind ViewModel.EditValueText, Mode=TwoWay}" TextWrapping="Wrap" AcceptsReturn="True" PlaceholderText="Enter the value"/>
76 141 </ContentDialog>
142 <ContentDialog x:Name="editEnumContentDialog" IsPrimaryButtonEnabled="True" IsSecondaryButtonEnabled="True" PrimaryButtonText="Edit" SecondaryButtonText="Cancel" DefaultButton="Primary" Title="Edit value">
143 <ComboBox ItemsSource="{x:Bind ViewModel.EditValueEnumList}" SelectedItem="{x:Bind ViewModel.SelectedEditEnum, Mode=TwoWay}"/>
144 </ContentDialog>
77 145 <Grid Canvas.ZIndex="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Visibility="{x:Bind ViewModel.IsProgressRingVisible, Mode=OneWay}" Background="{ThemeResource SmokeFillColorDefaultBrush}">
78 146 <Grid VerticalAlignment="Center" HorizontalAlignment="Center" CornerRadius="15" Padding="100">
79 147 <Grid.Background>
@@ -91,10 +159,6 @@
91 159 <RowDefinition Height="*"/>
92 160 </Grid.RowDefinitions>
93 161 <Grid Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
94 <Grid.RowDefinitions>
95 <RowDefinition Height="*"/>
96 <RowDefinition Height="*"/>
97 </Grid.RowDefinitions>
98 162 <MenuBar>
99 163 <MenuBarItem Title="File">
100 164 <MenuFlyoutItem Text="Open blueprint" Icon="OpenFile" Command="{x:Bind ViewModel.OpenBlueprintCommand}">
@@ -120,17 +184,14 @@
120 184 <MenuBarItem Title="View">
121 185 </MenuBarItem>
122 186 </MenuBar>
123 <CommandBar Grid.Row="1" DefaultLabelPosition="Right" HorizontalAlignment="Left">
124 <AppBarButton Icon="Add" Label="Add" IsEnabled="{x:Bind ((model:BlueprintPropertyViewData)ViewModel.SelectedTreeViewNode.Content).IsEnumerable, FallbackValue=False, Mode=OneWay}" Command="{x:Bind ViewModel.AddCommand}"/>
125 <AppBarButton Icon="Edit" Label="Edit" IsEnabled="{x:Bind ((model:BlueprintPropertyViewData)ViewModel.SelectedTreeViewNode.Content).IsBasicType, FallbackValue=False, Mode=OneWay}" Command="{x:Bind ViewModel.EditCommand}"/>
126 <AppBarButton Icon="Delete" Label="Delete" IsEnabled="{x:Bind ((model:BlueprintPropertyViewData)ViewModel.SelectedTreeViewNode.Content).Parent.IsEnumerable, FallbackValue=False, Mode=OneWay}" Command="{x:Bind ViewModel.DeleteCommand}"/>
127 </CommandBar>
128 187 </Grid>
129 188 <ScrollView Grid.Row="1" Canvas.ZIndex="0">
130 189 <StackPanel Spacing="20">
131 <!--<TreeView ItemsSource="{x:Bind ViewModel.ShipGridPropertyList, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedBlueprintPropertyViewData, Mode=TwoWay}" ItemTemplate="{StaticResource BlueprintDataTemplate}" Expanding="TreeView_Expanding" Collapsed="TreeView_Collapsed"/>-->
190 <ListView ItemsSource="{x:Bind }">
191
192 </ListView>
132 193 <Expander Header="蓝图属性" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
133 <TreeView x:Name="propertyTreeView" x:FieldModifier="internal" SelectedItem="{x:Bind ViewModel.SelectedTreeViewNode, Mode=TwoWay}" ItemTemplateSelector="{StaticResource ShipBlueprintItemTemplateSelector}" Expanding="TreeView_Expanding" Collapsed="TreeView_Collapsed"/>
194 <TreeView x:Name="propertyTreeView" x:FieldModifier="internal" SelectedItem="{x:Bind ViewModel.SelectedTreeViewNode, Mode=TwoWay}" ItemTemplateSelector="{StaticResource ShipBlueprintItemTemplateSelector}" Expanding="TreeView_Expanding" Collapsed="TreeView_Collapsed" CanDrag="False" CanDragItems="False"/>
134 195 </Expander>
135 196 </StackPanel>
136 197 </ScrollView>
Modified SpaceEngineersBlueprintEditor/Views/BlueprintEditPage.xaml.cs +21 -1
@@ -2,6 +2,7 @@ using Microsoft.UI.Xaml.Navigation;
2 2 using SpaceEngineersBlueprintEditor.Model;
3 3 using SpaceEngineersBlueprintEditor.Utilities;
4 4 using SpaceEngineersBlueprintEditor.ViewModels;
5 using XFEExtension.NetCore.StringExtension;
5 6
6 7 namespace SpaceEngineersBlueprintEditor.Views;
7 8
@@ -18,6 +19,7 @@ public sealed partial class BlueprintEditPage : Page
18 19 PageManager.AddOrUpdateCurrentPage(Current = this);
19 20 this.InitializeComponent();
20 21 ViewModel.DialogService.RegisterDialog(editValueContentDialog);
22 ViewModel.DialogService.RegisterDialog(editEnumContentDialog);
21 23 }
22 24
23 25 protected override void OnNavigatedTo(NavigationEventArgs e)
@@ -54,7 +56,7 @@ public sealed partial class BlueprintEditPage : Page
54 56 treeViewNode.Children.Add(new TreeViewNode
55 57 {
56 58 Content = child,
57 HasUnrealizedChildren = child.IsNotBasicType && child.Type is not null
59 HasUnrealizedChildren = !child.IsBasicType && child.Type is not null
58 60 });
59 61 }
60 62 treeViewNode.HasUnrealizedChildren = false;
@@ -70,4 +72,22 @@ public sealed partial class BlueprintEditPage : Page
70 72 args.Node.Children.Clear();
71 73 args.Node.HasUnrealizedChildren = true;
72 74 }
75
76 private void NumberBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
77 {
78 if (sender.DataContext is BlueprintPropertyViewData blueprintPropertyViewData)
79 blueprintPropertyViewData.Value = sender.Value;
80 }
81
82 private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
83 {
84 if (sender is ComboBox comboBox && comboBox.DataContext is BlueprintPropertyViewData blueprintPropertyViewData && comboBox.SelectedItem?.ToString() is string value && !value.IsNullOrEmpty())
85 blueprintPropertyViewData.Value = comboBox.SelectedItem;
86 }
87
88 private void Flyout_Closed(object sender, object e)
89 {
90 if (sender is Flyout flyout && flyout.Content is StackPanel stackPanel && stackPanel.DataContext is BlueprintPropertyViewData blueprintPropertyViewData && blueprintPropertyViewData.Type is not null)
91 blueprintPropertyViewData.Value = Enum.Parse(blueprintPropertyViewData.Type, string.Join(", ", stackPanel.Children.Where(child => child is CheckBox checkBox && checkBox.IsChecked is not null && checkBox.IsChecked.Value).Cast<CheckBox>().Select(checkBox => checkBox.Content.ToString())));
92 }
73 93 }