This commit is contained in:
Hakoyu 2023-09-26 16:05:39 +08:00
parent 179c62e0df
commit 19203ead6c
19 changed files with 122 additions and 129 deletions

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
@ -16,10 +18,10 @@ public static class Extensions
return source.IndexOf(value, comparisonType) >= 0;
}
public static string GetSourceFile(this BitmapImage image)
{
return ((FileStream)image.StreamSource).Name;
}
//public static string GetSourceFile(this BitmapImage image)
//{
// return ((FileStream)image.StreamSource).Name;
//}
public static void CloseStream(this ImageSource source)
{
@ -29,6 +31,37 @@ public static class Extensions
}
}
public static BitmapImage Copy(this BitmapImage image)
{
BitmapImage newImage = new();
newImage.BeginInit();
newImage.DecodePixelWidth = image.DecodePixelWidth;
newImage.DecodePixelHeight = image.DecodePixelHeight;
try
{
using var bitmap = new Bitmap(image.StreamSource);
var ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Png);
image.StreamSource.CopyTo(ms);
newImage.StreamSource = ms;
}
finally
{
newImage.EndInit();
}
return newImage;
}
public static void SaveToPng(this BitmapSource image, string path)
{
if (path.EndsWith(".png") is false)
path += ".png";
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using var fs = new FileStream(path, FileMode.Create);
encoder.Save(fs);
}
public static bool TryAdd<TKey, TValue>(
this IDictionary<TKey, TValue> dictionary,
TKey key,

View File

@ -11,17 +11,15 @@ namespace VPet.ModMaker.Models;
public class I18nHelper
{
public static I18nHelper Current { get; set; } = new();
public ObservableValue<string> MainCulture { get; } = new();
public ObservableValue<string> CultureName { get; } = new();
public ObservableCollection<string> CultureNames { get; } = new();
public I18nHelper()
{
CultureNames.CollectionChanged += Langs_CollectionChanged;
CultureNames.CollectionChanged += Cultures_CollectionChanged;
}
private void Langs_CollectionChanged(
private void Cultures_CollectionChanged(
object sender,
System.Collections.Specialized.NotifyCollectionChangedEventArgs e
)
@ -29,25 +27,25 @@ public class I18nHelper
// 替换
if (e.NewStartingIndex == e.OldStartingIndex)
{
ReplaceLang?.Invoke((string)e.OldItems[0], (string)e.NewItems[0]);
ReplaceCulture?.Invoke((string)e.OldItems[0], (string)e.NewItems[0]);
return;
}
// 删除
if (e.OldItems is not null)
{
RemoveLang?.Invoke((string)e.OldItems[0]);
RemoveCulture?.Invoke((string)e.OldItems[0]);
}
// 新增
if (e.NewItems is not null)
{
AddLang?.Invoke((string)e.NewItems[0]);
AddCulture?.Invoke((string)e.NewItems[0]);
}
}
public event LangEventHandler AddLang;
public event LangEventHandler RemoveLang;
public event ReplaceLangEventHandler ReplaceLang;
public event CultureEventHandler AddCulture;
public event CultureEventHandler RemoveCulture;
public event ReplaceCultureEventHandler ReplaceCulture;
public delegate void LangEventHandler(string lang);
public delegate void ReplaceLangEventHandler(string oldLang, string newLang);
public delegate void CultureEventHandler(string culture);
public delegate void ReplaceCultureEventHandler(string oldCulture, string newCulture);
}

View File

@ -16,9 +16,9 @@ public class I18nModel<T>
public I18nModel()
{
I18nHelper.Current.CultureName.ValueChanged += LangChanged;
I18nHelper.Current.AddLang += AddLang;
I18nHelper.Current.RemoveLang += RemoveLang;
I18nHelper.Current.ReplaceLang += ReplaceLang;
I18nHelper.Current.AddCulture += AddLang;
I18nHelper.Current.RemoveCulture += RemoveLang;
I18nHelper.Current.ReplaceCulture += ReplaceLang;
if (I18nHelper.Current.CultureNames.Count == 0)
return;
foreach (var item in I18nHelper.Current.CultureNames)

View File

@ -507,13 +507,11 @@ public class AnimeTypeModel
var imageIndex = 0;
foreach (var image in model.Images)
{
File.Copy(
image.Image.Value.GetSourceFile(),
image.Image.Value.SaveToPng(
Path.Combine(
imagesPath,
$"{model.Id.Value}_{imageIndex:000}_{image.Duration.Value}.png"
),
true
)
);
imageIndex++;
}
@ -537,7 +535,10 @@ public class AnimeModel
var info = Path.GetFileNameWithoutExtension(file).Split(Utils.Separator);
Id.Value = info[0];
var duration = info.Last();
var imageModel = new ImageModel(Utils.LoadImageToStream(file), int.Parse(duration));
var imageModel = new ImageModel(
Utils.LoadImageToMemoryStream(file),
int.Parse(duration)
);
Images.Add(imageModel);
}
}
@ -548,7 +549,7 @@ public class AnimeModel
model.Id.Value = Id.Value;
model.AnimeType.Value = AnimeType.Value;
foreach (var image in Images)
model.Images.Add(image);
model.Images.Add(image.Copy());
return model;
}

