mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
重构I18n资源
This commit is contained in:
parent
54d77018af
commit
4d64fdc766
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// I18n数据
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{ID}, Count = {Datas.Count}")]
|
||||
public class I18nData : ObservableObjectX
|
||||
{
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 基于 <see cref="I18nHelper.Current.CultureNames"/> 的索引的数据列表
|
||||
/// </summary>
|
||||
public ObservableList<Func<INotifyPropertyChanged, string>> Datas { get; } = new();
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
// TODO: 更新事件
|
||||
/// <summary>
|
||||
/// I18n助手
|
||||
/// </summary>
|
||||
public class I18nHelper : ObservableObjectX
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前数据
|
||||
/// </summary>
|
||||
public static I18nHelper Current { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前文化名称
|
||||
/// </summary>
|
||||
#region CultureName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _cultureName;
|
||||
|
||||
public string CultureName
|
||||
{
|
||||
get => _cultureName;
|
||||
set => SetProperty(ref _cultureName, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 文化列表
|
||||
/// </summary>
|
||||
public ObservableList<string> CultureNames { get; } = new();
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using Mapster;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// I18n模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class I18nModel<T> : ObservableObjectX
|
||||
where T : ObservableObjectX, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前I18n数据
|
||||
/// </summary>
|
||||
#region CurrentI18nData
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private T _currentI18nData;
|
||||
|
||||
[AdaptIgnore]
|
||||
public T CurrentI18nData
|
||||
{
|
||||
get => _currentI18nData;
|
||||
set => SetProperty(ref _currentI18nData, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 所有I18n数据
|
||||
/// </summary>
|
||||
[AdaptIgnore]
|
||||
public Dictionary<string, T> I18nDatas { get; } = new();
|
||||
|
||||
public I18nModel()
|
||||
{
|
||||
I18nHelper.Current.PropertyChangedX += Current_PropertyChangedX;
|
||||
I18nHelper.Current.CultureNames.ListChanged += CultureNames_ListChanged;
|
||||
if (I18nHelper.Current.CultureNames.HasValue() is false)
|
||||
return;
|
||||
foreach (var item in I18nHelper.Current.CultureNames)
|
||||
I18nDatas.Add(item, new());
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
private void CultureNames_ListChanged(
|
||||
IObservableList<string> sender,
|
||||
NotifyListChangedEventArgs<string> e
|
||||
)
|
||||
{
|
||||
if (e.Action is ListChangeAction.Add && e.NewItems is not null)
|
||||
{
|
||||
foreach (var item in e.NewItems)
|
||||
I18nDatas.TryAdd(item, new());
|
||||
}
|
||||
else if (e.Action is ListChangeAction.Remove && e.OldItems is not null)
|
||||
{
|
||||
foreach (var item in e.OldItems)
|
||||
I18nDatas.Remove(item);
|
||||
}
|
||||
else if (
|
||||
e.Action is ListChangeAction.Add
|
||||
&& e.NewItems is not null
|
||||
&& e.OldItems is not null
|
||||
)
|
||||
{
|
||||
var newItem = e.NewItems.First();
|
||||
var oldItem = e.OldItems.First();
|
||||
if (I18nDatas.ContainsKey(oldItem) is false)
|
||||
return;
|
||||
I18nDatas[newItem] = I18nDatas[oldItem];
|
||||
I18nDatas.Remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文化改变
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Current_PropertyChangedX(object? sender, PropertyChangedXEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(I18nHelper.CultureName))
|
||||
{
|
||||
if (e.NewValue is null)
|
||||
CurrentI18nData = null!;
|
||||
else if (I18nDatas.TryGetValue((string)e.NewValue, out var result))
|
||||
CurrentI18nData = result;
|
||||
}
|
||||
}
|
||||
}
|
@ -94,14 +94,14 @@ public class ModLoader
|
||||
public List<SelectText> SelectTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// I18n数据
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public Dictionary<string, I18nModInfoModel> I18nDatas { get; } = new();
|
||||
//public Dictionary<string, I18nModInfoModel> I18nDatas { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 其它I18n数据
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public Dictionary<string, Dictionary<string, string>> OtherI18nDatas { get; } = new();
|
||||
public Dictionary<string, Dictionary<string, string>> I18nDatas { get; } = new();
|
||||
|
||||
public ModLoader(DirectoryInfo path)
|
||||
{
|
||||
@ -125,15 +125,15 @@ public class ModLoader
|
||||
//MOD未加载时支持翻译
|
||||
foreach (var line in modlps.FindAllLine("lang"))
|
||||
{
|
||||
var i18nData = new I18nModInfoModel();
|
||||
if (I18nDatas.TryGetValue(line.Info, out var datas) is false)
|
||||
datas = I18nDatas[line.Info] = new();
|
||||
foreach (var sub in line)
|
||||
{
|
||||
if (sub.Name == Name)
|
||||
i18nData.Name = sub.Info;
|
||||
datas[Name] = sub.Info;
|
||||
else if (sub.Name == Intro)
|
||||
i18nData.Description = sub.Info;
|
||||
datas[Intro] = sub.Info;
|
||||
}
|
||||
I18nDatas.Add(line.Info, i18nData);
|
||||
}
|
||||
DirectoryInfo? langDirectory = null;
|
||||
foreach (DirectoryInfo di in path.EnumerateDirectories())
|
||||
@ -236,17 +236,14 @@ public class ModLoader
|
||||
}
|
||||
if (langDirectory is null)
|
||||
return;
|
||||
foreach (DirectoryInfo dis in langDirectory.EnumerateDirectories())
|
||||
foreach (var dis in langDirectory.EnumerateDirectories())
|
||||
{
|
||||
OtherI18nDatas.Add(dis.Name, new());
|
||||
I18nDatas.TryAdd(dis.Name, new());
|
||||
foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var lps = new LPS(File.ReadAllText(fi.FullName));
|
||||
foreach (var item in lps)
|
||||
{
|
||||
if (OtherI18nDatas[dis.Name].ContainsKey(item.Name) is false)
|
||||
OtherI18nDatas[dis.Name].TryAdd(item.Name, item.Info);
|
||||
}
|
||||
I18nDatas[dis.Name].TryAdd(item.Name, item.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ namespace VPet.ModMaker.Models;
|
||||
/// </summary>
|
||||
public class ModMakeHistory : IEquatable<ModMakeHistory>
|
||||
{
|
||||
public ModMakeHistory() { }
|
||||
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
@ -28,7 +30,7 @@ public class ModMakeHistory : IEquatable<ModMakeHistory>
|
||||
/// <summary>
|
||||
/// 路径
|
||||
/// </summary>
|
||||
private string _path = string.Empty;
|
||||
private string _sourcePath = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 资源路径
|
||||
@ -36,11 +38,13 @@ public class ModMakeHistory : IEquatable<ModMakeHistory>
|
||||
[Line(ignoreCase: true)]
|
||||
public string SourcePath
|
||||
{
|
||||
get => _path;
|
||||
get => _sourcePath;
|
||||
set
|
||||
{
|
||||
_path = value;
|
||||
var imagePath = Path.Combine(_path, "icon.png");
|
||||
if (string.IsNullOrWhiteSpace(_sourcePath) is false)
|
||||
Image?.CloseStream();
|
||||
_sourcePath = value;
|
||||
var imagePath = Path.Combine(_sourcePath, "icon.png");
|
||||
if (File.Exists(imagePath))
|
||||
Image = NativeUtils.LoadImageToMemoryStream(imagePath);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class AnimeModel : ObservableObjectX, ICloneable<AnimeModel>
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// ID
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media.Imaging;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet_Simulator.Core;
|
||||
using static VPet_Simulator.Core.GraphInfo;
|
||||
@ -103,7 +104,7 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// ID
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
@ -202,7 +203,7 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
public AnimeTypeModel(GraphInfo.GraphType graphType, string path)
|
||||
{
|
||||
Name = Path.GetFileName(path);
|
||||
// 为带有名字的类型设置Id
|
||||
// 为带有名字的类型设置ID
|
||||
if (graphType.IsHasNameAnime())
|
||||
ID = $"{graphType}_{Name}";
|
||||
else
|
||||
@ -643,8 +644,8 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
static void SaveAnimes(string animePath, ObservableList<AnimeModel> animes)
|
||||
{
|
||||
Directory.CreateDirectory(animePath);
|
||||
foreach (var anime in animes.EnumerateIndex())
|
||||
SaveImages(Path.Combine(animePath, anime.Index.ToString()), anime.Value);
|
||||
foreach ((var index, var anime) in animes.EnumerateIndex())
|
||||
SaveImages(Path.Combine(animePath, index.ToString()), anime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,10 +657,10 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
static void SaveImages(string imagesPath, AnimeModel model)
|
||||
{
|
||||
Directory.CreateDirectory(imagesPath);
|
||||
foreach (var image in model.Images.EnumerateIndex())
|
||||
foreach ((var index, var image) in model.Images.EnumerateIndex())
|
||||
{
|
||||
image.Value.Image.SaveToPng(
|
||||
Path.Combine(imagesPath, $"{model.ID}_{image.Index:000}_{image.Value.Duration}.png")
|
||||
image.Image.SaveToPng(
|
||||
Path.Combine(imagesPath, $"{model.ID}_{index:000}_{image.Duration}.png")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,14 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 点击文本模型
|
||||
/// </summary>
|
||||
public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
public class ClickTextModel : ObservableObjectX
|
||||
{
|
||||
public ClickTextModel() { }
|
||||
public ClickTextModel()
|
||||
{
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Add(
|
||||
new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Text), true)])
|
||||
);
|
||||
}
|
||||
|
||||
public ClickTextModel(ClickTextModel clickText)
|
||||
: this()
|
||||
@ -37,9 +42,6 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
Drink = clickText.Drink.Clone();
|
||||
Feel = clickText.Feel.Clone();
|
||||
Strength = clickText.Strength.Clone();
|
||||
foreach (var item in clickText.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public ClickTextModel(ClickText clickText)
|
||||
@ -121,6 +123,15 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region I18nData
|
||||
[AdaptIgnore]
|
||||
public string Text
|
||||
{
|
||||
get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Working
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _working = string.Empty;
|
||||
|
@ -7,6 +7,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript;
|
||||
using LinePutScript.Localization.WPF;
|
||||
@ -271,10 +272,10 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
var animePath = Path.Combine(path, Name);
|
||||
if (
|
||||
Directory.Exists(animePath)
|
||||
&& HappyAnimes.Count == 0
|
||||
&& NomalAnimes.Count == 0
|
||||
&& PoorConditionAnimes.Count == 0
|
||||
&& IllAnimes.Count == 0
|
||||
&& HappyAnimes.HasValue() is false
|
||||
&& NomalAnimes.HasValue() is false
|
||||
&& PoorConditionAnimes.HasValue() is false
|
||||
&& IllAnimes.HasValue() is false
|
||||
)
|
||||
{
|
||||
Directory.Delete(animePath, true);
|
||||
@ -303,15 +304,15 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
)
|
||||
{
|
||||
var modeAnimePath = Path.Combine(animePath, mode.ToString());
|
||||
foreach (var anime in animes.EnumerateIndex())
|
||||
foreach ((var index, var anime) in animes.EnumerateIndex())
|
||||
{
|
||||
var indexPath = Path.Combine(modeAnimePath, anime.Index.ToString());
|
||||
var indexPath = Path.Combine(modeAnimePath, index.ToString());
|
||||
Directory.CreateDirectory(indexPath);
|
||||
var infoFile = Path.Combine(indexPath, ModMakerInfo.InfoFile);
|
||||
var frontLayName = $"{Name.ToLower()}_{FrontLayName}_{anime.Index}";
|
||||
var backLayName = $"{Name.ToLower()}_{BackLayName}_{anime.Index}";
|
||||
SaveInfoFile(infoFile, frontLayName, backLayName, anime.Value, mode);
|
||||
SaveImages(anime.Value, indexPath);
|
||||
var frontLayName = $"{Name.ToLower()}_{FrontLayName}_{index}";
|
||||
var backLayName = $"{Name.ToLower()}_{BackLayName}_{index}";
|
||||
SaveInfoFile(infoFile, frontLayName, backLayName, anime, mode);
|
||||
SaveImages(anime, indexPath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,22 +329,16 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
var backLayPath = Path.Combine(indexPath, BackLayName);
|
||||
Directory.CreateDirectory(frontLayPath);
|
||||
Directory.CreateDirectory(backLayPath);
|
||||
foreach (var frontImage in anime.FrontImages.EnumerateIndex())
|
||||
foreach ((var index, var frontImage) in anime.FrontImages.EnumerateIndex())
|
||||
{
|
||||
frontImage.Value.Image.SaveToPng(
|
||||
Path.Combine(
|
||||
frontLayPath,
|
||||
$"{anime.ID}_{frontImage.Index:000}_{frontImage.Value.Duration}.png"
|
||||
)
|
||||
frontImage.Image.SaveToPng(
|
||||
Path.Combine(frontLayPath, $"{anime.ID}_{index:000}_{frontImage.Duration}.png")
|
||||
);
|
||||
}
|
||||
foreach (var backImage in anime.BackImages.EnumerateIndex())
|
||||
foreach ((var index, var backImage) in anime.BackImages.EnumerateIndex())
|
||||
{
|
||||
backImage.Value.Image.SaveToPng(
|
||||
Path.Combine(
|
||||
backLayPath,
|
||||
$"{anime.ID}_{backImage.Index:000}_{backImage.Value.Duration}.png"
|
||||
)
|
||||
backImage.Image.SaveToPng(
|
||||
Path.Combine(backLayPath, $"{anime.ID}_{backImage:000}_{backImage.Duration}.png")
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -376,10 +371,10 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
new Sub("mode", mode.ToString()),
|
||||
new Sub("graph", Name)
|
||||
};
|
||||
foreach (var foodLocation in anime.FoodLocations.EnumerateIndex())
|
||||
foreach ((var index, var foodLocation) in anime.FoodLocations.EnumerateIndex())
|
||||
{
|
||||
var sub = new Sub($"a{foodLocation.Index}");
|
||||
sub.info = foodLocation.Value.ToString();
|
||||
var sub = new Sub($"a{index}");
|
||||
sub.info = foodLocation.ToString();
|
||||
line.Add(sub);
|
||||
}
|
||||
line.Add(new Sub(FrontLayName, frontLayName));
|
||||
|
@ -21,11 +21,21 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 食物模型
|
||||
/// </summary>
|
||||
public class FoodModel : I18nModel<I18nFoodModel>
|
||||
public class FoodModel : ObservableObjectX
|
||||
{
|
||||
public FoodModel()
|
||||
{
|
||||
PropertyChangedX += FoodModel_PropertyChangedX;
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Add(
|
||||
new(
|
||||
this,
|
||||
OnPropertyChanged,
|
||||
[
|
||||
(nameof(ID), ID, nameof(Name), true),
|
||||
(nameof(DescriptionID), DescriptionID, nameof(Description), true)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static FrozenSet<string> _notifyReferencePrice = FrozenSet.ToFrozenSet(
|
||||
@ -54,9 +64,6 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
{
|
||||
model.Adapt(this);
|
||||
Image = model.Image?.CloneStream();
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public FoodModel(Food food)
|
||||
@ -108,6 +115,26 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region I18nData
|
||||
[AdaptIgnore]
|
||||
public string Name
|
||||
{
|
||||
get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
|
||||
[AdaptIgnore]
|
||||
public string Description
|
||||
{
|
||||
get =>
|
||||
ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(
|
||||
DescriptionID,
|
||||
string.Empty
|
||||
);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(DescriptionID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph = string.Empty;
|
||||
@ -310,7 +337,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
//};
|
||||
}
|
||||
|
||||
public void RefreshId()
|
||||
public void RefreshID()
|
||||
{
|
||||
DescriptionID = $"{ID}_{nameof(DescriptionID)}";
|
||||
}
|
||||
@ -318,34 +345,10 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
public void Close()
|
||||
{
|
||||
Image?.CloseStream();
|
||||
var item = ModInfoModel.Current.I18nResource.I18nObjectInfos.FirstOrDefault(i =>
|
||||
i.Source == this
|
||||
);
|
||||
if (item is not null)
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nFoodModel : ObservableObjectX, ICloneable<I18nFoodModel>
|
||||
{
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Description
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _description = string.Empty;
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nFoodModel Clone() => this.Adapt<I18nFoodModel>();
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
@ -16,18 +16,19 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 低状态文本
|
||||
/// </summary>
|
||||
public class LowTextModel : I18nModel<I18nLowTextModel>
|
||||
public class LowTextModel : ObservableObjectX
|
||||
{
|
||||
public LowTextModel() { }
|
||||
public LowTextModel()
|
||||
{
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Add(
|
||||
new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Text), true)])
|
||||
);
|
||||
}
|
||||
|
||||
public LowTextModel(LowTextModel lowText)
|
||||
: this()
|
||||
{
|
||||
lowText.Adapt(this);
|
||||
|
||||
foreach (var item in lowText.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public LowTextModel(LowText lowText)
|
||||
@ -69,6 +70,15 @@ public class LowTextModel : I18nModel<I18nLowTextModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region I18nData
|
||||
[AdaptIgnore]
|
||||
public string Text
|
||||
{
|
||||
get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Mode
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private LowText.ModeType _mode;
|
||||
@ -119,24 +129,3 @@ public class LowTextModel : I18nModel<I18nLowTextModel>
|
||||
return this.Adapt<LowText>();
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nLowTextModel : ObservableObjectX, ICloneable<I18nLowTextModel>
|
||||
{
|
||||
#region Text
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _text = string.Empty;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => _text;
|
||||
set => SetProperty(ref _text, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nLowTextModel Clone()
|
||||
{
|
||||
return this.Adapt<I18nLowTextModel>();
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -26,10 +27,11 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 模组信息模型
|
||||
/// </summary>
|
||||
public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
public class ModInfoModel : ObservableObjectX
|
||||
{
|
||||
public ModInfoModel()
|
||||
{
|
||||
Current = this;
|
||||
PropertyChanged += ModInfoModel_PropertyChanged;
|
||||
Pets.CollectionChanged += Pets_CollectionChanged;
|
||||
}
|
||||
@ -104,25 +106,22 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
LoadAnime(petModel, p);
|
||||
}
|
||||
|
||||
//loader.Pets.First().Name = "TestMainPet";
|
||||
//Pets.Insert(0, new(loader.Pets.First(), true));
|
||||
|
||||
// 插入本体宠物
|
||||
foreach (var pet in ModMakerInfo.MainPets)
|
||||
{
|
||||
// 确保Id不重复
|
||||
// 确保ID不重复
|
||||
if (Pets.All(i => i.ID != pet.Key))
|
||||
Pets.Insert(0, pet.Value);
|
||||
}
|
||||
|
||||
// 载入本地化
|
||||
foreach (var lang in loader.I18nDatas)
|
||||
I18nDatas.Add(lang.Key, lang.Value);
|
||||
OtherI18nDatas = loader.OtherI18nDatas;
|
||||
// 载入本地化模组信息
|
||||
//foreach (var lang in loader.I18nDatas)
|
||||
// I18nDatas.Add(lang.Key, lang.Value);
|
||||
//OtherI18nDatas = loader.I18nDatas;
|
||||
|
||||
LoadI18nDatas();
|
||||
RefreshAllId();
|
||||
if (I18nHelper.Current.CultureNames.HasValue())
|
||||
LoadI18nDatas(loader);
|
||||
RefreshAllID();
|
||||
if (I18nResource.CultureDatas.HasValue())
|
||||
RefreshID();
|
||||
}
|
||||
|
||||
@ -143,6 +142,21 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public static ModInfoModel Current { get; set; } = new();
|
||||
|
||||
public I18nResource<string, string> I18nResource { get; } = new();
|
||||
|
||||
#region I18nData
|
||||
public string Name
|
||||
{
|
||||
get => I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
public string Description
|
||||
{
|
||||
get => I18nResource.GetCurrentCultureDataOrDefault(DescriptionID, string.Empty);
|
||||
set => I18nResource.SetCurrentCultureData(DescriptionID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AutoSetFoodPrice
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _autoSetFoodPrice;
|
||||
@ -173,12 +187,12 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
#region ModInfo
|
||||
/// <summary>
|
||||
/// 作者Id
|
||||
/// 作者ID
|
||||
/// </summary>
|
||||
public long AuthorID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目Id
|
||||
/// 项目ID
|
||||
/// </summary>
|
||||
public ulong ItemID { get; }
|
||||
|
||||
@ -187,7 +201,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// ID
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
@ -198,15 +212,15 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
#region DescriptionID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionId = string.Empty;
|
||||
private string _descriptionID = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 描述Id
|
||||
/// 描述ID
|
||||
/// </summary>
|
||||
public string DescriptionID
|
||||
{
|
||||
get => _descriptionId;
|
||||
set => SetProperty(ref _descriptionId, value);
|
||||
get => _descriptionID;
|
||||
set => SetProperty(ref _descriptionID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -322,15 +336,6 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 其它I18n数据
|
||||
/// </summary>
|
||||
public Dictionary<string, Dictionary<string, string>> OtherI18nDatas { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 需要保存的I18n数据
|
||||
/// </summary>
|
||||
public static Dictionary<string, Dictionary<string, string>> SaveI18nDatas { get; } = new();
|
||||
#endregion
|
||||
|
||||
private void Pets_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
@ -439,100 +444,121 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// <summary>
|
||||
/// 加载本地化数据
|
||||
/// </summary>
|
||||
private void LoadI18nDatas()
|
||||
private void LoadI18nDatas(ModLoader modLoader)
|
||||
{
|
||||
foreach (var lang in I18nDatas.Keys.Union(OtherI18nDatas.Keys))
|
||||
{
|
||||
if (I18nHelper.Current.CultureNames.Contains(lang) is false)
|
||||
I18nHelper.Current.CultureNames.Add(lang);
|
||||
}
|
||||
if (I18nHelper.Current.CultureNames.Count == 0)
|
||||
if (modLoader.I18nDatas.HasValue() is false)
|
||||
return;
|
||||
I18nHelper.Current.CultureName = I18nHelper.Current.CultureNames.First();
|
||||
foreach (var i18nData in OtherI18nDatas)
|
||||
foreach (var cultureDatas in modLoader.I18nDatas)
|
||||
{
|
||||
LoadFoodI18nData(i18nData.Key, i18nData.Value);
|
||||
LoadLowTextI18nData(i18nData.Key, i18nData.Value);
|
||||
LoadClickTextI18nData(i18nData.Key, i18nData.Value);
|
||||
LoadSelectTextI18nData(i18nData.Key, i18nData.Value);
|
||||
LoadPetI18nData(i18nData.Key, i18nData.Value);
|
||||
var culture = CultureInfo.GetCultureInfo(cultureDatas.Key);
|
||||
I18nResource.AddCulture(culture);
|
||||
foreach (var data in cultureDatas.Value)
|
||||
I18nResource.AddCultureData(culture, data.Key, data.Value);
|
||||
}
|
||||
if (I18nResource.SetCurrentCulture(CultureInfo.CurrentCulture) is false)
|
||||
I18nResource.SetCurrentCulture(I18nResource.CultureDatas.First().Key);
|
||||
I18nResource.I18nObjectInfos.Add(
|
||||
new(
|
||||
this,
|
||||
OnPropertyChanged,
|
||||
[
|
||||
(nameof(ID), ID, nameof(Name), true),
|
||||
(nameof(DescriptionID), DescriptionID, nameof(Description), true)
|
||||
]
|
||||
)
|
||||
);
|
||||
//foreach (var lang in I18nDatas.Keys.Union(OtherI18nDatas.Keys))
|
||||
//{
|
||||
// if (I18nHelper.Current.CultureNames.Contains(lang) is false)
|
||||
// I18nHelper.Current.CultureNames.Add(lang);
|
||||
//}
|
||||
//if (I18nHelper.Current.CultureNames.Count == 0)
|
||||
// return;
|
||||
//I18nHelper.Current.CultureName = I18nHelper.Current.CultureNames.First();
|
||||
//foreach (var i18nData in OtherI18nDatas)
|
||||
//{
|
||||
// LoadFoodI18nData(i18nData.Key, i18nData.Value);
|
||||
// LoadLowTextI18nData(i18nData.Key, i18nData.Value);
|
||||
// LoadClickTextI18nData(i18nData.Key, i18nData.Value);
|
||||
// LoadSelectTextI18nData(i18nData.Key, i18nData.Value);
|
||||
// LoadPetI18nData(i18nData.Key, i18nData.Value);
|
||||
//}
|
||||
}
|
||||
|
||||
private void LoadFoodI18nData(string key, Dictionary<string, string> i18nData)
|
||||
//private void LoadFoodI18nData(string key, Dictionary<string, string> i18nData)
|
||||
//{
|
||||
// foreach (var food in Foods)
|
||||
// {
|
||||
// if (food.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
// continue;
|
||||
// if (i18nData.TryGetValue(food.ID, out var name))
|
||||
// data.Name = name;
|
||||
// if (i18nData.TryGetValue(food.DescriptionID, out var description))
|
||||
// data.Description = description;
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void LoadLowTextI18nData(string key, Dictionary<string, string> i18nData)
|
||||
//{
|
||||
// foreach (var lowText in LowTexts)
|
||||
// {
|
||||
// if (lowText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
// continue;
|
||||
// if (i18nData.TryGetValue(lowText.ID, out var text))
|
||||
// data.Text = text;
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void LoadClickTextI18nData(string key, Dictionary<string, string> i18nData)
|
||||
//{
|
||||
// foreach (var clickText in ClickTexts)
|
||||
// {
|
||||
// if (clickText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
// continue;
|
||||
// if (i18nData.TryGetValue(clickText.ID, out var text))
|
||||
// data.Text = text;
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void LoadSelectTextI18nData(string key, Dictionary<string, string> i18nData)
|
||||
//{
|
||||
// foreach (var selectText in SelectTexts)
|
||||
// {
|
||||
// if (selectText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
// continue;
|
||||
// if (i18nData.TryGetValue(selectText.ID, out var text))
|
||||
// data.Text = text;
|
||||
// if (i18nData.TryGetValue(selectText.ChooseID, out var choose))
|
||||
// data.Choose = choose;
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void LoadPetI18nData(string key, Dictionary<string, string> i18nData)
|
||||
//{
|
||||
// foreach (var pet in Pets)
|
||||
// {
|
||||
// if (pet.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
// continue;
|
||||
// if (i18nData.TryGetValue(pet.ID, out var name))
|
||||
// data.Name = name;
|
||||
// if (i18nData.TryGetValue(pet.PetNameID, out var petName))
|
||||
// data.PetName = petName;
|
||||
// if (i18nData.TryGetValue(pet.DescriptionID, out var description))
|
||||
// data.Description = description;
|
||||
// foreach (var work in pet.Works)
|
||||
// {
|
||||
// if (work.I18nDatas.TryGetValue(key, out var workData) is false)
|
||||
// continue;
|
||||
// if (i18nData.TryGetValue(work.ID, out var workName))
|
||||
// workData.Name = workName;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
private void RefreshAllID()
|
||||
{
|
||||
foreach (var food in Foods)
|
||||
{
|
||||
if (food.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(food.ID, out var name))
|
||||
data.Name = name;
|
||||
if (i18nData.TryGetValue(food.DescriptionID, out var description))
|
||||
data.Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadLowTextI18nData(string key, Dictionary<string, string> i18nData)
|
||||
{
|
||||
foreach (var lowText in LowTexts)
|
||||
{
|
||||
if (lowText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(lowText.ID, out var text))
|
||||
data.Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadClickTextI18nData(string key, Dictionary<string, string> i18nData)
|
||||
{
|
||||
foreach (var clickText in ClickTexts)
|
||||
{
|
||||
if (clickText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(clickText.ID, out var text))
|
||||
data.Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSelectTextI18nData(string key, Dictionary<string, string> i18nData)
|
||||
{
|
||||
foreach (var selectText in SelectTexts)
|
||||
{
|
||||
if (selectText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(selectText.ID, out var text))
|
||||
data.Text = text;
|
||||
if (i18nData.TryGetValue(selectText.ChooseID, out var choose))
|
||||
data.Choose = choose;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPetI18nData(string key, Dictionary<string, string> i18nData)
|
||||
{
|
||||
foreach (var pet in Pets)
|
||||
{
|
||||
if (pet.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(pet.ID, out var name))
|
||||
data.Name = name;
|
||||
if (i18nData.TryGetValue(pet.PetNameID, out var petName))
|
||||
data.PetName = petName;
|
||||
if (i18nData.TryGetValue(pet.DescriptionID, out var description))
|
||||
data.Description = description;
|
||||
foreach (var work in pet.Works)
|
||||
{
|
||||
if (work.I18nDatas.TryGetValue(key, out var workData) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(work.ID, out var workName))
|
||||
workData.Name = workName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshAllId()
|
||||
{
|
||||
foreach (var food in Foods)
|
||||
food.RefreshId();
|
||||
food.RefreshID();
|
||||
foreach (var selectText in SelectTexts)
|
||||
selectText.RefreshID();
|
||||
foreach (var pet in Pets)
|
||||
@ -554,7 +580,6 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// <param name="path">路径</param>
|
||||
public void SaveTo(string path)
|
||||
{
|
||||
SaveI18nDatas.Clear();
|
||||
// 保存模型信息
|
||||
SaveModInfo(path);
|
||||
// 保存模组数据
|
||||
@ -563,7 +588,6 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
SaveText(path);
|
||||
SaveI18nData(path);
|
||||
SaveImage(path);
|
||||
SaveI18nDatas.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -576,10 +600,6 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
if (File.Exists(modInfoFile) is false)
|
||||
File.Create(modInfoFile).Close();
|
||||
|
||||
SaveI18nDatas.Clear();
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
SaveI18nDatas.Add(cultureName, new());
|
||||
|
||||
var lps = new LPS()
|
||||
{
|
||||
new Line("vupmod", ID)
|
||||
@ -593,13 +613,23 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
new Line("itemid", ItemID.ToString()),
|
||||
new Line("cachedate", DateTime.Now.Date.ToString("s"))
|
||||
};
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
foreach (var cultureData in Current.I18nResource.CultureDatas)
|
||||
{
|
||||
lps.Add(
|
||||
new Line("lang", cultureName)
|
||||
new Line("cultureDatas", cultureData.Key.Name)
|
||||
{
|
||||
new Sub(ID, I18nDatas[cultureName].Name),
|
||||
new Sub(DescriptionID, I18nDatas[cultureName].Description),
|
||||
new Sub(
|
||||
ID,
|
||||
I18nResource.GetCultureDataOrDefault(cultureData.Key.Name, ID, string.Empty)
|
||||
),
|
||||
new Sub(
|
||||
DescriptionID,
|
||||
I18nResource.GetCultureDataOrDefault(
|
||||
cultureData.Key.Name,
|
||||
DescriptionID,
|
||||
string.Empty
|
||||
)
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -646,15 +676,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
File.Create(foodFile).Close();
|
||||
var lps = new LPS();
|
||||
foreach (var food in Foods)
|
||||
{
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(food.ToFood(), "food"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName].TryAdd(food.ID, food.I18nDatas[cultureName].Name);
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(food.DescriptionID, food.I18nDatas[cultureName].Description);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(foodFile, lps.ToString());
|
||||
}
|
||||
|
||||
@ -690,15 +712,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
File.Create(textFile).Close();
|
||||
var lps = new LPS();
|
||||
foreach (var text in SelectTexts)
|
||||
{
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(text.ToSelectText(), "SelectText"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName].TryAdd(text.ID, text.I18nDatas[cultureName].Text);
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(text.ChooseID, text.I18nDatas[cultureName].Choose);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(textFile, lps.ToString());
|
||||
}
|
||||
|
||||
@ -714,13 +728,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
File.Create(textFile).Close();
|
||||
var lps = new LPS();
|
||||
foreach (var text in LowTexts)
|
||||
{
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(text.ToLowText(), "lowfoodtext"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName].TryAdd(text.ID, text.I18nDatas[cultureName].Text);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(textFile, lps.ToString());
|
||||
}
|
||||
|
||||
@ -736,32 +744,26 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
File.Create(textFile).Close();
|
||||
var lps = new LPS();
|
||||
foreach (var text in ClickTexts)
|
||||
{
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(text.ToClickText(), "clicktext"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName].TryAdd(text.ID, text.I18nDatas[cultureName].Text);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(textFile, lps.ToString());
|
||||
}
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 保存I18n数据
|
||||
/// 保存I18n资源
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
private void SaveI18nData(string path)
|
||||
{
|
||||
var langPath = Path.Combine(path, "lang");
|
||||
Directory.CreateDirectory(langPath);
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
foreach (var cultureData in I18nResource.CultureDatas)
|
||||
{
|
||||
var culturePath = Path.Combine(langPath, cultureName);
|
||||
var culturePath = Path.Combine(langPath, cultureData.Key.Name);
|
||||
Directory.CreateDirectory(culturePath);
|
||||
var cultureFile = Path.Combine(culturePath, $"{cultureName}.lps");
|
||||
var cultureFile = Path.Combine(culturePath, $"{cultureData.Key.Name}.lps");
|
||||
File.Create(cultureFile).Close();
|
||||
var lps = new LPS();
|
||||
foreach (var data in SaveI18nDatas[cultureName])
|
||||
foreach (var data in cultureData.Value)
|
||||
lps.Add(new Line(data.Key, data.Value));
|
||||
File.WriteAllText(cultureFile, lps.ToString());
|
||||
}
|
||||
@ -806,7 +808,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
// 保存模型信息
|
||||
SaveModInfo(path);
|
||||
// 保存文化数据
|
||||
var langPath = Path.Combine(path, "lang");
|
||||
var langPath = Path.Combine(path, "cultureDatas");
|
||||
Directory.CreateDirectory(langPath);
|
||||
foreach (var cultureName in cultures)
|
||||
{
|
||||
@ -828,26 +830,26 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nModInfoModel : ObservableObjectX
|
||||
{
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
//public class I18nModInfoModel : ObservableObjectX
|
||||
//{
|
||||
// #region Name
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
// private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
#region Description
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _description = string.Empty;
|
||||
// public string Name
|
||||
// {
|
||||
// get => _name;
|
||||
// set => SetProperty(ref _name, value);
|
||||
// }
|
||||
// #endregion
|
||||
// #region Description
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
// private string _description = string.Empty;
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
// public string Description
|
||||
// {
|
||||
// get => _description;
|
||||
// set => SetProperty(ref _description, value);
|
||||
// }
|
||||
// #endregion
|
||||
//}
|
||||
|
@ -23,13 +23,24 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 宠物模型
|
||||
/// </summary>
|
||||
public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
public class PetModel : ObservableObjectX
|
||||
{
|
||||
public PetModel()
|
||||
{
|
||||
PropertyChanged += PetModel_PropertyChanged;
|
||||
Animes.PropertyChanged += Animes_PropertyChanged;
|
||||
FoodAnimes.PropertyChanged += FoodAnimes_PropertyChanged;
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Add(
|
||||
new(
|
||||
this,
|
||||
OnPropertyChanged,
|
||||
[
|
||||
(nameof(ID), ID, nameof(Name), true),
|
||||
(nameof(PetNameID), PetNameID, nameof(Name), true),
|
||||
(nameof(DescriptionID), DescriptionID, nameof(Description), true)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void PetModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
@ -54,10 +65,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
RaisePoint = model.RaisePoint.Clone();
|
||||
foreach (var work in model.Works)
|
||||
Works.Add(work);
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public PetModel(PetLoader loader, bool fromMain = false)
|
||||
@ -185,6 +192,37 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region I18nData
|
||||
[AdaptIgnore]
|
||||
public string Name
|
||||
{
|
||||
get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
|
||||
[AdaptIgnore]
|
||||
public string PetName
|
||||
{
|
||||
get =>
|
||||
ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(
|
||||
PetNameID,
|
||||
string.Empty
|
||||
);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(PetNameID, value);
|
||||
}
|
||||
|
||||
[AdaptIgnore]
|
||||
public string Description
|
||||
{
|
||||
get =>
|
||||
ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(
|
||||
DescriptionID,
|
||||
string.Empty
|
||||
);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(DescriptionID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Tags
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _tags = string.Empty;
|
||||
@ -344,16 +382,17 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
/// <param name="path">路径</param>
|
||||
public void Save(string path)
|
||||
{
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
ModInfoModel.SaveI18nDatas[cultureName].TryAdd(ID, I18nDatas[cultureName].Name);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(PetNameID, I18nDatas[cultureName].PetName);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(DescriptionID, I18nDatas[cultureName].Description);
|
||||
}
|
||||
// TODO
|
||||
//foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
//{
|
||||
// ModInfoModel.SaveI18nDatas[cultureName].TryAdd(ID, I18nDatas[cultureName].Name);
|
||||
// ModInfoModel
|
||||
// .SaveI18nDatas[cultureName]
|
||||
// .TryAdd(PetNameID, I18nDatas[cultureName].PetName);
|
||||
// ModInfoModel
|
||||
// .SaveI18nDatas[cultureName]
|
||||
// .TryAdd(DescriptionID, I18nDatas[cultureName].Description);
|
||||
//}
|
||||
var petFile = Path.Combine(path, $"{ID}.lps");
|
||||
if (File.Exists(petFile) is false)
|
||||
File.Create(petFile).Close();
|
||||
@ -400,13 +439,14 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
foreach (var work in Works)
|
||||
{
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(work.ToWork(), "work"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(work.ID, work.I18nDatas[cultureName].Name);
|
||||
}
|
||||
//TODO
|
||||
//lps.Add(LPSConvert.SerializeObjectToLine<Line>(work.ToWork(), "work"));
|
||||
//foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
//{
|
||||
// ModInfoModel
|
||||
// .SaveI18nDatas[cultureName]
|
||||
// .TryAdd(work.ID, work.I18nDatas[cultureName].Name);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,51 +585,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class I18nPetInfoModel : ObservableObjectX, ICloneable<I18nPetInfoModel>
|
||||
{
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
#region PetName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _petName = string.Empty;
|
||||
|
||||
public string PetName
|
||||
{
|
||||
get => _petName;
|
||||
set => SetProperty(ref _petName, value);
|
||||
}
|
||||
#endregion
|
||||
#region Description
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _description = string.Empty;
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nPetInfoModel Clone()
|
||||
{
|
||||
var result = new I18nPetInfoModel();
|
||||
result.Name = Name;
|
||||
result.PetName = PetName;
|
||||
result.Description = Description;
|
||||
return result;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
||||
public class ObservableMultiStateRectangleLocation
|
||||
: ObservableObjectX,
|
||||
IEquatable<ObservableMultiStateRectangleLocation>,
|
||||
|
@ -16,9 +16,21 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 选择文本模型
|
||||
/// </summary>
|
||||
public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
public class SelectTextModel : ObservableObjectX
|
||||
{
|
||||
public SelectTextModel() { }
|
||||
public SelectTextModel()
|
||||
{
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Add(
|
||||
new(
|
||||
this,
|
||||
OnPropertyChanged,
|
||||
[
|
||||
(nameof(ID), ID, nameof(Text), true),
|
||||
(nameof(ChooseID), ChooseID, nameof(Choose), true)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public SelectTextModel(SelectTextModel model)
|
||||
: this()
|
||||
@ -37,10 +49,6 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
Drink = model.Drink.Clone();
|
||||
Feel = model.Feel.Clone();
|
||||
Strength = model.Strength.Clone();
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public SelectTextModel(SelectText text)
|
||||
@ -126,6 +134,26 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region I18nData
|
||||
[AdaptIgnore]
|
||||
public string Text
|
||||
{
|
||||
get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
|
||||
[AdaptIgnore]
|
||||
public string Choose
|
||||
{
|
||||
get =>
|
||||
ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(
|
||||
ChooseID,
|
||||
string.Empty
|
||||
);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ChooseID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 宠物状态
|
||||
/// </summary>
|
||||
@ -212,34 +240,3 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nSelectTextModel : ObservableObjectX, ICloneable<I18nSelectTextModel>
|
||||
{
|
||||
#region Choose
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _choose = string.Empty;
|
||||
|
||||
public string Choose
|
||||
{
|
||||
get => _choose;
|
||||
set => SetProperty(ref _choose, value);
|
||||
}
|
||||
#endregion
|
||||
#region Text
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _text = string.Empty;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => _text;
|
||||
set => SetProperty(ref _text, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nSelectTextModel Clone()
|
||||
{
|
||||
return this.Adapt<I18nSelectTextModel>();
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
@ -18,11 +18,14 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 工作模型
|
||||
/// </summary>
|
||||
public class WorkModel : I18nModel<I18nWorkModel>
|
||||
public class WorkModel : ObservableObjectX
|
||||
{
|
||||
public WorkModel()
|
||||
{
|
||||
PropertyChanged += WorkModel_PropertyChanged;
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Add(
|
||||
new(this, OnPropertyChanged, [(nameof(ID), ID, nameof(Name), true)])
|
||||
);
|
||||
}
|
||||
|
||||
private static readonly FrozenSet<string> _notifyIsOverLoad = FrozenSet.ToFrozenSet(
|
||||
@ -71,9 +74,6 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
Width = model.Width;
|
||||
|
||||
//Image = model.Image?.CloneStream();
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public WorkModel(VPet_Simulator.Core.GraphHelper.Work work)
|
||||
@ -111,12 +111,12 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
public static FrozenSet<VPet_Simulator.Core.GraphHelper.Work.WorkType> WorkTypes { get; } =
|
||||
Enum.GetValues<VPet_Simulator.Core.GraphHelper.Work.WorkType>().ToFrozenSet();
|
||||
|
||||
#region Id
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// ID
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
@ -125,6 +125,15 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region I18nData
|
||||
[AdaptIgnore]
|
||||
public string Name
|
||||
{
|
||||
get => ModInfoModel.Current.I18nResource.GetCurrentCultureDataOrDefault(ID, string.Empty);
|
||||
set => ModInfoModel.Current.I18nResource.SetCurrentCultureData(ID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph = string.Empty;
|
||||
@ -450,28 +459,10 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
public void Close()
|
||||
{
|
||||
//Image?.CloseStream();
|
||||
var item = ModInfoModel.Current.I18nResource.I18nObjectInfos.FirstOrDefault(i =>
|
||||
i.Source == this
|
||||
);
|
||||
if (item is not null)
|
||||
ModInfoModel.Current.I18nResource.I18nObjectInfos.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nWorkModel : ObservableObjectX, ICloneable<I18nWorkModel>
|
||||
{
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nWorkModel Clone()
|
||||
{
|
||||
var result = new I18nWorkModel();
|
||||
result.Name = Name;
|
||||
return result;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
@ -46,9 +46,9 @@
|
||||
</ControlTemplate>
|
||||
<ControlTemplate x:Key="ListBox_ShowLangs" TargetType="ListBox">
|
||||
<ListBox
|
||||
ItemsSource="{Binding I18nData.CultureNames}"
|
||||
ItemsSource="{Binding I18nResource.CultureDatas.ObservableKeys}"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
SelectedItem="{Binding I18nData.CultureName}">
|
||||
SelectedItem="{Binding I18nResource.CurrentCulture}">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="ListBoxItem">
|
||||
<Setter Property="Content" Value="{Binding}" />
|
||||
|
@ -258,19 +258,6 @@ public static class NativeExtensions
|
||||
return weakReference.TryGetTarget(out var t) ? t : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 枚举出带有索引值的枚举值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
/// <param name="collection">集合</param>
|
||||
/// <returns>带有索引的枚举值</returns>
|
||||
public static IEnumerable<ItemInfo<T>> EnumerateIndex<T>(this IEnumerable<T> collection)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var item in collection)
|
||||
yield return new(index++, item);
|
||||
}
|
||||
|
||||
public static void SetDataContext<T>(this Window window, Action? closedAction = null)
|
||||
where T : new()
|
||||
{
|
||||
@ -304,36 +291,3 @@ public static class NativeExtensions
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 项信息
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("[{Index}, {Value}]")]
|
||||
public readonly struct ItemInfo<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 索引值
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public T Value { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="index">索引值</param>
|
||||
public ItemInfo(int index, T value)
|
||||
{
|
||||
Index = index;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Index}, {Value}]";
|
||||
}
|
||||
}
|
||||
|
@ -10,25 +10,26 @@
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<UseWPF>true</UseWPF>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\food.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="VPet-Simulator.Core" Version="1.1.0.1" />
|
||||
<PackageReference Include="VPet-Simulator.Windows.Interface" Version="1.1.0.1" />
|
||||
<PackageReference Include="VPet-Simulator.Core" Version="1.1.0.4" />
|
||||
<PackageReference Include="VPet-Simulator.Windows.Interface" Version="1.1.0.5" />
|
||||
<PackageReference Include="LinePutScript" Version="1.11.6" />
|
||||
<PackageReference Include="LinePutScript.Localization.WPF" Version="1.0.6" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
|
||||
<PackageReference Include="Panuon.WPF" Version="1.1.0" />
|
||||
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1.1" />
|
||||
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1.2" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="HKW.Utils" Version="1.2.6" />
|
||||
<PackageReference Include="HKW.WPF" Version="1.0.3" />
|
||||
<PackageReference Include="HKW.Utils" Version="1.2.13" />
|
||||
<PackageReference Include="HKW.WPF" Version="1.0.4" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -13,7 +13,10 @@ namespace VPet.ModMaker.ViewModels.ModEdit.ClickTextEdit;
|
||||
|
||||
public class ClickTextEditWindowVM : ObservableObjectX
|
||||
{
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
/// <summary>
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nResource<string, string> I18nResource => ModInfoModel.Current.I18nResource;
|
||||
|
||||
#region Value
|
||||
/// <summary>
|
||||
|
@ -25,7 +25,11 @@ public class FoodEditWindowVM : ObservableObjectX
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
|
||||
/// <summary>
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nResource<string, string> I18nResource => ModInfoModel.Current.I18nResource;
|
||||
|
||||
#region Property
|
||||
public FoodModel? OldFood { get; set; }
|
||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using Mapster;
|
||||
using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.I18nEdit;
|
||||
@ -67,12 +68,12 @@ public class I18nEditWindowVM : ObservableObjectX { }
|
||||
// #endregion
|
||||
|
||||
// /// <summary>
|
||||
// /// 全部I18n数据 (ID, I18nData)
|
||||
// /// 全部I18n资源 (ID, I18nData)
|
||||
// /// </summary>
|
||||
// public Dictionary<string, I18nData> AllI18nDatas { get; } = new();
|
||||
|
||||
// /// <summary>
|
||||
// /// 全部的I18n数据
|
||||
// /// 全部的I18n资源
|
||||
// /// </summary>
|
||||
// #region ShowI18nDatas
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -144,7 +145,7 @@ public class I18nEditWindowVM : ObservableObjectX { }
|
||||
|
||||
// #region LoadData
|
||||
// /// <summary>
|
||||
// /// 初始化I18n数据
|
||||
// /// 初始化I18n资源
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// public void InitializeI18nData(ModInfoModel model)
|
||||
@ -360,11 +361,19 @@ public class I18nEditWindowVM : ObservableObjectX { }
|
||||
// /// <param name="id"></param>
|
||||
// /// <param name="i18nModel"></param>
|
||||
// /// <param name="i18nValue"></param>
|
||||
// private void AddData<T>(string id, Func<T,string> getValue)
|
||||
// where T : , new()
|
||||
// private void AddData<TViewModel, TI18nModel>(
|
||||
// TViewModel viewModel,
|
||||
// Func<TViewModel, string> getID,
|
||||
// Action<TViewModel, string> setID,
|
||||
// Func<TI18nModel, string> getI18nData,
|
||||
// Action<TI18nModel, string> setI18nData
|
||||
// )
|
||||
// where TViewModel : I18nModel<TI18nModel>
|
||||
// where TI18nModel : ObservableObjectX, new()
|
||||
// {
|
||||
// if (AllI18nDatas.TryGetValue(id, out var outData))
|
||||
// if (AllI18nDatas.TryGetValue(getID(viewModel), out var outData))
|
||||
// {
|
||||
// AdaptMemberAttribute
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
// {
|
||||
// if (outData.Datas[culture.Index].Group is null)
|
||||
@ -379,7 +388,7 @@ public class I18nEditWindowVM : ObservableObjectX { }
|
||||
// else
|
||||
// {
|
||||
// var data = new I18nData();
|
||||
// data.ID = id.Value;
|
||||
// data.ID = getID(viewModel);
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
// data.Datas.Add(i18nValue(i18nModel.I18nDatas[culture]));
|
||||
// I18nDatas.Add(data);
|
||||
@ -417,7 +426,7 @@ public class I18nEditWindowVM : ObservableObjectX { }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 删除I18n数据
|
||||
// /// 删除I18n资源
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <param name="id"></param>
|
||||
@ -452,7 +461,7 @@ public class I18nEditWindowVM : ObservableObjectX { }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 替换I18n数据
|
||||
// /// 替换I18n资源
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <param name="id"></param>
|
||||
|
@ -13,7 +13,10 @@ namespace VPet.ModMaker.ViewModels.ModEdit.LowTextEdit;
|
||||
|
||||
public class LowTextEditWindowVM : ObservableObjectX
|
||||
{
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
/// <summary>
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nResource<string, string> I18nResource => ModInfoModel.Current.I18nResource;
|
||||
#region Value
|
||||
public LowTextModel? OldLowText { get; set; }
|
||||
|
||||
|
@ -11,6 +11,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
@ -59,9 +60,9 @@ public class ModEditWindowVM : ObservableObjectX
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// I18n数据
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
public I18nResource<string, string> I18nResource => ModInfo.I18nResource;
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
@ -163,9 +164,8 @@ public class ModEditWindowVM : ObservableObjectX
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
I18nHelper.Current.CultureNames.Add(window.ViewModel.Culture);
|
||||
if (I18nHelper.Current.CultureNames.Count == 1)
|
||||
I18nHelper.Current.CultureName = window.ViewModel.Culture;
|
||||
ModInfoModel.Current.I18nResource.AddCulture(window.ViewModel.Culture);
|
||||
ModInfoModel.Current.I18nResource.SetCurrentCulture(window.ViewModel.Culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -179,8 +179,7 @@ public class ModEditWindowVM : ObservableObjectX
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
I18nHelper.Current.CultureNames[I18nHelper.Current.CultureNames.IndexOf(oldCulture)] =
|
||||
window.ViewModel.Culture;
|
||||
ModInfoModel.Current.I18nResource.ReplaceCulture(oldCulture, window.ViewModel.Culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -197,7 +196,7 @@ public class ModEditWindowVM : ObservableObjectX
|
||||
) is MessageBoxResult.No
|
||||
)
|
||||
return;
|
||||
I18nHelper.Current.CultureNames.Remove(oldCulture);
|
||||
ModInfoModel.Current.I18nResource.RemoveCulture(oldCulture);
|
||||
}
|
||||
|
||||
public void SetMainCultureCommand_ExecuteCommand(string culture)
|
||||
@ -212,30 +211,31 @@ public class ModEditWindowVM : ObservableObjectX
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
ModInfo.I18nDatas[culture].Name = ModInfo.ID;
|
||||
ModInfo.I18nDatas[culture].Description = ModInfo.DescriptionID;
|
||||
foreach (var food in ModInfo.Foods)
|
||||
{
|
||||
food.I18nDatas[culture].Name = food.ID;
|
||||
food.I18nDatas[culture].Description = food.DescriptionID;
|
||||
}
|
||||
foreach (var text in ModInfo.LowTexts)
|
||||
text.I18nDatas[culture].Text = text.ID;
|
||||
foreach (var text in ModInfo.ClickTexts)
|
||||
text.I18nDatas[culture].Text = text.ID;
|
||||
foreach (var text in ModInfo.SelectTexts)
|
||||
{
|
||||
text.I18nDatas[culture].Text = text.ID;
|
||||
text.I18nDatas[culture].Choose = text.ChooseID;
|
||||
}
|
||||
foreach (var pet in ModInfo.Pets)
|
||||
{
|
||||
pet.I18nDatas[culture].Name = pet.ID;
|
||||
pet.I18nDatas[culture].PetName = pet.PetNameID;
|
||||
pet.I18nDatas[culture].Description = pet.DescriptionID;
|
||||
foreach (var work in pet.Works)
|
||||
work.I18nDatas[culture].Name = work.ID;
|
||||
}
|
||||
// TODO
|
||||
//ModInfo.I18nDatas[culture].Name = ModInfo.ID;
|
||||
//ModInfo.I18nDatas[culture].Description = ModInfo.DescriptionID;
|
||||
//foreach (var food in ModInfo.Foods)
|
||||
//{
|
||||
// food.I18nDatas[culture].Name = food.ID;
|
||||
// food.I18nDatas[culture].Description = food.DescriptionID;
|
||||
//}
|
||||
//foreach (var text in ModInfo.LowTexts)
|
||||
// text.I18nDatas[culture].Text = text.ID;
|
||||
//foreach (var text in ModInfo.ClickTexts)
|
||||
// text.I18nDatas[culture].Text = text.ID;
|
||||
//foreach (var text in ModInfo.SelectTexts)
|
||||
//{
|
||||
// text.I18nDatas[culture].Text = text.ID;
|
||||
// text.I18nDatas[culture].Choose = text.ChooseID;
|
||||
//}
|
||||
//foreach (var pet in ModInfo.Pets)
|
||||
//{
|
||||
// pet.I18nDatas[culture].Name = pet.ID;
|
||||
// pet.I18nDatas[culture].PetName = pet.PetNameID;
|
||||
// pet.I18nDatas[culture].Description = pet.DescriptionID;
|
||||
// foreach (var work in pet.Works)
|
||||
// work.I18nDatas[culture].Name = work.ID;
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -303,7 +303,7 @@ public class ModEditWindowVM : ObservableObjectX
|
||||
/// <returns>成功为 <see langword="true"/> 失败为 <see langword="false"/></returns>
|
||||
private bool ValidationData(ModInfoModel model)
|
||||
{
|
||||
if (I18nHelper.Current.CultureNames.Count == 0)
|
||||
if (ModInfoModel.Current.I18nResource.CultureDatas.HasValue() is false)
|
||||
{
|
||||
MessageBox.Show(
|
||||
ModEditWindow,
|
||||
|
@ -23,7 +23,10 @@ public class PetEditWindowVM : ObservableObjectX
|
||||
}
|
||||
|
||||
#region Property
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
/// <summary>
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nResource<string, string> I18nResource => ModInfoModel.Current.I18nResource;
|
||||
public PetModel? OldPet { get; set; }
|
||||
|
||||
#region Pet
|
||||
|
@ -11,7 +11,10 @@ namespace VPet.ModMaker.ViewModels.ModEdit.SelectTextEdit;
|
||||
|
||||
public class SelectTextEditWindowVM : ObservableObjectX
|
||||
{
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
/// <summary>
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nResource<string, string> I18nResource => ModInfoModel.Current.I18nResource;
|
||||
#region Value
|
||||
public SelectTextModel? OldSelectText { get; set; }
|
||||
|
||||
|
@ -92,8 +92,10 @@ public class WorkEditWindowVM : ObservableObjectX
|
||||
}
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
/// <summary>
|
||||
/// I18n资源
|
||||
/// </summary>
|
||||
public static I18nResource<string, string> I18nResource => ModInfoModel.Current.I18nResource;
|
||||
#region Property
|
||||
public PetModel CurrentPet { get; set; } = null!;
|
||||
public WorkModel? OldWork { get; set; }
|
||||
|
@ -230,7 +230,6 @@ public class ModMakerWindowVM : ObservableObjectX
|
||||
SaveHistories();
|
||||
}
|
||||
ModInfoModel.Current?.Close();
|
||||
I18nHelper.Current = new();
|
||||
ModMakerWindow.Show();
|
||||
ModMakerWindow.Activate();
|
||||
GC.Collect();
|
||||
@ -305,7 +304,6 @@ public class ModMakerWindowVM : ObservableObjectX
|
||||
ModEditWindow?.Close();
|
||||
ModEditWindow = null!;
|
||||
ModInfoModel.Current?.Close();
|
||||
I18nHelper.Current = new();
|
||||
I18nEditWindow.Current?.Close(true);
|
||||
ModMakerWindow.Show();
|
||||
ModMakerWindow.Activate();
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -51,7 +52,11 @@ public partial class AddCultureWindow : WindowX
|
||||
MessageBox.Show("文化不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (I18nHelper.Current.CultureNames.Contains(ViewModel.Culture))
|
||||
if (
|
||||
ModInfoModel.Current.I18nResource.CultureDatas.ContainsKey(
|
||||
CultureInfo.GetCultureInfo(ViewModel.Culture)
|
||||
)
|
||||
)
|
||||
{
|
||||
MessageBox.Show("此文化已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
@ -62,10 +67,8 @@ public partial class AddCultureWindow : WindowX
|
||||
|
||||
private void Hyperlink_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start(
|
||||
new ProcessStartInfo(
|
||||
"https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c"
|
||||
)
|
||||
NativeUtils.OpenLink(
|
||||
"https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<!--<Label Content="{ll:Str 动画Id}" />
|
||||
<!--<Label Content="{ll:Str 动画ID}" />
|
||||
<TextBox Grid.Column="1" />-->
|
||||
<Label Content="{ll:Str 动画类型}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Anime.GraphType}" />
|
||||
|
@ -45,7 +45,7 @@
|
||||
Style="{DynamicResource StandardComboBoxStyle}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="ComboBoxItem">
|
||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Name}" />
|
||||
<Setter Property="ToolTip" Value="{Binding Name}" />
|
||||
<Setter Property="Visibility">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource AllTrueToCollapsedConverter}">
|
||||
|
@ -58,9 +58,9 @@
|
||||
</TextBlock>
|
||||
<!--<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 动画Id(非必要)}"
|
||||
Text="{Binding Id, UpdateSourceTrigger=PropertyChanged}" />-->
|
||||
<!-- pu:TextBoxHelper.Watermark="{ll:Str 动画Id(非必要)}" -->
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 动画ID(非必要)}"
|
||||
Text="{Binding ID, UpdateSourceTrigger=PropertyChanged}" />-->
|
||||
<!-- pu:TextBoxHelper.Watermark="{ll:Str 动画ID(非必要)}" -->
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
<Grid>
|
||||
@ -538,7 +538,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<!--<Label Content="{ll:Str 动画Id}" />
|
||||
<!--<Label Content="{ll:Str 动画ID}" />
|
||||
<TextBox Grid.Column="1" />-->
|
||||
<Label Content="{ll:Str 动画类型}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Anime.GraphType}" />
|
||||
|
@ -47,7 +47,7 @@
|
||||
d:Text="这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 文本}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding ClickText.CurrentI18nData.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding ClickText.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -38,7 +38,7 @@ public partial class ClickTextEditWindow : Window
|
||||
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.ID))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.ClickText.ID))
|
||||
{
|
||||
MessageBox.Show("ID不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
@ -51,7 +51,7 @@ public partial class ClickTextEditWindow : Window
|
||||
MessageBox.Show("此ID已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.CurrentI18nData.Text))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.ClickText.Text))
|
||||
{
|
||||
MessageBox.Show("文本不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
|
@ -19,7 +19,7 @@
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 搜索ID}"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<DataGrid
|
||||
@ -53,12 +53,12 @@
|
||||
SortMemberPath="ID" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="300"
|
||||
Binding="{Binding CurrentI18nData.Text}"
|
||||
Binding="{Binding Text}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{StaticResource TextBlock_Wrap}"
|
||||
Header="{ll:Str 文本}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Text" />
|
||||
SortMemberPath="Text" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Mode.Value}"
|
||||
CanUserSort="True"
|
||||
|
@ -59,7 +59,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="Id" />
|
||||
<Label Content="ID" />
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="ID"
|
||||
@ -82,14 +82,14 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 食物名称}"
|
||||
Text="{Binding Food.CurrentI18nData.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Food.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="4" Content="{ll:Str 食物描述}" />
|
||||
<TextBox
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 食物描述}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding Food.CurrentI18nData.Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Food.Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
@ -74,12 +74,12 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Name}"
|
||||
Binding="{Binding Name}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 食物名称}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Name" />
|
||||
SortMemberPath="Name" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Type}"
|
||||
CanUserSort="True"
|
||||
@ -152,12 +152,12 @@
|
||||
SortMemberPath="Price" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="300"
|
||||
Binding="{Binding CurrentI18nData.Description}"
|
||||
Binding="{Binding Description}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_Wrap}"
|
||||
Header="{ll:Str 描述}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Description" />
|
||||
SortMemberPath="Description" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button
|
||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using Panuon.WPF.UI;
|
||||
using VPet.ModMaker.Models;
|
||||
@ -89,10 +90,7 @@ public partial class I18nEditWindow : WindowX
|
||||
/// <param name="culture"></param>
|
||||
public void AddCulture(string culture)
|
||||
{
|
||||
var dataPath = string.Format(
|
||||
ValueBindingFormat,
|
||||
I18nHelper.Current.CultureNames.IndexOf(culture)
|
||||
);
|
||||
var dataPath = string.Format(ValueBindingFormat, culture);
|
||||
// 文化数据列
|
||||
var column = new DataGridTextColumn()
|
||||
{
|
||||
@ -118,8 +116,7 @@ public partial class I18nEditWindow : WindowX
|
||||
_dataGridI18nColumns.Remove(culture);
|
||||
foreach (var columnData in _dataGridI18nColumns)
|
||||
{
|
||||
var index = I18nHelper.Current.CultureNames.IndexOf(columnData.Key);
|
||||
var dataPath = string.Format(ValueBindingFormat, index);
|
||||
var dataPath = string.Format(ValueBindingFormat, culture);
|
||||
columnData.Value.Binding = new Binding(dataPath) { Mode = BindingMode.TwoWay };
|
||||
columnData.Value.SortMemberPath = dataPath;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
d:Text="这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 文本}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding LowText.CurrentI18nData.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding LowText.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -39,7 +39,7 @@ public partial class LowTextEditWindow : Window
|
||||
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.LowText.ID))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.LowText.ID))
|
||||
{
|
||||
MessageBox.Show("ID不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
@ -52,7 +52,7 @@ public partial class LowTextEditWindow : Window
|
||||
MessageBox.Show("此ID已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(ViewModel.LowText.CurrentI18nData.Text))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.LowText.Text))
|
||||
{
|
||||
MessageBox.Show("文本不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
|
@ -54,12 +54,12 @@
|
||||
SortMemberPath="ID" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="300"
|
||||
Binding="{Binding CurrentI18nData.Text}"
|
||||
Binding="{Binding Text}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{StaticResource TextBlock_Wrap}"
|
||||
Header="{ll:Str 文本}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Text" />
|
||||
SortMemberPath="Text" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Mode}"
|
||||
CanUserSort="True"
|
||||
|
@ -119,7 +119,7 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 模组名称}"
|
||||
Text="{Binding ModInfo.CurrentI18nData.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding ModInfo.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="5" Content="{ll:Str 模组介绍}" />
|
||||
<TextBox
|
||||
x:Name="TextBox_Description"
|
||||
@ -129,7 +129,7 @@
|
||||
VerticalContentAlignment="Top"
|
||||
d:Text="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 模组介绍}"
|
||||
Text="{Binding ModInfo.CurrentI18nData.Description, UpdateSourceTrigger=PropertyChanged}"
|
||||
Text="{Binding ModInfo.Description, UpdateSourceTrigger=PropertyChanged}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
@ -279,9 +279,9 @@
|
||||
x:Name="ListBox_Cultures"
|
||||
Grid.Row="1"
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
ItemsSource="{Binding I18nData.CultureNames}"
|
||||
ItemsSource="{Binding I18nResource.CultureDatas.ObservableKeys}"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
SelectedItem="{Binding I18nData.CultureName}">
|
||||
SelectedItem="{Binding I18nResource.CurrentCulture}">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="ListBoxItem">
|
||||
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
|
||||
|
@ -16,6 +16,7 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using Panuon.WPF;
|
||||
@ -72,7 +73,7 @@ public partial class ModEditWindow : WindowX
|
||||
/// </summary>
|
||||
public void InitializeData()
|
||||
{
|
||||
if (I18nHelper.Current.CultureNames.Count == 0)
|
||||
if (ModInfoModel.Current.I18nResource.CultureDatas.HasValue() is false)
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("未添加任何文化,确定要添加文化吗?".Translate(), "", MessageBoxButton.YesNo)
|
||||
@ -81,16 +82,20 @@ public partial class ModEditWindow : WindowX
|
||||
return;
|
||||
ViewModel.AddCultureCommand_ExecuteCommand();
|
||||
if (
|
||||
I18nHelper.Current.CultureNames.Count == 0
|
||||
ModInfoModel.Current.I18nResource.CultureDatas.HasValue() is false
|
||||
|| MessageBox.Show(
|
||||
"需要将文化 {0} 设为主要文化吗?".Translate(I18nHelper.Current.CultureNames.First()),
|
||||
"需要将文化 {0} 设为主要文化吗?".Translate(
|
||||
ModInfoModel.Current.I18nResource.CultureDatas.First().Key.Name
|
||||
),
|
||||
"",
|
||||
MessageBoxButton.YesNo
|
||||
)
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
ViewModel.SetMainCultureCommand_ExecuteCommand(I18nHelper.Current.CultureNames.First());
|
||||
ViewModel.SetMainCultureCommand_ExecuteCommand(
|
||||
ModInfoModel.Current.I18nResource.CultureDatas.First().Key.Name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
||||
<TextBox
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Text="{Binding Pet.CurrentI18nData.Description}" />-->
|
||||
Text="{Binding Pet.Description}" />-->
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
|
@ -45,7 +45,7 @@
|
||||
Style="{DynamicResource StandardComboBoxStyle}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="ComboBoxItem">
|
||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Name}" />
|
||||
<Setter Property="ToolTip" Value="{Binding Name}" />
|
||||
<Setter Property="Visibility">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource AllTrueToCollapsedConverter}">
|
||||
|
@ -368,26 +368,26 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 名称}"
|
||||
Text="{Binding Pet.CurrentI18nData.Name, UpdateSourceTrigger=PropertyChanged}" />-->
|
||||
Text="{Binding Pet.Name, UpdateSourceTrigger=PropertyChanged}" />-->
|
||||
<Label Grid.Row="2" Content="{ll:Str 名称}" />
|
||||
<TextBox
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 名称}"
|
||||
Text="{Binding Pet.CurrentI18nData.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Pet.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="3" Content="{ll:Str 宠物名称}" />
|
||||
<TextBox
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 宠物名称}"
|
||||
Text="{Binding Pet.CurrentI18nData.PetName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Pet.PetName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="4" Content="{ll:Str 描述}" />
|
||||
<TextBox
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 描述}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding Pet.CurrentI18nData.Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Pet.Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
|
@ -49,15 +49,15 @@ public partial class PetEditWindow : Window
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Pet.ID))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBox.Show("ID不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Pet.CurrentI18nData.Name))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Pet.Name))
|
||||
{
|
||||
MessageBox.Show("名称不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Pet.CurrentI18nData.PetName))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Pet.PetName))
|
||||
{
|
||||
MessageBox.Show(
|
||||
"宠物名称不可为空".Translate(),
|
||||
@ -72,7 +72,7 @@ public partial class PetEditWindow : Window
|
||||
&& ModInfoModel.Current.Pets.Any(i => i.ID == ViewModel.Pet.ID)
|
||||
)
|
||||
{
|
||||
MessageBox.Show("此Id已存在", "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBox.Show("此ID已存在", "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
IsCancel = false;
|
||||
|
@ -82,19 +82,19 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Name}"
|
||||
Binding="{Binding Name}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 名称}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Name" />
|
||||
SortMemberPath="Name" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.PetName}"
|
||||
Binding="{Binding PetName}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 宠物名称}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Name" />
|
||||
SortMemberPath="Name" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Tags}"
|
||||
CanUserSort="True"
|
||||
@ -103,12 +103,12 @@
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Tags" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Description}"
|
||||
Binding="{Binding Description}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 描述}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Description" />
|
||||
SortMemberPath="Description" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button
|
||||
|
@ -50,7 +50,7 @@
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 显示在选项列表中的名称}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding SelectText.CurrentI18nData.Choose, UpdateSourceTrigger=PropertyChanged}"
|
||||
Text="{Binding SelectText.Choose, UpdateSourceTrigger=PropertyChanged}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<TextBox
|
||||
@ -59,7 +59,7 @@
|
||||
d:Text="这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 文本}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding SelectText.CurrentI18nData.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding SelectText.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -48,7 +48,7 @@ public partial class SelectTextEditWindow : Window
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.SelectText.ID))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBox.Show("ID不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
@ -56,10 +56,10 @@ public partial class SelectTextEditWindow : Window
|
||||
&& ModInfoModel.Current.SelectTexts.Any(i => i.ID == ViewModel.SelectText.ID)
|
||||
)
|
||||
{
|
||||
MessageBox.Show("此Id已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBox.Show("此ID已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.SelectText.CurrentI18nData.Choose))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.SelectText.Choose))
|
||||
{
|
||||
MessageBox.Show(
|
||||
"选项名不可为空".Translate(),
|
||||
@ -69,7 +69,7 @@ public partial class SelectTextEditWindow : Window
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.SelectText.CurrentI18nData.Text))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.SelectText.Text))
|
||||
{
|
||||
MessageBox.Show("文本不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
|
@ -53,20 +53,20 @@
|
||||
SortMemberPath="ID" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="300"
|
||||
Binding="{Binding CurrentI18nData.Text}"
|
||||
Binding="{Binding Text}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{StaticResource TextBlock_Wrap}"
|
||||
Header="{ll:Str 文本}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Text" />
|
||||
SortMemberPath="Text" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="200"
|
||||
Binding="{Binding CurrentI18nData.Choose}"
|
||||
Binding="{Binding Choose}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 选择名}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Choose" />
|
||||
SortMemberPath="Choose" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="200"
|
||||
Binding="{Binding Tags}"
|
||||
|
@ -132,7 +132,7 @@
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Text="{Binding Work.CurrentI18nData.Name}" />
|
||||
Text="{Binding Work.Name}" />
|
||||
<Label Grid.Row="2" Content="{ll:Str 类型}" />
|
||||
<ComboBox
|
||||
Grid.Row="2"
|
||||
@ -163,7 +163,7 @@
|
||||
<TextBox
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Text="{Binding Pet.CurrentI18nData.Description}" />-->
|
||||
Text="{Binding Pet.Description}" />-->
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
|
@ -48,7 +48,7 @@
|
||||
Style="{DynamicResource StandardComboBoxStyle}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="ComboBoxItem">
|
||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Name}" />
|
||||
<Setter Property="ToolTip" Value="{Binding Name}" />
|
||||
<Setter Property="Visibility">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource AllTrueToCollapsedConverter}">
|
||||
@ -111,12 +111,12 @@
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="ID" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Name}"
|
||||
Binding="{Binding Name}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 工作名称}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Name" />
|
||||
SortMemberPath="Name" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding WorkType}"
|
||||
CanUserSort="True"
|
||||
|
Loading…
Reference in New Issue
Block a user