返回提交历史
Modified
SpaceEngineersBlueprintEditor/Model/DefinitionViewData.cs
+8
-3
Modified
SpaceEngineersBlueprintEditor/Utilities/AppPath.cs
+2
-0
Modified
SpaceEngineersBlueprintEditor/Utilities/Helpers/Extensions.cs
+0
-1
Modified
SpaceEngineersBlueprintEditor/Utilities/Helpers/FileHelper.cs
+20
-24
Modified
SpaceEngineersBlueprintEditor/Utilities/Helpers/SpaceEngineersHelper.cs
+14
-3
Modified
SpaceEngineersBlueprintEditor/ViewModels/BlueprintsViewPageViewModel.cs
+1
-1
Modified
SpaceEngineersBlueprintEditor/ViewModels/GameDefinitionsViewPageViewModel.cs
+14
-17
Modified
SpaceEngineersBlueprintEditor/Views/GameDefinitionsViewPage.xaml
+14
-4
Modified
SpaceEngineersBlueprintEditor/Views/GameDefinitionsViewPage.xaml.cs
+2
-0
SpaceEngineersModDev/SpaceEngineersBlueprintEditorInWinUI
完善加载和定义页面
512631e
代码差异
9 个文件
+75
-53
@@ -1,10 +1,15 @@
1
1
using Microsoft.UI.Xaml.Media;
2
2
using VRage.Game;
3
using XFEExtension.NetCore.StringExtension;
3
4
4
5
namespace SpaceEngineersBlueprintEditor.Model;
5
6
6
public class DefinitionViewData(ImageSource? imageSource, MyDefinitionBase myDefinitionBase)
7
public class DefinitionViewData
7
8
{
8
public ImageSource? ImageSource { get; set; } = imageSource;
9
public MyDefinitionBase DefinitionBase { get; set; } = myDefinitionBase;
9
public ImageSource? ImageSource { get; set; }
10
public string? AdditionalInfo { get; set; }
11
public bool HasAdditionalInfo => AdditionalInfo is not null && !AdditionalInfo.IsNullOrEmpty();
12
public string? CubeSize { get; set; }
13
public bool HasCubeSize => CubeSize is not null && !CubeSize.IsNullOrEmpty();
14
public required MyDefinitionBase DefinitionBase { get; set; }
10
15
}
@@ -14,6 +14,8 @@ public partial class AppPath
14
14
[AutoPath]
15
15
private static readonly string appCache = @$"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\Temp\SpaceEngineersBlueprintsEditor";
16
16
[AutoPath]
17
private static readonly string definitionImages = @$"{AppCache}\DefinitionImages";
18
[AutoPath]
17
19
private static readonly string localProfile = @$"{AppLocalData}\Profiles";
18
20
[AutoPath]
19
21
private static readonly string localVersionProfile = $@"{AppLocalVersionData}\Profiles";
@@ -10,5 +10,4 @@ public static class Extensions
10
10
private static readonly ResourceLoader _resourceLoader = new();
11
11
public static string GetLocalized(this string resourceKey) => _resourceLoader.GetString(resourceKey);
12
12
public static BlueprintInfoViewData ToBlueprintInfoViewData(this BlueprintInfo blueprintInfo) => new(new BitmapImage(blueprintInfo.HasImage ? new(blueprintInfo.ImagePath) : new Uri("ms-appx:///Assets/Images/BlueprintDrag.png", UriKind.RelativeOrAbsolute)), !blueprintInfo.HasBlueprint, blueprintInfo.Name, blueprintInfo.FileSize, blueprintInfo.BlueprintPath);
13
public static DefinitionViewData ToDefinitionViewData(this MyDefinitionBase myDefinitionBase) => new(new BitmapImage(), myDefinitionBase);
14
13
}
@@ -1,11 +1,8 @@
1
using System.Diagnostics;
1
using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
2
using System.Diagnostics;
2
3
using System.Drawing.Imaging;
3
using System.Runtime.InteropServices.WindowsRuntime;
4
4
using System.Runtime.InteropServices;
5
5
using VRage.FileSystem;
6
using Windows.Storage.Streams;
7
using Microsoft.UI.Xaml.Media.Imaging;
8
using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
9
6
10
7
namespace SpaceEngineersBlueprintEditor.Utilities.Helpers;
11
8
@@ -37,7 +34,7 @@ public static class FileHelper
37
34
}
38
35
}
39
36
40
public static async Task<BitmapImage?> ToBitmap(string ddsFilePath)
37
public static void ToBitmap(string ddsFilePath, string savePath)
41
38
{
42
39
try
43
40
{
@@ -46,29 +43,28 @@ public static class FileHelper
46
43
int height = -1;
47
44
if (ImageConverter.TextureToRgbaBuffer(readStream, 0, ref width, ref height) is byte[] buffer)
48
45
{
49
var bmp = new System.Drawing.Bitmap(width, height, PixelFormat.Format32bppArgb);
50
var bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat);
51
Marshal.Copy(buffer, 0, bmpData.Scan0, buffer.Length);
52
bmp.UnlockBits(bmpData);
53
using var saveStream = new MemoryStream();
54
bmp.Save(saveStream, ImageFormat.Png);
55
saveStream.Seek(0, SeekOrigin.Begin);
56
var randomAccessStream = new InMemoryRandomAccessStream();
57
await randomAccessStream.WriteAsync(saveStream.ToArray().AsBuffer());
58
randomAccessStream.Seek(0);
59
var bitmapImage = new BitmapImage();
60
await bitmapImage.SetSourceAsync(randomAccessStream);
61
return bitmapImage;
62
}
63
else
64
{
65
return null;
46
var bitmap = new System.Drawing.Bitmap(width, height, PixelFormat.Format32bppArgb);
47
var data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
48
Marshal.Copy(buffer, 0, data.Scan0, buffer.Length);
49
bitmap.UnlockBits(data);
50
bitmap.Save(savePath, ImageFormat.Png);
66
51
}
67
52
}
68
53
catch (Exception ex)
69
54
{
70
55
Debug.WriteLine(ex.Message);
71
return null;
72
56
}
73
57
}
58
59
public static string ChangeExtension(string filePath, string extension) => @$"{Path.GetDirectoryName(filePath)}\{Path.GetFileNameWithoutExtension(filePath)}.{extension}";
60
61
public static bool AutoCreateDirectory(string filePath)
62
{
63
if (Path.GetDirectoryName(filePath) is string directory && !Directory.Exists(directory))
64
{
65
Directory.CreateDirectory(directory);
66
return true;
67
}
68
return false;
69
}
74
70
}
@@ -1,9 +1,14 @@
1
using Microsoft.UI.Xaml.Media.Imaging;
1
using Microsoft.UI.Dispatching;
2
using Microsoft.UI.Xaml.Media.Imaging;
2
3
using Sandbox.Definitions;
3
4
using SpaceEngineersBlueprintEditor.Model;
4
5
using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
6
using System.Collections.Concurrent;
7
using System.Diagnostics;
5
8
using VRage.Collections;
6
9
using VRage.Game;
10
using VRage.Game.Definitions;
11
using Windows.Storage.Streams;
7
12
8
13
namespace SpaceEngineersBlueprintEditor.Utilities.Helpers;
9
14
@@ -11,17 +16,23 @@ public static class SpaceEngineersHelper
11
16
{
12
17
public static event EventHandler? LoadComplete;
13
18
public static bool IsLoadComplete { get; private set; } = false;
14
public static Dictionary<MyDefinitionBase, BitmapImage?> DefinitionImageList { get; set; } = [];
15
19
public static DictionaryValuesReader<MyDefinitionId, MyDefinitionBase> AllDefinitions => MyDefinitionManager.Static.GetAllDefinitions();
16
20
public static IEnumerable<MyCubeBlockDefinition> CubeBlockDefinitions => AllDefinitions.Where(definition => definition is MyCubeBlockDefinition).Cast<MyCubeBlockDefinition>();
17
21
public static IEnumerable<MyComponentDefinition> ComponentDefinitions => AllDefinitions.Where(definition => definition is MyComponentDefinition).Cast<MyComponentDefinition>();
18
22
public static IEnumerable<MyPhysicalItemDefinition> ItemDefinitions => AllDefinitions.Where(definition => definition is MyPhysicalItemDefinition).Cast<MyPhysicalItemDefinition>();
23
public static IEnumerable<MyDlcDefinition> DLCDefinitions => AllDefinitions.Where(definition => definition is MyDlcDefinition).Cast<MyDlcDefinition>();
19
24
public static async Task LoadDefinitionViewDataListAsync()
20
25
{
21
26
while (!Initializer.IsDefinitionsLoadComplete) { await Task.Delay(100); }
22
27
foreach (var definition in AllDefinitions)
23
28
if (definition is not null && definition.Icons is not null && definition.Icons.Length > 0)
24
DefinitionImageList.Add(definition, await FileHelper.ToBitmap($@"{SpaceEngineersPath.SpaceEngineerContentPath}\{definition.Icons[0]}"));
29
{
30
var originalPath = @$"{SpaceEngineersPath.SpaceEngineerContentPath}\{definition.Icons[0]}";
31
var targetPath = @$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(definition.Icons[0], "png")}";
32
FileHelper.AutoCreateDirectory(targetPath);
33
if (!File.Exists(targetPath))
34
FileHelper.ToBitmap(originalPath, targetPath);
35
}
25
36
IsLoadComplete = true;
26
37
LoadComplete?.Invoke(null, EventArgs.Empty);
27
38
}
@@ -35,7 +35,7 @@ public partial class BlueprintsViewPageViewModel : ViewModelBase
35
35
LoadBlueprints(SearchBlueprints(currentParameter, value).ToList());
36
36
}
37
37
38
private static IEnumerable<BlueprintInfo> SearchBlueprints(string searchMode, string blueprintName) => GetCurrentBlueprints(searchMode).Where(blueprint => blueprint.Name.Contains(blueprintName));
38
private static IEnumerable<BlueprintInfo> SearchBlueprints(string searchMode, string blueprintName) => GetCurrentBlueprints(searchMode).Where(blueprint => blueprint.Name.Contains(blueprintName, StringComparison.OrdinalIgnoreCase));
39
39
40
40
private static List<BlueprintInfo> GetCurrentBlueprints(string currentLocation) => currentLocation switch
41
41
{
@@ -1,11 +1,12 @@
1
1
using CommunityToolkit.Mvvm.ComponentModel;
2
2
using Microsoft.UI.Xaml.Media.Imaging;
3
using Sandbox.Definitions;
3
4
using SpaceEngineersBlueprintEditor.Implements.Services;
4
5
using SpaceEngineersBlueprintEditor.Interface.Services;
5
6
using SpaceEngineersBlueprintEditor.Model;
7
using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
6
8
using SpaceEngineersBlueprintEditor.Utilities;
7
9
using System.Collections.ObjectModel;
8
using System.Diagnostics;
9
10
using VRage.Game;
10
11
11
12
namespace SpaceEngineersBlueprintEditor.ViewModels;
@@ -16,16 +17,19 @@ public partial class GameDefinitionsViewPageViewModel : ViewModelBase
16
17
private string searchText = "";
17
18
[ObservableProperty]
18
19
private bool isProgressRingVisible = true;
20
[ObservableProperty]
21
private DefinitionViewData? selectedDefinitionViewData;
19
22
private string currentParameter = "";
20
private List<DefinitionViewData> _definitions = [];
23
private readonly List<DefinitionViewData> _definitions = [];
21
24
public ObservableCollection<DefinitionViewData> Definitions { get; } = [];
22
25
public INavigationParameterService<string> NavigationParameterService { get; } = new NavigationParameterService<string>();
23
26
24
27
public GameDefinitionsViewPageViewModel() => NavigationParameterService.ParameterChange += NavigationParameterService_ParameterChange;
25
28
26
private void NavigationParameterService_ParameterChange(object? sender, string e)
29
private async void NavigationParameterService_ParameterChange(object? sender, string e)
27
30
{
28
31
currentParameter = e;
32
while (!Initializer.IsDefinitionsLoadComplete) { await Task.Delay(100); }
29
33
LoadDefinitions(GetCurrentDefinitions(currentParameter));
30
34
IsProgressRingVisible = false;
31
35
}
@@ -35,25 +39,18 @@ public partial class GameDefinitionsViewPageViewModel : ViewModelBase
35
39
foreach (var definition in myDefinitions)
36
40
if (definition is not null)
37
41
{
38
SpaceEngineersHelper.DefinitionImageList.TryGetValue(definition, out var bitmapImage);
39
var definitionViewData = new DefinitionViewData(bitmapImage, definition);
42
var definitionViewData = new DefinitionViewData
43
{
44
DefinitionBase = definition,
45
ImageSource = definition.Icons is not null && definition.Icons.Length > 0 ? new BitmapImage(new(@$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(definition.Icons[0], "png")}")) : null,
46
CubeSize = definition is MyCubeBlockDefinition myCubeBlockDefinition ? myCubeBlockDefinition.CubeSize == MyCubeSize.Small ? "\uE744" : "\uE978" : null
47
};
40
48
_definitions.Add(definitionViewData);
41
49
Definitions.Add(definitionViewData);
42
50
}
43
51
}
44
52
45
//private async Task LoadDefinitions(IEnumerable<MyDefinitionBase> myDefinitions)
46
//{
47
// foreach (var definition in myDefinitions)
48
// if (definition is not null)
49
// {
50
// var definitionViewData = new DefinitionViewData(await FileHelper.ToBitmap($@"{SpaceEngineersPath.SpaceEngineerContentPath}\{definition.Icons[0]}"), definition);
51
// _definitions.Add(definitionViewData);
52
// Definitions.Add(definitionViewData);
53
// }
54
//}
55
56
private IEnumerable<DefinitionViewData> SearchDefinitions(string definitionsName) => _definitions.Where(definition => definition.DefinitionBase.DisplayNameText is not null && definition.DefinitionBase.DisplayNameText.Contains(definitionsName));
53
private IEnumerable<DefinitionViewData> SearchDefinitions(string definitionsName) => _definitions.Where(definition => definition.DefinitionBase.DisplayNameText is not null && definition.DefinitionBase.DisplayNameText.Contains(definitionsName, StringComparison.OrdinalIgnoreCase));
57
54
58
55
private static IEnumerable<MyDefinitionBase> GetCurrentDefinitions(string currentLocation) => currentLocation switch
59
56
{
@@ -21,8 +21,8 @@
21
21
</StackPanel>
22
22
</Grid>
23
23
</Grid>
24
<Grid ColumnDefinitions="4*, *" RowSpacing="20" Background="{ThemeResource SolidBackgroundFillColorBaseBrush}" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Margin="0,0,0,36">
25
<ItemsView Canvas.ZIndex="0" Padding="4" ItemsSource="{x:Bind ViewModel.Definitions}">
24
<Grid ColumnDefinitions="4*, *" RowSpacing="20" Background="{ThemeResource SolidBackgroundFillColorBaseBrush}" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" Margin="0,0,0,36" CornerRadius="8">
25
<ItemsView x:Name="definitionsItemView" SelectionChanged="DefinitionsItemView_SelectionChanged" Canvas.ZIndex="0" Padding="4" ItemsSource="{x:Bind ViewModel.Definitions}">
26
26
<ItemsView.Layout>
27
27
<UniformGridLayout Orientation="Horizontal" />
28
28
</ItemsView.Layout>
@@ -30,15 +30,25 @@
30
30
<DataTemplate x:DataType="model:DefinitionViewData">
31
31
<ItemContainer Width="100" Height="100" Margin="4" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}">
32
32
<Grid RowDefinitions="60, Auto" Padding="5">
33
<Image Source="{x:Bind ImageSource, Mode=OneWay}" Width="60" Height="60" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center"/>
33
<Image Source="{x:Bind ImageSource}" Width="60" Height="60" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center"/>
34
34
<TextBlock Grid.Row="1" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text="{x:Bind DefinitionBase.DisplayNameText}"/>
35
<Grid HorizontalAlignment="Right" CornerRadius="4" VerticalAlignment="Top" Padding="1" Visibility="{x:Bind HasAdditionalInfo}" Background="{ThemeResource AccentFillColorDefaultBrush}">
36
<TextBlock Text="{x:Bind AdditionalInfo}" FontSize="12" Foreground="{ThemeResource TextOnAccentFillColorPrimaryBrush}"/>
37
</Grid>
38
<FontIcon HorizontalAlignment="Right" VerticalAlignment="Top" Glyph="{x:Bind CubeSize}" Visibility="{x:Bind HasCubeSize}"/>
35
39
</Grid>
36
40
</ItemContainer>
37
41
</DataTemplate>
38
42
</ItemsView.ItemTemplate>
39
43
</ItemsView>
40
44
<Grid Grid.Column="1" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}">
41
45
<ScrollView>
46
<StackPanel Padding="16" Spacing="20">
47
<TextBlock Text="{x:Bind ViewModel.SelectedDefinitionViewData.DefinitionBase.DisplayNameText, Mode=OneWay}" HorizontalAlignment="Left" Style="{ThemeResource SubtitleTextBlockStyle}"/>
48
<Image Source="{x:Bind ViewModel.SelectedDefinitionViewData.ImageSource, Mode=OneWay}" HorizontalAlignment="Left" Width="128" Height="128"/>
49
<TextBlock Text="{x:Bind ViewModel.SelectedDefinitionViewData.DefinitionBase.DescriptionText, Mode=OneWay}" HorizontalAlignment="Left" Style="{ThemeResource CaptionTextBlockStyle}"/>
50
</StackPanel>
51
</ScrollView>
42
52
</Grid>
43
53
<Grid Margin="0,0,0,20" Width="250" Padding="5" CornerRadius="8" VerticalAlignment="Bottom" HorizontalAlignment="Center" Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}">
44
54
<AutoSuggestBox PlaceholderText="Search definitions..." QueryIcon="Find" Text="{x:Bind ViewModel.SearchText, Mode=TwoWay}"/>
@@ -27,4 +27,6 @@ public sealed partial class GameDefinitionsViewPage : Page
27
27
ViewModel.NavigationParameterService.OnParameterChange(Parameter);
28
28
}
29
29
}
30
31
private void DefinitionsItemView_SelectionChanged(ItemsView sender, ItemsViewSelectionChangedEventArgs args) => ViewModel.SelectedDefinitionViewData = (Model.DefinitionViewData?)sender.SelectedItem;
30
32
}