View File

@ -54,7 +54,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
Likability.Value = model.Likability.Value;
Price.Value = model.Price.Value;
Exp.Value = model.Exp.Value;
Image.Value = Utils.LoadImageToStream(model.Image.Value.GetSourceFile());
Image.Value = model.Image.Value;
foreach (var item in model.I18nDatas)
I18nDatas[item.Key] = item.Value.Copy();
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
@ -76,7 +76,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
Price.Value = food.Price;
Exp.Value = food.Exp;
if (File.Exists(food.Image))
Image.Value = Utils.LoadImageToStream(food.Image);
Image.Value = Utils.LoadImageToMemoryStream(food.Image);
}
public Food ToFood()

View File

@ -21,10 +21,7 @@ public class ImageModel
public ImageModel Copy()
{
var model = new ImageModel(
Utils.LoadImageToStream(Image.Value.GetSourceFile()),
Duration.Value
);
var model = new ImageModel(Image.Value, Duration.Value);
return model;
}

View File

@ -65,7 +65,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
AuthorID = loader.AuthorID;
var imagePath = Path.Combine(loader.ModPath.FullName, "icon.png");
if (File.Exists(imagePath))
Image.Value = Utils.LoadImageToStream(imagePath);
Image.Value = Utils.LoadImageToMemoryStream(imagePath);
foreach (var food in loader.Foods)
Foods.Add(new(food));
foreach (var clickText in loader.ClickTexts)
@ -260,13 +260,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
}
);
}
if (Image.Value is not null)
{
var imagePath = Image.Value.GetSourceFile();
var targetImagePath = Path.Combine(path, Path.GetFileName(imagePath));
if (imagePath != targetImagePath)
File.Copy(imagePath, targetImagePath, true);
}
Image.Value?.SaveToPng(Path.Combine(path, "icon.png"));
File.WriteAllText(modInfoFile, lps.ToString());
SavePets(path);
SaveFoods(path);
@ -548,13 +542,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
Directory.CreateDirectory(foodPath);
foreach (var food in Foods)
{
var foodImagePath = food.Image.Value.GetSourceFile();
var targetImagePath = Path.Combine(
foodPath,
$"{food.Id.Value}{Path.GetExtension(foodImagePath)}"
);
if (foodImagePath != targetImagePath)
File.Copy(foodImagePath, targetImagePath, true);
food.Image.Value.SaveToPng(Path.Combine(foodPath, food.Id.Value));
}
}
}

View File

@ -15,21 +15,21 @@ public static class Utils
public const int DecodePixelHeight = 250;
public static char[] Separator { get; } = new char[] { '_' };
public static BitmapImage LoadImageToStream(string imagePath)
{
BitmapImage bitmapImage = new();
bitmapImage.BeginInit();
bitmapImage.DecodePixelWidth = DecodePixelWidth;
try
{
bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream;
}
finally
{
bitmapImage.EndInit();
}
return bitmapImage;
}
//public static BitmapImage LoadImageToStream(string imagePath)
//{
// BitmapImage bitmapImage = new();
// bitmapImage.BeginInit();
// bitmapImage.DecodePixelWidth = DecodePixelWidth;
// try
// {
// bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream;
// }
// finally
// {
// bitmapImage.EndInit();
// }
// return bitmapImage;
//}
public static BitmapImage LoadImageToMemoryStream(string imagePath)
{

View File

@ -67,6 +67,7 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />

View File

@ -137,7 +137,7 @@ public class AnimeEditWindowVM
};
if (openFileDialog.ShowDialog() is true)
{
value.Images.Add(new(Utils.LoadImageToStream(openFileDialog.FileName)));
value.Images.Add(new(Utils.LoadImageToMemoryStream(openFileDialog.FileName)));
}
}
@ -149,13 +149,13 @@ public class AnimeEditWindowVM
{
if (File.Exists(path))
{
model.Images.Add(new(Utils.LoadImageToStream(path)));
model.Images.Add(new(Utils.LoadImageToMemoryStream(path)));
}
else if (Directory.Exists(path))
{
foreach (var file in Directory.EnumerateFiles(path, "*.png"))
{
model.Images.Add(new(Utils.LoadImageToStream(path)));
model.Images.Add(new(Utils.LoadImageToMemoryStream(path)));
}
}
}

View File

@ -48,7 +48,7 @@ public class FoodEditWindowVM
};
if (openFileDialog.ShowDialog() is true)
{
Food.Value.Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Food.Value.Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
@ -63,7 +63,7 @@ public class FoodEditWindowVM
if (openFileDialog.ShowDialog() is true)
{
Food.Value.Image.Value?.StreamSource?.Close();
Food.Value.Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Food.Value.Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
}

View File

@ -14,6 +14,7 @@ using VPet.ModMaker.Views.ModEdit;
using System.Windows;
using System.IO;
using LinePutScript.Localization.WPF;
using Panuon.WPF.UI;
namespace VPet.ModMaker.ViewModels.ModEdit;
@ -77,7 +78,7 @@ public class ModEditWindowVM
};
if (openFileDialog.ShowDialog() is true)
{
ModInfo.Value.Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
ModInfo.Value.Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
@ -92,11 +93,11 @@ public class ModEditWindowVM
if (openFileDialog.ShowDialog() is true)
{
ModInfo.Value.Image.Value?.StreamSource?.Close();
ModInfo.Value.Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
ModInfo.Value.Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
private void AddCulture()
public void AddCulture()
{
var window = new AddCultureWindow();
window.ShowDialog();
@ -163,19 +164,22 @@ public class ModEditWindowVM
};
if (saveFileDialog.ShowDialog() is true)
{
var pending = PendingBox.Show("保存中".Translate());
try
{
var path = Path.GetDirectoryName(saveFileDialog.FileName);
ModInfo.Value.SaveTo(path);
if (string.IsNullOrWhiteSpace(ModInfo.Value.SourcePath.Value))
ModInfo.Value.SourcePath.Value = path;
pending.Close();
MessageBox.Show(ModEditWindow, "保存成功".Translate());
}
catch (Exception ex)
{
pending.Close();
MessageBox.Show($"保存失败 错误信息:\n{0}".Translate(ex));
return;
}
MessageBox.Show("保存成功".Translate());
}
}

View File

@ -52,7 +52,7 @@ public class MoveEditWindowVM
};
if (openFileDialog.ShowDialog() is true)
{
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
@ -67,7 +67,7 @@ public class MoveEditWindowVM
if (openFileDialog.ShowDialog() is true)
{
Image.Value?.StreamSource?.Close();
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
}

View File

@ -52,7 +52,7 @@ public class PetEditWindowVM
};
if (openFileDialog.ShowDialog() is true)
{
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
@ -67,7 +67,7 @@ public class PetEditWindowVM
if (openFileDialog.ShowDialog() is true)
{
Image.Value?.StreamSource?.Close();
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
}

View File

@ -53,7 +53,7 @@ public class WorkEditWindowVM
};
if (openFileDialog.ShowDialog() is true)
{
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
@ -68,7 +68,7 @@ public class WorkEditWindowVM
if (openFileDialog.ShowDialog() is true)
{
Image.Value?.StreamSource?.Close();
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
Image.Value = Utils.LoadImageToMemoryStream(openFileDialog.FileName);
}
}
}

View File

@ -146,6 +146,11 @@ public class ModMakerWindowVM
private void ClearHistories()
{
if (
MessageBox.Show("确定要清空吗?".Translate(), "", MessageBoxButton.YesNo)
is not MessageBoxResult.Yes
)
return;
ShowHistories.Value.Clear();
Histories.Clear();
File.WriteAllText(ModMakerInfo.HistoryFile, string.Empty);

View File

@ -284,7 +284,7 @@
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Command="{Binding AddCultureCommand}" Content="{ll:Str 添加语言}" />
<Button Command="{Binding AddCultureCommand}" Content="{ll:Str 添加文化}" />
<ListBox
x:Name="ListBox_Cultures"
Grid.Row="1"

View File

@ -1,4 +1,5 @@
using Microsoft.Win32;
using LinePutScript.Localization.WPF;
using Microsoft.Win32;
using Panuon.WPF;
using System;
using System.Collections.Generic;
@ -16,6 +17,7 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using VPet.ModMaker.Models;
using VPet.ModMaker.ViewModels.ModEdit;
using VPet.ModMaker.Views.ModEdit.AnimeEdit;
using VPet.ModMaker.Views.ModEdit.ClickTextEdit;
@ -48,10 +50,23 @@ public partial class ModEditWindow : Window
{
InitializeComponent();
DataContext = new ModEditWindowVM(this);
Closed += Window_ModEdit_Closed;
Closed += ModEditWindow_Closed;
Loaded += ModEditWindow_Loaded;
}
private void Window_ModEdit_Closed(object sender, EventArgs e)
private void ModEditWindow_Loaded(object sender, RoutedEventArgs e)
{
if (I18nHelper.Current.CultureNames.Count == 0)
{
if (
MessageBox.Show("未添加任何文化,确定要添加文化吗?".Translate(), "", MessageBoxButton.YesNo)
is MessageBoxResult.Yes
)
ViewModel.AddCulture();
}
}
private void ModEditWindow_Closed(object sender, EventArgs e)
{
ViewModel.Close();
try

View File

@ -108,53 +108,4 @@
</StackPanel>
</Grid>
</Grid>
<!--<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="1*" />
<RowDefinition Height="8*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Label
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{x:Null}"
Content="{ll:Str Mod制作器}"
FontSize="24" />
<Label
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{x:Null}"
Content="{ll:Str 打开最近制作的MOD}" />
<ListBox
Grid.Row="2"
Grid.RowSpan="1"
Grid.Column="1"
Grid.ColumnSpan="2"
Background="{DynamicResource PrimaryLighter}"
FontSize="20" />
<Button
Grid.Row="4"
Grid.Column="2"
Grid.ColumnSpan="1"
VerticalAlignment="Center"
Content="{ll:Str 创建新MOD}"
Style="{DynamicResource ThemedButtonStyle}" />
<TextBox
Grid.Row="4"
Grid.Column="1"
pu:TextBoxHelper.Watermark="{ll:Str 'MOD名称(英文)'}"
Style="{DynamicResource StandardTextBoxStyle}" />
</Grid>-->
</Window>