mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
# 更新
- 完全重构 - 添加版本升级提示(109->11000)
This commit is contained in:
parent
75951b92d6
commit
0fe086bd8b
@ -12,6 +12,9 @@
|
||||
<c:EqualsMultiConverter x:Key="EqualsConverter" />
|
||||
<c:EqualsMultiConverter x:Key="NotEqualsConverter" IsInverted="True" />
|
||||
<c:NullToBoolConverter x:Key="NullToFalseConverter" />
|
||||
<c:AllBoolToVisibilityMultiConverter x:Key="AllTrueToCollapsedConverter" />
|
||||
<c:AllBoolToVisibilityMultiConverter
|
||||
x:Key="AllTrueToCollapsedConverter"
|
||||
FalseValue="Visible"
|
||||
TrueValue="Collapsed" />
|
||||
<c:BoolInverteConverter x:Key="BoolInverter" />
|
||||
</ResourceDictionary>
|
@ -32,5 +32,5 @@ public class I18nData : ObservableObjectX<I18nData>
|
||||
/// <summary>
|
||||
/// 基于 <see cref="I18nHelper.Current.CultureNames"/> 的索引的数据列表
|
||||
/// </summary>
|
||||
public ObservableCollection<ObservableValue<string>> Datas { get; } = new();
|
||||
public ObservableList<ObservableValue<string>> Datas { get; } = new();
|
||||
}
|
||||
|
@ -12,23 +12,23 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 模组制作历史
|
||||
/// </summary>
|
||||
public class ModMakeHistory
|
||||
public class ModMakeHistory : IEquatable<ModMakeHistory>
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public BitmapImage Image { get; set; }
|
||||
public BitmapImage? Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
[Line(ignoreCase: true)]
|
||||
public string Id { get; set; }
|
||||
public string ID { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
/// </summary>
|
||||
private string _path;
|
||||
private string _path = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 资源路径
|
||||
@ -56,4 +56,20 @@ public class ModMakeHistory
|
||||
/// </summary>
|
||||
[Line(ignoreCase: true)]
|
||||
public DateTime LastTime { get; set; } = DateTime.Now;
|
||||
|
||||
public bool Equals(ModMakeHistory? other)
|
||||
{
|
||||
return SourcePath.Equals(other?.SourcePath);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return Equals(obj as ModMakeHistory);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return SourcePath.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public class ModMaker : MainPlugin
|
||||
//public ILine Set;
|
||||
public override string PluginName => "ModMaker";
|
||||
|
||||
public ModMakerWindow Maker;
|
||||
public ModMakerWindow Maker = null!;
|
||||
|
||||
public ModMaker(IMainWindow mainwin)
|
||||
: base(mainwin) { }
|
||||
@ -61,8 +61,8 @@ public class ModMaker : MainPlugin
|
||||
}
|
||||
}
|
||||
|
||||
private void Maker_Closed(object sender, EventArgs e)
|
||||
private void Maker_Closed(object? sender, EventArgs e)
|
||||
{
|
||||
Maker = null;
|
||||
Maker = null!;
|
||||
}
|
||||
}
|
||||
|
@ -10,16 +10,34 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
/// <summary>
|
||||
/// 动画模型
|
||||
/// </summary>
|
||||
public class AnimeModel : ObservableObjectX<AnimeModel>
|
||||
public class AnimeModel : ObservableObjectX<AnimeModel>, ICloneable<AnimeModel>
|
||||
{
|
||||
#region Id
|
||||
public AnimeModel() { }
|
||||
|
||||
public AnimeModel(string imagesPath)
|
||||
: this()
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(imagesPath))
|
||||
{
|
||||
var info = Path.GetFileNameWithoutExtension(file).Split(NativeUtils.Separator);
|
||||
ID = info[0];
|
||||
var duration = info.Last();
|
||||
var imageModel = new ImageModel(
|
||||
NativeUtils.LoadImageToMemoryStream(file),
|
||||
int.Parse(duration)
|
||||
);
|
||||
Images.Add(imageModel);
|
||||
}
|
||||
}
|
||||
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string Id
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
@ -43,40 +61,24 @@ public class AnimeModel : ObservableObjectX<AnimeModel>
|
||||
/// <summary>
|
||||
/// 图像列表
|
||||
/// </summary>
|
||||
public ObservableCollection<ImageModel> Images { get; } = new();
|
||||
|
||||
public AnimeModel() { }
|
||||
|
||||
public AnimeModel(string imagesPath)
|
||||
: this()
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(imagesPath))
|
||||
{
|
||||
var info = Path.GetFileNameWithoutExtension(file).Split(NativeUtils.Separator);
|
||||
Id = info[0];
|
||||
var duration = info.Last();
|
||||
var imageModel = new ImageModel(
|
||||
NativeUtils.LoadImageToMemoryStream(file),
|
||||
int.Parse(duration)
|
||||
);
|
||||
Images.Add(imageModel);
|
||||
}
|
||||
}
|
||||
public ObservableList<ImageModel> Images { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 复制
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public AnimeModel Copy()
|
||||
public AnimeModel Clone()
|
||||
{
|
||||
var model = new AnimeModel();
|
||||
model.Id = Id;
|
||||
model.ID = ID;
|
||||
model.AnimeType = AnimeType;
|
||||
foreach (var image in Images)
|
||||
model.Images.Add(image.Copy());
|
||||
model.Images.Add(image.Clone());
|
||||
return model;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
|
||||
/// <summary>
|
||||
/// 关闭所有图像流
|
||||
/// </summary>
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -16,64 +18,94 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
{
|
||||
public AnimeTypeModel()
|
||||
{
|
||||
PropertyChanged += AnimeTypeModel_PropertyChanged;
|
||||
}
|
||||
|
||||
private void AnimeTypeModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(Name))
|
||||
{
|
||||
ID = $"{GraphType}_{Name}";
|
||||
}
|
||||
}
|
||||
|
||||
public AnimeTypeModel(AnimeTypeModel model)
|
||||
: this()
|
||||
{
|
||||
ID = model.ID;
|
||||
Name = model.Name;
|
||||
GraphType = model.GraphType;
|
||||
foreach (var anime in model.HappyAnimes)
|
||||
HappyAnimes.Add(anime.Clone());
|
||||
foreach (var anime in model.NomalAnimes)
|
||||
NomalAnimes.Add(anime.Clone());
|
||||
foreach (var anime in model.PoorConditionAnimes)
|
||||
PoorConditionAnimes.Add(anime.Clone());
|
||||
foreach (var anime in model.IllAnimes)
|
||||
IllAnimes.Add(anime.Clone());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动作类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<GraphInfo.GraphType> GraphTypes { get; } =
|
||||
new(Enum.GetValues<GraphInfo.GraphType>());
|
||||
public static FrozenSet<GraphInfo.GraphType> GraphTypes { get; } =
|
||||
Enum.GetValues<GraphInfo.GraphType>().ToFrozenSet();
|
||||
|
||||
/// <summary>
|
||||
/// 动画类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<GraphInfo.AnimatType> AnimatTypes { get; } =
|
||||
new(Enum.GetValues(typeof(GraphInfo.AnimatType)).Cast<GraphInfo.AnimatType>());
|
||||
public static FrozenSet<GraphInfo.AnimatType> AnimatTypes { get; } =
|
||||
Enum.GetValues<GraphInfo.AnimatType>().ToFrozenSet();
|
||||
|
||||
/// <summary>
|
||||
/// 模式类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<ModeType> ModeTypes { get; } =
|
||||
new(Enum.GetValues(typeof(ModeType)).Cast<ModeType>());
|
||||
public static FrozenSet<ModeType> ModeTypes { get; } = Enum.GetValues<ModeType>().ToFrozenSet();
|
||||
|
||||
/// <summary>
|
||||
/// 含有名称的动作列表
|
||||
/// </summary>
|
||||
public static HashSet<GraphInfo.GraphType> HasNameAnimes { get; } =
|
||||
new()
|
||||
{
|
||||
GraphInfo.GraphType.Common,
|
||||
GraphInfo.GraphType.Work,
|
||||
GraphInfo.GraphType.Idel,
|
||||
GraphInfo.GraphType.Move,
|
||||
GraphInfo.GraphType.Say
|
||||
};
|
||||
public static FrozenSet<GraphInfo.GraphType> HasNameAnimes { get; } =
|
||||
FrozenSet.ToFrozenSet(
|
||||
[
|
||||
GraphInfo.GraphType.Common,
|
||||
GraphInfo.GraphType.Work,
|
||||
GraphInfo.GraphType.Idel,
|
||||
GraphInfo.GraphType.Move,
|
||||
GraphInfo.GraphType.Say
|
||||
]
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 含有不同动画类型的动作列表
|
||||
/// </summary>
|
||||
public static HashSet<GraphInfo.GraphType> HasMultiTypeAnimes { get; } =
|
||||
new()
|
||||
{
|
||||
GraphInfo.GraphType.Touch_Head,
|
||||
GraphInfo.GraphType.Touch_Body,
|
||||
GraphInfo.GraphType.Sleep,
|
||||
GraphInfo.GraphType.Raised_Static,
|
||||
GraphInfo.GraphType.StateONE,
|
||||
GraphInfo.GraphType.StateTWO,
|
||||
GraphInfo.GraphType.Common,
|
||||
GraphInfo.GraphType.Work,
|
||||
GraphInfo.GraphType.Idel,
|
||||
GraphInfo.GraphType.Move,
|
||||
GraphInfo.GraphType.Say
|
||||
};
|
||||
public static FrozenSet<GraphInfo.GraphType> HasMultiTypeAnimes { get; } =
|
||||
FrozenSet.ToFrozenSet(
|
||||
[
|
||||
GraphInfo.GraphType.Touch_Head,
|
||||
GraphInfo.GraphType.Touch_Body,
|
||||
GraphInfo.GraphType.Sleep,
|
||||
GraphInfo.GraphType.Raised_Static,
|
||||
GraphInfo.GraphType.StateONE,
|
||||
GraphInfo.GraphType.StateTWO,
|
||||
GraphInfo.GraphType.Common,
|
||||
GraphInfo.GraphType.Work,
|
||||
GraphInfo.GraphType.Idel,
|
||||
GraphInfo.GraphType.Move,
|
||||
GraphInfo.GraphType.Say
|
||||
]
|
||||
);
|
||||
|
||||
#region Id
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string Id
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
@ -82,7 +114,7 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name;
|
||||
private string _name = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
@ -96,61 +128,37 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
|
||||
#region GraphType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private GraphInfo.GraphType _GraphType;
|
||||
private GraphInfo.GraphType _graphType;
|
||||
|
||||
/// <summary>
|
||||
/// 动作类型
|
||||
/// </summary>
|
||||
public GraphInfo.GraphType GraphType
|
||||
{
|
||||
get => _GraphType;
|
||||
set => SetProperty(ref _GraphType, value);
|
||||
get => _graphType;
|
||||
set => SetProperty(ref _graphType, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 开心动画
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeModel> HappyAnimes { get; } = new();
|
||||
public ObservableList<AnimeModel> HappyAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 普通动画 (默认)
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeModel> NomalAnimes { get; } = new();
|
||||
public ObservableList<AnimeModel> NomalAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 低状态动画
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeModel> PoorConditionAnimes { get; } = new();
|
||||
public ObservableList<AnimeModel> PoorConditionAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 生病动画
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public AnimeTypeModel()
|
||||
{ //TODO
|
||||
//Name.ValueChanged += (_, _) =>
|
||||
//{
|
||||
// Id.Value = $"{GraphType.Value}_{Name.Value}";
|
||||
//};
|
||||
}
|
||||
|
||||
public AnimeTypeModel(AnimeTypeModel model)
|
||||
: this()
|
||||
{
|
||||
Id = model.Id;
|
||||
Name = model.Name;
|
||||
GraphType = model.GraphType;
|
||||
foreach (var anime in model.HappyAnimes)
|
||||
HappyAnimes.Add(anime.Copy());
|
||||
foreach (var anime in model.NomalAnimes)
|
||||
NomalAnimes.Add(anime.Copy());
|
||||
foreach (var anime in model.PoorConditionAnimes)
|
||||
PoorConditionAnimes.Add(anime.Copy());
|
||||
foreach (var anime in model.IllAnimes)
|
||||
IllAnimes.Add(anime.Copy());
|
||||
}
|
||||
public ObservableList<AnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 创建动画类型模型
|
||||
@ -196,9 +204,9 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
Name = Path.GetFileName(path);
|
||||
// 为带有名字的类型设置Id
|
||||
if (graphType.IsHasNameAnime())
|
||||
Id = $"{graphType}_{Name}";
|
||||
ID = $"{graphType}_{Name}";
|
||||
else
|
||||
Id = graphType.ToString();
|
||||
ID = graphType.ToString();
|
||||
GraphType = graphType;
|
||||
if (
|
||||
graphType
|
||||
@ -389,7 +397,7 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="animatType">动画类型</param>
|
||||
private static void AddAnime(
|
||||
ObservableCollection<AnimeModel> collection,
|
||||
ObservableList<AnimeModel> collection,
|
||||
string path,
|
||||
GraphInfo.AnimatType animatType = AnimatType.Single
|
||||
)
|
||||
@ -572,7 +580,7 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
SaveAnimes(modePath, animeTypeModel.IllAnimes);
|
||||
}
|
||||
|
||||
static void SaveAnimes(string animePath, ObservableCollection<AnimeModel> animes)
|
||||
static void SaveAnimes(string animePath, ObservableList<AnimeModel> animes)
|
||||
{
|
||||
Directory.CreateDirectory(animePath);
|
||||
var countA = 0;
|
||||
@ -632,7 +640,7 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
var modePath = Path.Combine(animePath, nameof(ModeType.Ill));
|
||||
SaveAnimes(modePath, animeType.IllAnimes);
|
||||
}
|
||||
static void SaveAnimes(string animePath, ObservableCollection<AnimeModel> animes)
|
||||
static void SaveAnimes(string animePath, ObservableList<AnimeModel> animes)
|
||||
{
|
||||
Directory.CreateDirectory(animePath);
|
||||
foreach (var anime in animes.EnumerateIndex())
|
||||
@ -651,7 +659,7 @@ public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
foreach (var image in model.Images.EnumerateIndex())
|
||||
{
|
||||
image.Value.Image.SaveToPng(
|
||||
Path.Combine(imagesPath, $"{model.Id}_{image.Index:000}_{image.Value.Duration}.png")
|
||||
Path.Combine(imagesPath, $"{model.ID}_{image.Index:000}_{image.Value.Duration}.png")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,12 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
/// <summary>
|
||||
/// 食物图像位置模型
|
||||
/// </summary>
|
||||
public class FoodAnimeLocationModel : ObservableObjectX<FoodAnimeLocationModel>
|
||||
public class FoodAnimeLocationModel
|
||||
: ObservableObjectX<FoodAnimeLocationModel>,
|
||||
ICloneable<FoodAnimeLocationModel>
|
||||
{
|
||||
public FoodAnimeLocationModel() { }
|
||||
|
||||
#region Duration
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _duration;
|
||||
@ -30,7 +34,7 @@ public class FoodAnimeLocationModel : ObservableObjectX<FoodAnimeLocationModel>
|
||||
/// <summary>
|
||||
/// 范围
|
||||
/// </summary>
|
||||
public ObservableRectangleLocation<double> Rect { get; set; } = new();
|
||||
public ObservableRectangleLocation<double> RectangleLocation { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 旋转角度
|
||||
@ -59,27 +63,27 @@ public class FoodAnimeLocationModel : ObservableObjectX<FoodAnimeLocationModel>
|
||||
set => SetProperty(ref _opacity, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public FoodAnimeLocationModel()
|
||||
public FoodAnimeLocationModel Clone()
|
||||
{
|
||||
Rect.PropertyChangedX += (s, e) =>
|
||||
var model = new FoodAnimeLocationModel
|
||||
{
|
||||
Rect.Height = (int)e.NewValue;
|
||||
Duration = Duration,
|
||||
RectangleLocation = new(
|
||||
RectangleLocation.X,
|
||||
RectangleLocation.Y,
|
||||
RectangleLocation.Width,
|
||||
RectangleLocation.Width
|
||||
),
|
||||
Rotate = Rotate,
|
||||
Opacity = Opacity
|
||||
};
|
||||
}
|
||||
|
||||
public FoodAnimeLocationModel Copy()
|
||||
{
|
||||
var model = new FoodAnimeLocationModel();
|
||||
model.Duration = Duration;
|
||||
model.Rect = new(Rect.X, Rect.Y, Rect.Width, Rect.Height);
|
||||
model.Rotate = Rotate;
|
||||
model.Opacity = Opacity;
|
||||
return model;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Duration}, {Rect.X}, {Rect.Y}, {Rect.Width}, {Rotate}, {Opacity}";
|
||||
return $"{Duration}, {RectangleLocation.X}, {RectangleLocation.Y}, {RectangleLocation.Width}, {Rotate}, {Opacity}";
|
||||
}
|
||||
}
|
||||
|
@ -13,42 +13,14 @@ using static VPet_Simulator.Core.IGameSave;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class FoodAnimeModel : ObservableObjectX<FoodAnimeModel>
|
||||
public class FoodAnimeModel : ObservableObjectX<FoodAnimeModel>, ICloneable<FoodAnimeModel>
|
||||
{
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _Id;
|
||||
|
||||
public string Id
|
||||
{
|
||||
get => _Id;
|
||||
set => SetProperty(ref _Id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableValue<ModeType> Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 后图像列表
|
||||
/// </summary>
|
||||
public ObservableCollection<ImageModel> BackImages { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 前图像列表
|
||||
/// </summary>
|
||||
public ObservableCollection<ImageModel> FrontImages { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 食物定位列表
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeLocationModel> FoodLocations { get; } = new();
|
||||
|
||||
public FoodAnimeModel() { }
|
||||
|
||||
public FoodAnimeModel(ILine line)
|
||||
: this()
|
||||
{
|
||||
foreach (var item in line.Where(i => i.Name.StartsWith("a")))
|
||||
foreach (var item in line.Where(i => i.Name.StartsWith('a')))
|
||||
{
|
||||
//var index = int.Parse(item.Name.Substring(1));
|
||||
var infos = item.Info.Split(',');
|
||||
@ -56,7 +28,7 @@ public class FoodAnimeModel : ObservableObjectX<FoodAnimeModel>
|
||||
foodLocationInfo.Duration = int.Parse(infos[0]);
|
||||
if (infos.Length > 1)
|
||||
{
|
||||
foodLocationInfo.Rect = new(
|
||||
foodLocationInfo.RectangleLocation = new(
|
||||
double.Parse(infos[1]),
|
||||
double.Parse(infos[2]),
|
||||
double.Parse(infos[3]),
|
||||
@ -71,23 +43,53 @@ public class FoodAnimeModel : ObservableObjectX<FoodAnimeModel>
|
||||
}
|
||||
}
|
||||
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableValue<ModeType> Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 后图像列表
|
||||
/// </summary>
|
||||
public ObservableList<ImageModel> BackImages { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 前图像列表
|
||||
/// </summary>
|
||||
public ObservableList<ImageModel> FrontImages { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 食物定位列表
|
||||
/// </summary>
|
||||
public ObservableList<FoodAnimeLocationModel> FoodLocations { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 复制
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public FoodAnimeModel Copy()
|
||||
public FoodAnimeModel Clone()
|
||||
{
|
||||
var model = new FoodAnimeModel();
|
||||
model.Id = Id;
|
||||
model.ID = ID;
|
||||
foreach (var image in FrontImages)
|
||||
model.FrontImages.Add(image.Copy());
|
||||
model.FrontImages.Add(image.Clone());
|
||||
foreach (var image in BackImages)
|
||||
model.BackImages.Add(image.Copy());
|
||||
model.BackImages.Add(image.Clone());
|
||||
foreach (var foodLocation in FoodLocations)
|
||||
model.FoodLocations.Add(foodLocation.Copy());
|
||||
model.FoodLocations.Add(foodLocation.Clone());
|
||||
return model;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
|
||||
/// <summary>
|
||||
/// 关闭所有图像流
|
||||
/// </summary>
|
||||
|
@ -17,6 +17,8 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
{
|
||||
public FoodAnimeTypeModel() { }
|
||||
|
||||
/// <summary>
|
||||
/// 动作类型
|
||||
/// </summary>
|
||||
@ -38,11 +40,11 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
/// </summary>
|
||||
public const string BackLayName = "back_lay";
|
||||
|
||||
#region Id
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
public string Id
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
@ -59,37 +61,34 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _name, value) is false)
|
||||
return;
|
||||
ID = $"{GraphType}_{Name}";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 开心动画
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeModel> HappyAnimes { get; } = new();
|
||||
public ObservableList<FoodAnimeModel> HappyAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 普通动画 (默认)
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeModel> NomalAnimes { get; } = new();
|
||||
public ObservableList<FoodAnimeModel> NomalAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 低状态动画
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeModel> PoorConditionAnimes { get; } = new();
|
||||
public ObservableList<FoodAnimeModel> PoorConditionAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 生病动画
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public FoodAnimeTypeModel()
|
||||
{ //TODO
|
||||
//Name.ValueChanged += (_, _) =>
|
||||
//{
|
||||
// Id.Value = $"{GraphType}_{Name.Value}";
|
||||
//};
|
||||
}
|
||||
public ObservableList<FoodAnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public void Close()
|
||||
{
|
||||
@ -131,16 +130,16 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
public FoodAnimeTypeModel(FoodAnimeTypeModel model)
|
||||
: this()
|
||||
{
|
||||
Id = model.Id;
|
||||
ID = model.ID;
|
||||
Name = model.Name;
|
||||
foreach (var anime in model.HappyAnimes)
|
||||
HappyAnimes.Add(anime.Copy());
|
||||
HappyAnimes.Add(anime.Clone());
|
||||
foreach (var anime in model.NomalAnimes)
|
||||
NomalAnimes.Add(anime.Copy());
|
||||
NomalAnimes.Add(anime.Clone());
|
||||
foreach (var anime in model.PoorConditionAnimes)
|
||||
PoorConditionAnimes.Add(anime.Copy());
|
||||
PoorConditionAnimes.Add(anime.Clone());
|
||||
foreach (var anime in model.IllAnimes)
|
||||
IllAnimes.Add(anime.Copy());
|
||||
IllAnimes.Add(anime.Clone());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -217,7 +216,7 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
public void AddModeAnime(
|
||||
string path,
|
||||
ModeType mode,
|
||||
ObservableCollection<FoodAnimeModel> foodAnimes,
|
||||
ObservableList<FoodAnimeModel> foodAnimes,
|
||||
ILine line,
|
||||
List<PNGAnimeInfo> pngAnimeInfos
|
||||
)
|
||||
@ -250,7 +249,7 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
}
|
||||
foodAnimes.Add(anime);
|
||||
|
||||
static ObservableCollection<ImageModel> GetImages(string path, PNGAnimeInfo pngAnimeInfo)
|
||||
static ObservableList<ImageModel> GetImages(string path, PNGAnimeInfo pngAnimeInfo)
|
||||
{
|
||||
return new(
|
||||
Directory
|
||||
@ -299,7 +298,7 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
/// <param name="mode">模式</param>
|
||||
private void SaveAnimeInfo(
|
||||
string animePath,
|
||||
ObservableCollection<FoodAnimeModel> animes,
|
||||
ObservableList<FoodAnimeModel> animes,
|
||||
ModeType mode
|
||||
)
|
||||
{
|
||||
@ -334,7 +333,7 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
frontImage.Value.Image.SaveToPng(
|
||||
Path.Combine(
|
||||
frontLayPath,
|
||||
$"{anime.Id}_{frontImage.Index:000}_{frontImage.Value.Duration}.png"
|
||||
$"{anime.ID}_{frontImage.Index:000}_{frontImage.Value.Duration}.png"
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -343,7 +342,7 @@ public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
backImage.Value.Image.SaveToPng(
|
||||
Path.Combine(
|
||||
backLayPath,
|
||||
$"{anime.Id}_{backImage.Index:000}_{backImage.Value.Duration}.png"
|
||||
$"{anime.ID}_{backImage.Index:000}_{backImage.Value.Duration}.png"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -25,25 +25,6 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
{
|
||||
public FoodModel()
|
||||
{
|
||||
//DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
//TODO
|
||||
//Id.ValueChanged += (s, e) =>
|
||||
//{
|
||||
// DescriptionId.Value = $"{e.NewValue}_{nameof(DescriptionId)}";
|
||||
//};
|
||||
//ReferencePrice.AddNotifySender(
|
||||
// Strength,
|
||||
// StrengthFood,
|
||||
// StrengthDrink,
|
||||
// Feeling,
|
||||
// Health,
|
||||
// Likability,
|
||||
// Exp
|
||||
//);
|
||||
//ReferencePrice.SenderPropertyChanged += (s, _) =>
|
||||
//{
|
||||
// s.Value = Math.Floor(SetValueToFood(_food).RealPrice);
|
||||
//};
|
||||
PropertyChangedX += FoodModel_PropertyChangedX;
|
||||
}
|
||||
|
||||
@ -64,11 +45,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
PropertyChangedXEventArgs e
|
||||
)
|
||||
{
|
||||
if (e.PropertyName == nameof(ID))
|
||||
{
|
||||
DescriptionID = $"{e.NewValue}_{nameof(DescriptionID)}";
|
||||
}
|
||||
else if (_notifyReferencePrice.Contains(e.PropertyName))
|
||||
if (e.PropertyName is not null && _notifyReferencePrice.Contains(e.PropertyName))
|
||||
{
|
||||
this.Adapt(_food);
|
||||
ReferencePrice = Math.Floor(_food.RealPrice);
|
||||
@ -96,7 +73,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
/// <summary>
|
||||
/// 食物类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<Food.FoodType> FoodTypes { get; } =
|
||||
public static ObservableList<Food.FoodType> FoodTypes { get; } =
|
||||
new(Enum.GetValues(typeof(Food.FoodType)).Cast<Food.FoodType>());
|
||||
|
||||
#region ID
|
||||
|
@ -13,11 +13,17 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
/// <summary>
|
||||
/// 图像模型
|
||||
/// </summary>
|
||||
public class ImageModel : ObservableObjectX<ImageModel>
|
||||
public class ImageModel : ObservableObjectX<ImageModel>, ICloneable<ImageModel>
|
||||
{
|
||||
public ImageModel(BitmapImage image, int duration = 100)
|
||||
{
|
||||
Image = image;
|
||||
Duration = duration;
|
||||
}
|
||||
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
private BitmapImage _image = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 图像
|
||||
@ -42,19 +48,14 @@ public class ImageModel : ObservableObjectX<ImageModel>
|
||||
set => SetProperty(ref _duration, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ImageModel(BitmapImage image, int duration = 100)
|
||||
{
|
||||
Image = image;
|
||||
Duration = duration;
|
||||
}
|
||||
|
||||
public ImageModel Copy()
|
||||
public ImageModel Clone()
|
||||
{
|
||||
var model = new ImageModel(Image.CloneStream(), Duration);
|
||||
return model;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image?.CloseStream();
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -26,6 +27,29 @@ namespace VPet.ModMaker.Models;
|
||||
/// </summary>
|
||||
public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
public ModInfoModel()
|
||||
{
|
||||
PropertyChanged += ModInfoModel_PropertyChanged;
|
||||
Pets.CollectionChanged += Pets_CollectionChanged;
|
||||
}
|
||||
|
||||
private void ModInfoModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(ID))
|
||||
{
|
||||
DescriptionID = $"{ID}_{nameof(DescriptionID)}";
|
||||
}
|
||||
else if (e.PropertyName == nameof(ShowMainPet))
|
||||
{
|
||||
Pets_CollectionChanged(null, null!);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前
|
||||
/// </summary>
|
||||
public static ModInfoModel Current { get; set; } = new();
|
||||
|
||||
#region AutoSetFoodPrice
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _autoSetFoodPrice;
|
||||
@ -65,33 +89,28 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public ulong ItemID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前
|
||||
/// </summary>
|
||||
public static ModInfoModel Current { get; set; } = new();
|
||||
|
||||
#region Id
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string Id
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DescriptionId
|
||||
#region DescriptionID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionId = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 描述Id
|
||||
/// </summary>
|
||||
public string DescriptionId
|
||||
public string DescriptionID
|
||||
{
|
||||
get => _descriptionId;
|
||||
set => SetProperty(ref _descriptionId, value);
|
||||
@ -145,9 +164,9 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
private BitmapImage? _image;
|
||||
|
||||
public BitmapImage Image
|
||||
public BitmapImage? Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
@ -174,27 +193,27 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// <summary>
|
||||
/// 食物
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodModel> Foods { get; } = new();
|
||||
public ObservableList<FoodModel> Foods { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 点击文本
|
||||
/// </summary>
|
||||
public ObservableCollection<ClickTextModel> ClickTexts { get; } = new();
|
||||
public ObservableList<ClickTextModel> ClickTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 低状态文本
|
||||
/// </summary>
|
||||
public ObservableCollection<LowTextModel> LowTexts { get; } = new();
|
||||
public ObservableList<LowTextModel> LowTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 选择文本
|
||||
/// </summary>
|
||||
public ObservableCollection<SelectTextModel> SelectTexts { get; } = new();
|
||||
public ObservableList<SelectTextModel> SelectTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 宠物
|
||||
/// </summary>
|
||||
public ObservableCollection<PetModel> Pets { get; } = new();
|
||||
public ObservableList<PetModel> Pets { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 宠物实际数量
|
||||
@ -220,27 +239,8 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public static Dictionary<string, Dictionary<string, string>> SaveI18nDatas { get; } = new();
|
||||
#endregion
|
||||
public ModInfoModel()
|
||||
{
|
||||
DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
//TODO
|
||||
//Id.ValueChanged += (o, n) =>
|
||||
//{
|
||||
// DescriptionId.Value = $"{n}_{nameof(DescriptionId)}";
|
||||
//};
|
||||
//Pets.CollectionChanged += Pets_CollectionChanged;
|
||||
//ShowMainPet.ValueChanged += ShowMainPet_ValueChanged;
|
||||
}
|
||||
|
||||
private void ShowMainPet_ValueChanged(
|
||||
ObservableValue<bool> sender,
|
||||
ValueChangedEventArgs<bool> e
|
||||
)
|
||||
{
|
||||
Pets_CollectionChanged(null, null);
|
||||
}
|
||||
|
||||
private void Pets_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
private void Pets_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (ShowMainPet)
|
||||
PetDisplayedCount = Pets.Count;
|
||||
@ -252,8 +252,8 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
: this()
|
||||
{
|
||||
SourcePath = loader.ModPath.FullName;
|
||||
Id = loader.Name;
|
||||
DescriptionId = loader.Intro;
|
||||
ID = loader.Name;
|
||||
DescriptionID = loader.Intro;
|
||||
Author = loader.Author;
|
||||
GameVersion = loader.GameVer;
|
||||
ModVersion = loader.Ver;
|
||||
@ -280,22 +280,25 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
// 若宠物的值为默认值并且本体同名宠物不为默认值, 则把本体宠物的值作为模组宠物的默认值
|
||||
if (
|
||||
petModel.TouchHeadRect == PetModel.Default.TouchHeadRect
|
||||
&& petModel.TouchHeadRect != mainPet.TouchHeadRect
|
||||
petModel.TouchHeadRectangleLocation
|
||||
== PetModel.Current.TouchHeadRectangleLocation
|
||||
&& petModel.TouchHeadRectangleLocation != mainPet.TouchHeadRectangleLocation
|
||||
)
|
||||
petModel.TouchHeadRect = mainPet.TouchHeadRect;
|
||||
petModel.TouchHeadRectangleLocation = mainPet.TouchHeadRectangleLocation;
|
||||
if (
|
||||
petModel.TouchBodyRect == PetModel.Default.TouchBodyRect
|
||||
&& petModel.TouchBodyRect != mainPet.TouchBodyRect
|
||||
petModel.TouchBodyRectangleLocation
|
||||
== PetModel.Current.TouchBodyRectangleLocation
|
||||
&& petModel.TouchBodyRectangleLocation != mainPet.TouchBodyRectangleLocation
|
||||
)
|
||||
petModel.TouchBodyRect = mainPet.TouchBodyRect;
|
||||
petModel.TouchBodyRectangleLocation = mainPet.TouchBodyRectangleLocation;
|
||||
if (
|
||||
petModel.TouchRaisedRect == PetModel.Default.TouchRaisedRect
|
||||
&& petModel.TouchRaisedRect != mainPet.TouchRaisedRect
|
||||
petModel.TouchRaisedRectangleLocation
|
||||
== PetModel.Current.TouchRaisedRectangleLocation
|
||||
&& petModel.TouchRaisedRectangleLocation != mainPet.TouchRaisedRectangleLocation
|
||||
)
|
||||
petModel.TouchRaisedRect = mainPet.TouchRaisedRect;
|
||||
petModel.TouchRaisedRectangleLocation = mainPet.TouchRaisedRectangleLocation;
|
||||
if (
|
||||
petModel.RaisePoint == PetModel.Default.RaisePoint
|
||||
petModel.RaisePoint == PetModel.Current.RaisePoint
|
||||
&& petModel.RaisePoint != mainPet.RaisePoint
|
||||
)
|
||||
petModel.RaisePoint = mainPet.RaisePoint;
|
||||
@ -328,7 +331,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
public void RefreshId()
|
||||
{
|
||||
DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
DescriptionID = $"{ID}_{nameof(DescriptionID)}";
|
||||
}
|
||||
|
||||
#region Load
|
||||
@ -500,15 +503,15 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
continue;
|
||||
if (i18nData.TryGetValue(pet.ID, out var name))
|
||||
data.Name = name;
|
||||
if (i18nData.TryGetValue(pet.PetNameId, out var petName))
|
||||
if (i18nData.TryGetValue(pet.PetNameID, out var petName))
|
||||
data.PetName = petName;
|
||||
if (i18nData.TryGetValue(pet.DescriptionId, out var description))
|
||||
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))
|
||||
if (i18nData.TryGetValue(work.ID, out var workName))
|
||||
workData.Name = workName;
|
||||
}
|
||||
}
|
||||
@ -521,7 +524,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
foreach (var selectText in SelectTexts)
|
||||
selectText.RefreshID();
|
||||
foreach (var pet in Pets)
|
||||
pet.RefreshId();
|
||||
pet.RefreshID();
|
||||
}
|
||||
#endregion
|
||||
#region Save
|
||||
@ -567,13 +570,13 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
var lps = new LPS()
|
||||
{
|
||||
new Line("vupmod", Id)
|
||||
new Line("vupmod", ID)
|
||||
{
|
||||
new Sub("author", Author),
|
||||
new Sub("gamever", GameVersion),
|
||||
new Sub("ver", ModVersion)
|
||||
},
|
||||
new Line("intro", DescriptionId),
|
||||
new Line("intro", DescriptionID),
|
||||
new Line("authorid", AuthorID.ToString()),
|
||||
new Line("itemid", ItemID.ToString()),
|
||||
new Line("cachedate", DateTime.Now.Date.ToString("s"))
|
||||
@ -583,8 +586,8 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
lps.Add(
|
||||
new Line("lang", cultureName)
|
||||
{
|
||||
new Sub(Id, I18nDatas[cultureName].Name),
|
||||
new Sub(DescriptionId, I18nDatas[cultureName].Description),
|
||||
new Sub(ID, I18nDatas[cultureName].Name),
|
||||
new Sub(DescriptionID, I18nDatas[cultureName].Description),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -768,7 +771,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
Directory.CreateDirectory(foodPath);
|
||||
foreach (var food in Foods)
|
||||
{
|
||||
food.Image.SaveToPng(Path.Combine(foodPath, food.ID));
|
||||
food.Image?.SaveToPng(Path.Combine(foodPath, food.ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -778,12 +781,12 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
Image.CloseStream();
|
||||
Image?.CloseStream();
|
||||
foreach (var food in Foods)
|
||||
food.Close();
|
||||
foreach (var pet in Pets)
|
||||
pet.Close();
|
||||
Current = null;
|
||||
Current = null!;
|
||||
}
|
||||
|
||||
public void SaveTranslationMod(string path, IEnumerable<string> cultures)
|
||||
|
86
VPet.ModMaker/Models/ModModel/ModUpdataHelper.cs
Normal file
86
VPet.ModMaker/Models/ModModel/ModUpdataHelper.cs
Normal file
@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.ViewModels.ModEdit;
|
||||
using VPet.ModMaker.Views;
|
||||
using VPet.ModMaker.Views.ModEdit;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 模组升级助手
|
||||
/// </summary>
|
||||
public static class ModUpdataHelper
|
||||
{
|
||||
public static int LastVersion => UpdataAction.Last().Key;
|
||||
|
||||
/// <summary>
|
||||
/// 能否升级模组
|
||||
/// </summary>
|
||||
/// <param name="mod">模组</param>
|
||||
/// <param name="version">版本</param>
|
||||
/// <returns>可以升级为 <see langword="true"/> 不可以为 <see langword="false"/></returns>
|
||||
public static bool CanUpdata(ModInfoModel mod)
|
||||
{
|
||||
if (mod.ModVersion >= LastVersion)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 升级模组
|
||||
/// </summary>
|
||||
/// <param name="mod">模组</param>
|
||||
/// <param name="version">版本</param>
|
||||
/// <returns>可以升级为 <see langword="true"/> 不可以为 <see langword="false"/></returns>
|
||||
public static bool Updata(ModInfoModel mod)
|
||||
{
|
||||
if (CanUpdata(mod) is false)
|
||||
return false;
|
||||
foreach (var action in UpdataAction)
|
||||
{
|
||||
if (mod.ModVersion >= action.Key)
|
||||
continue;
|
||||
try
|
||||
{
|
||||
// 更新模组
|
||||
action.Value(mod);
|
||||
// 更新支持的游戏版本
|
||||
mod.GameVersion = action.Key;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
ModEditWindow.Current,
|
||||
"模组更新失败\n当前版本: {0}\n目标版本: {1}\n{2}".Translate(mod.ModVersion, action.Key, ex)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SortedDictionary<int, Action<ModInfoModel>> UpdataAction { get; } =
|
||||
new()
|
||||
{
|
||||
[11000] = (ModInfoModel m) =>
|
||||
{
|
||||
// 修改宠物默认ID
|
||||
foreach (var pet in m.Pets)
|
||||
{
|
||||
if (pet.ID == "默认虚拟桌宠")
|
||||
pet.ID = "vup";
|
||||
foreach (var work in pet.Works)
|
||||
{
|
||||
// 修复工作溢出
|
||||
work.FixOverLoad();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
@ -15,20 +16,65 @@ namespace VPet.ModMaker.Models;
|
||||
/// </summary>
|
||||
public class MoveModel : ObservableObjectX<MoveModel>
|
||||
{
|
||||
public MoveModel() { }
|
||||
|
||||
public MoveModel(MoveModel model)
|
||||
: this()
|
||||
{
|
||||
//Id.EnumValue = model.Id.EnumValue;
|
||||
Graph = model.Graph;
|
||||
Distance = model.Distance;
|
||||
Interval = model.Interval;
|
||||
CheckLeft = model.CheckLeft;
|
||||
CheckRight = model.CheckRight;
|
||||
CheckTop = model.CheckTop;
|
||||
CheckBottom = model.CheckBottom;
|
||||
SpeedX = model.SpeedX;
|
||||
SpeedY = model.SpeedY;
|
||||
LocateLength = model.LocateLength;
|
||||
TriggerLeft = model.TriggerLeft;
|
||||
TriggerRight = model.TriggerRight;
|
||||
TriggerTop = model.TriggerTop;
|
||||
TriggerBottom = model.TriggerBottom;
|
||||
LocateType.Value = model.LocateType.Value;
|
||||
TriggerType.Value = model.TriggerType.Value;
|
||||
ModeType.Value = model.ModeType.Value;
|
||||
}
|
||||
|
||||
public MoveModel(GraphHelper.Move move)
|
||||
: this()
|
||||
{
|
||||
//Id.EnumValue = move.Id.EnumValue;
|
||||
Graph = move.Graph;
|
||||
Distance = move.Distance;
|
||||
Interval = move.Interval;
|
||||
CheckLeft = move.CheckLeft;
|
||||
CheckRight = move.CheckRight;
|
||||
CheckTop = move.CheckTop;
|
||||
CheckBottom = move.CheckBottom;
|
||||
SpeedX = move.SpeedX;
|
||||
SpeedY = move.SpeedY;
|
||||
LocateLength = move.LocateLength;
|
||||
TriggerLeft = move.TriggerLeft;
|
||||
TriggerRight = move.TriggerRight;
|
||||
TriggerTop = move.TriggerTop;
|
||||
TriggerBottom = move.TriggerBottom;
|
||||
LocateType.Value = move.LocateType;
|
||||
TriggerType.Value = move.TriggerType;
|
||||
ModeType.Value = move.Mode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<GraphHelper.Move.DirectionType> DirectionTypes { get; } =
|
||||
new(
|
||||
Enum.GetValues(typeof(GraphHelper.Move.DirectionType))
|
||||
.Cast<GraphHelper.Move.DirectionType>()
|
||||
);
|
||||
public static FrozenSet<GraphHelper.Move.DirectionType> DirectionTypes { get; } =
|
||||
Enum.GetValues<GraphHelper.Move.DirectionType>().ToFrozenSet();
|
||||
|
||||
/// <summary>
|
||||
/// 模式类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<GraphHelper.Move.ModeType> ModeTypes { get; } =
|
||||
new(Enum.GetValues(typeof(GraphHelper.Move.ModeType)).Cast<GraphHelper.Move.ModeType>());
|
||||
public static FrozenSet<GraphHelper.Move.ModeType> ModeTypes { get; } =
|
||||
Enum.GetValues<GraphHelper.Move.ModeType>().ToFrozenSet();
|
||||
|
||||
//#region Id
|
||||
//[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -38,7 +84,7 @@ public class MoveModel : ObservableObjectX<MoveModel>
|
||||
//#endregion
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph;
|
||||
private string _graph = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 指定动画
|
||||
@ -255,54 +301,6 @@ public class MoveModel : ObservableObjectX<MoveModel>
|
||||
| GraphHelper.Move.ModeType.Ill
|
||||
);
|
||||
|
||||
public MoveModel() { }
|
||||
|
||||
public MoveModel(MoveModel model)
|
||||
: this()
|
||||
{
|
||||
//Id.EnumValue = model.Id.EnumValue;
|
||||
Graph = model.Graph;
|
||||
Distance = model.Distance;
|
||||
Interval = model.Interval;
|
||||
CheckLeft = model.CheckLeft;
|
||||
CheckRight = model.CheckRight;
|
||||
CheckTop = model.CheckTop;
|
||||
CheckBottom = model.CheckBottom;
|
||||
SpeedX = model.SpeedX;
|
||||
SpeedY = model.SpeedY;
|
||||
LocateLength = model.LocateLength;
|
||||
TriggerLeft = model.TriggerLeft;
|
||||
TriggerRight = model.TriggerRight;
|
||||
TriggerTop = model.TriggerTop;
|
||||
TriggerBottom = model.TriggerBottom;
|
||||
LocateType.Value = model.LocateType.Value;
|
||||
TriggerType.Value = model.TriggerType.Value;
|
||||
ModeType.Value = model.ModeType.Value;
|
||||
}
|
||||
|
||||
public MoveModel(GraphHelper.Move move)
|
||||
: this()
|
||||
{
|
||||
//Id.EnumValue = move.Id.EnumValue;
|
||||
Graph = move.Graph;
|
||||
Distance = move.Distance;
|
||||
Interval = move.Interval;
|
||||
CheckLeft = move.CheckLeft;
|
||||
CheckRight = move.CheckRight;
|
||||
CheckTop = move.CheckTop;
|
||||
CheckBottom = move.CheckBottom;
|
||||
SpeedX = move.SpeedX;
|
||||
SpeedY = move.SpeedY;
|
||||
LocateLength = move.LocateLength;
|
||||
TriggerLeft = move.TriggerLeft;
|
||||
TriggerRight = move.TriggerRight;
|
||||
TriggerTop = move.TriggerTop;
|
||||
TriggerBottom = move.TriggerBottom;
|
||||
LocateType.Value = move.LocateType;
|
||||
TriggerType.Value = move.TriggerType;
|
||||
ModeType.Value = move.Mode;
|
||||
}
|
||||
|
||||
public GraphHelper.Move ToMove()
|
||||
{
|
||||
return new()
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -13,6 +14,7 @@ using HKW.HKWUtils.Observable;
|
||||
using LinePutScript;
|
||||
using LinePutScript.Converter;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Mapster;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
@ -23,189 +25,38 @@ namespace VPet.ModMaker.Models;
|
||||
/// </summary>
|
||||
public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
public static PetModel Default { get; } = new();
|
||||
|
||||
#region FromMain
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _fromMain;
|
||||
|
||||
/// <summary>
|
||||
/// 来自本体
|
||||
/// </summary>
|
||||
public bool FromMain
|
||||
{
|
||||
get => _fromMain;
|
||||
set => SetProperty(ref _fromMain, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
#region PetNameId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _petNameId;
|
||||
|
||||
/// <summary>
|
||||
/// 名称Id
|
||||
/// </summary>
|
||||
public string PetNameId
|
||||
{
|
||||
get => _petNameId;
|
||||
set => SetProperty(ref _petNameId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DescriptionId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionId;
|
||||
|
||||
/// <summary>
|
||||
/// 描述Id
|
||||
/// </summary>
|
||||
public string DescriptionId
|
||||
{
|
||||
get => _descriptionId;
|
||||
set => SetProperty(ref _descriptionId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TouchHeadRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _touchHeadRect = new(159, 16, 189, 178);
|
||||
|
||||
/// <summary>
|
||||
/// 头部点击区域
|
||||
/// </summary>
|
||||
public ObservableRectangleLocation<double> TouchHeadRect
|
||||
{
|
||||
get => _touchHeadRect;
|
||||
set => SetProperty(ref _touchHeadRect, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TouchBodyRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _touchBodyRect = new(166, 206, 163, 136);
|
||||
|
||||
/// <summary>
|
||||
/// 身体区域
|
||||
/// </summary>
|
||||
public ObservableRectangleLocation<double> TouchBodyRect
|
||||
{
|
||||
get => _touchBodyRect;
|
||||
set => SetProperty(ref _touchBodyRect, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 提起区域
|
||||
/// </summary>
|
||||
#region TouchRaisedRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableMultiStateRect _touchRaisedRect =
|
||||
new(
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 200, 500, 300)
|
||||
);
|
||||
|
||||
public ObservableMultiStateRect TouchRaisedRect
|
||||
{
|
||||
get => _touchRaisedRect;
|
||||
set => SetProperty(ref _touchRaisedRect, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RaisePoint
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableMultiStatePoint _raisePoint =
|
||||
new(new(290, 128), new(290, 128), new(290, 128), new(225, 115));
|
||||
|
||||
/// <summary>
|
||||
/// 提起定位
|
||||
/// </summary>
|
||||
public ObservableMultiStatePoint RaisePoint
|
||||
{
|
||||
get => _raisePoint;
|
||||
set => SetProperty(ref _raisePoint, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 工作
|
||||
/// </summary>
|
||||
public ObservableCollection<WorkModel> Works { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 移动
|
||||
/// </summary>
|
||||
public ObservableCollection<MoveModel> Moves { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeTypeModel> Animes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
///食物动画
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeTypeModel> FoodAnimes { get; } = new();
|
||||
|
||||
#region AnimeCount
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _AnimeCount;
|
||||
|
||||
public int AnimeCount
|
||||
{
|
||||
get => _AnimeCount;
|
||||
set => SetProperty(ref _AnimeCount, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public PetModel()
|
||||
{
|
||||
PetNameId = $"{ID}_{nameof(PetNameId)}";
|
||||
DescriptionId = $"{ID}_{nameof(DescriptionId)}";
|
||||
//TODO
|
||||
//ID.ValueChanged += (s, e) =>
|
||||
//{
|
||||
// PetNameId = $"{e.NewValue}_{nameof(PetNameId)}";
|
||||
// DescriptionId = $"{e.NewValue}_{nameof(DescriptionId)}";
|
||||
//};
|
||||
//AnimeCount.AddNotifySender(Animes);
|
||||
//AnimeCount.AddNotifySender(FoodAnimes);
|
||||
//AnimeCount.SenderPropertyChanged += (s, _) =>
|
||||
//{
|
||||
// s.Value = Animes.Count + FoodAnimes.Count;
|
||||
//};
|
||||
PropertyChanged += PetModel_PropertyChanged;
|
||||
Animes.PropertyChanged += Animes_PropertyChanged;
|
||||
FoodAnimes.PropertyChanged += FoodAnimes_PropertyChanged;
|
||||
}
|
||||
|
||||
private void PetModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(ID))
|
||||
{
|
||||
PetNameID = $"{ID}_{nameof(PetNameID)}";
|
||||
DescriptionID = $"{ID}_{nameof(DescriptionID)}";
|
||||
}
|
||||
}
|
||||
|
||||
public PetModel(PetModel model)
|
||||
: this()
|
||||
{
|
||||
ID = model.ID;
|
||||
PetNameId = model.PetNameId;
|
||||
TouchHeadRect = model.TouchHeadRect.Clone();
|
||||
TouchBodyRect = model.TouchBodyRect.Clone();
|
||||
TouchRaisedRect = model.TouchRaisedRect.Copy();
|
||||
RaisePoint = model.RaisePoint.Copy();
|
||||
PetNameID = model.PetNameID;
|
||||
DescriptionID = model.DescriptionID;
|
||||
Tags = model.Tags;
|
||||
TouchHeadRectangleLocation = model.TouchHeadRectangleLocation.Clone();
|
||||
TouchBodyRectangleLocation = model.TouchBodyRectangleLocation.Clone();
|
||||
TouchRaisedRectangleLocation = model.TouchRaisedRectangleLocation.Clone();
|
||||
RaisePoint = model.RaisePoint.Clone();
|
||||
foreach (var work in model.Works)
|
||||
Works.Add(work);
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
I18nDatas[item.Key] = item.Value.Clone();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
@ -213,42 +64,43 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
: this()
|
||||
{
|
||||
ID = loader.Name;
|
||||
PetNameId = loader.PetName;
|
||||
DescriptionId = loader.Intor;
|
||||
PetNameID = loader.PetName;
|
||||
DescriptionID = loader.Intor;
|
||||
Tags = loader.Config.Data["tag"].Info;
|
||||
|
||||
TouchHeadRect = new(
|
||||
TouchHeadRectangleLocation = new(
|
||||
loader.Config.TouchHeadLocate.X,
|
||||
loader.Config.TouchHeadLocate.Y,
|
||||
loader.Config.TouchHeadSize.Width,
|
||||
loader.Config.TouchHeadSize.Height
|
||||
);
|
||||
|
||||
TouchBodyRect = new(
|
||||
TouchBodyRectangleLocation = new(
|
||||
loader.Config.TouchBodyLocate.X,
|
||||
loader.Config.TouchBodyLocate.Y,
|
||||
loader.Config.TouchBodySize.Width,
|
||||
loader.Config.TouchBodySize.Height
|
||||
);
|
||||
|
||||
TouchRaisedRect.Happy = new(
|
||||
TouchRaisedRectangleLocation.Happy = new(
|
||||
loader.Config.TouchRaisedLocate[0].X,
|
||||
loader.Config.TouchRaisedLocate[0].Y,
|
||||
loader.Config.TouchRaisedSize[0].Width,
|
||||
loader.Config.TouchRaisedSize[0].Height
|
||||
);
|
||||
TouchRaisedRect.Nomal = new(
|
||||
TouchRaisedRectangleLocation.Nomal = new(
|
||||
loader.Config.TouchRaisedLocate[1].X,
|
||||
loader.Config.TouchRaisedLocate[1].Y,
|
||||
loader.Config.TouchRaisedSize[1].Width,
|
||||
loader.Config.TouchRaisedSize[1].Height
|
||||
);
|
||||
TouchRaisedRect.PoorCondition = new(
|
||||
TouchRaisedRectangleLocation.PoorCondition = new(
|
||||
loader.Config.TouchRaisedLocate[2].X,
|
||||
loader.Config.TouchRaisedLocate[2].Y,
|
||||
loader.Config.TouchRaisedSize[2].Width,
|
||||
loader.Config.TouchRaisedSize[2].Height
|
||||
);
|
||||
TouchRaisedRect.Ill = new(
|
||||
TouchRaisedRectangleLocation.Ill = new(
|
||||
loader.Config.TouchRaisedLocate[3].X,
|
||||
loader.Config.TouchRaisedLocate[3].Y,
|
||||
loader.Config.TouchRaisedSize[3].Width,
|
||||
@ -272,10 +124,191 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
Moves.Add(new(move));
|
||||
}
|
||||
|
||||
public void RefreshId()
|
||||
public static PetModel Current { get; } = new();
|
||||
|
||||
#region FromMain
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _fromMain;
|
||||
|
||||
/// <summary>
|
||||
/// 来自本体
|
||||
/// </summary>
|
||||
public bool FromMain
|
||||
{
|
||||
PetNameId = $"{ID}_{nameof(PetNameId)}";
|
||||
DescriptionId = $"{ID}_{nameof(DescriptionId)}";
|
||||
get => _fromMain;
|
||||
set => SetProperty(ref _fromMain, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _id, value);
|
||||
RefreshID();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region PetNameId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _petNameID = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 名称Id
|
||||
/// </summary>
|
||||
public string PetNameID
|
||||
{
|
||||
get => _petNameID;
|
||||
set => SetProperty(ref _petNameID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DescriptionId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionID = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 描述Id
|
||||
/// </summary>
|
||||
public string DescriptionID
|
||||
{
|
||||
get => _descriptionID;
|
||||
set => SetProperty(ref _descriptionID, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Tags
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _tags = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
public string Tags
|
||||
{
|
||||
get => _tags;
|
||||
set => SetProperty(ref _tags, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region TouchHeadRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _touchHeadRectangleLocation =
|
||||
new(159, 16, 189, 178);
|
||||
|
||||
/// <summary>
|
||||
/// 头部点击区域
|
||||
/// </summary>
|
||||
public ObservableRectangleLocation<double> TouchHeadRectangleLocation
|
||||
{
|
||||
get => _touchHeadRectangleLocation;
|
||||
set => SetProperty(ref _touchHeadRectangleLocation, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TouchBodyRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _touchBodyRectangleLocation =
|
||||
new(166, 206, 163, 136);
|
||||
|
||||
/// <summary>
|
||||
/// 身体区域
|
||||
/// </summary>
|
||||
public ObservableRectangleLocation<double> TouchBodyRectangleLocation
|
||||
{
|
||||
get => _touchBodyRectangleLocation;
|
||||
set => SetProperty(ref _touchBodyRectangleLocation, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 提起区域
|
||||
/// </summary>
|
||||
#region TouchRaisedRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableMultiStateRectangleLocation _touchRaisedRectangleLocation =
|
||||
new(
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 200, 500, 300)
|
||||
);
|
||||
|
||||
public ObservableMultiStateRectangleLocation TouchRaisedRectangleLocation
|
||||
{
|
||||
get => _touchRaisedRectangleLocation;
|
||||
set => SetProperty(ref _touchRaisedRectangleLocation, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RaisePoint
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableMultiStatePoint _raisePoint =
|
||||
new(new(290, 128), new(290, 128), new(290, 128), new(225, 115));
|
||||
|
||||
/// <summary>
|
||||
/// 提起定位
|
||||
/// </summary>
|
||||
public ObservableMultiStatePoint RaisePoint
|
||||
{
|
||||
get => _raisePoint;
|
||||
set => SetProperty(ref _raisePoint, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 工作
|
||||
/// </summary>
|
||||
public ObservableList<WorkModel> Works { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 移动
|
||||
/// </summary>
|
||||
public ObservableList<MoveModel> Moves { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableList<AnimeTypeModel> Animes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
///食物动画
|
||||
/// </summary>
|
||||
public ObservableList<FoodAnimeTypeModel> FoodAnimes { get; } = new();
|
||||
|
||||
#region AnimeCount
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _animeCount;
|
||||
|
||||
public int AnimeCount
|
||||
{
|
||||
get => _animeCount;
|
||||
set => SetProperty(ref _animeCount, value);
|
||||
}
|
||||
#endregion
|
||||
private void FoodAnimes_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
AnimeCount = Animes.Count + FoodAnimes.Count;
|
||||
}
|
||||
|
||||
private void Animes_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
AnimeCount = Animes.Count + FoodAnimes.Count;
|
||||
}
|
||||
|
||||
public void RefreshID()
|
||||
{
|
||||
PetNameID = $"{ID}_{nameof(PetNameID)}";
|
||||
DescriptionID = $"{ID}_{nameof(DescriptionID)}";
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@ -316,10 +349,10 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
ModInfoModel.SaveI18nDatas[cultureName].TryAdd(ID, I18nDatas[cultureName].Name);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(PetNameId, I18nDatas[cultureName].PetName);
|
||||
.TryAdd(PetNameID, I18nDatas[cultureName].PetName);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(DescriptionId, I18nDatas[cultureName].Description);
|
||||
.TryAdd(DescriptionID, I18nDatas[cultureName].Description);
|
||||
}
|
||||
var petFile = Path.Combine(path, $"{ID}.lps");
|
||||
if (File.Exists(petFile) is false)
|
||||
@ -351,7 +384,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
/// 保存移动信息
|
||||
/// </summary>
|
||||
/// <param name="lps"></param>
|
||||
/// <param name="pet"></param>
|
||||
void SaveMoveInfo(LPS lps)
|
||||
{
|
||||
foreach (var move in Moves)
|
||||
@ -364,7 +396,6 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
/// 保存工作信息
|
||||
/// </summary>
|
||||
/// <param name="lps"></param>
|
||||
/// <param name="pet"></param>
|
||||
void SaveWorksInfo(LPS lps)
|
||||
{
|
||||
foreach (var work in Works)
|
||||
@ -374,7 +405,7 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(work.Id, work.I18nDatas[cultureName].Name);
|
||||
.TryAdd(work.ID, work.I18nDatas[cultureName].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -405,16 +436,22 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
SavePetBasicInfo(lps);
|
||||
// 如果值不为默认并且不与本体值相同, 则保存
|
||||
if (TouchHeadRect != Default.TouchHeadRect && TouchHeadRect != mainPet.TouchHeadRect)
|
||||
if (
|
||||
TouchHeadRectangleLocation != Current.TouchHeadRectangleLocation
|
||||
&& TouchHeadRectangleLocation != mainPet.TouchHeadRectangleLocation
|
||||
)
|
||||
SavePetTouchHeadInfo(lps);
|
||||
if (TouchBodyRect != Default.TouchBodyRect && TouchBodyRect != mainPet.TouchBodyRect)
|
||||
if (
|
||||
TouchBodyRectangleLocation != Current.TouchBodyRectangleLocation
|
||||
&& TouchBodyRectangleLocation != mainPet.TouchBodyRectangleLocation
|
||||
)
|
||||
SavePetTouchBodyInfo(lps);
|
||||
if (
|
||||
TouchRaisedRect != Default.TouchRaisedRect
|
||||
&& TouchRaisedRect != mainPet.TouchRaisedRect
|
||||
TouchRaisedRectangleLocation != Current.TouchRaisedRectangleLocation
|
||||
&& TouchRaisedRectangleLocation != mainPet.TouchRaisedRectangleLocation
|
||||
)
|
||||
SavePetTouchRaisedInfo(lps);
|
||||
if (RaisePoint != Default.RaisePoint && RaisePoint != mainPet.RaisePoint)
|
||||
if (RaisePoint != Current.RaisePoint && RaisePoint != mainPet.RaisePoint)
|
||||
SavePetRaisePointInfo(lps);
|
||||
}
|
||||
|
||||
@ -423,11 +460,12 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("pet", ID)
|
||||
{
|
||||
new Sub("intor", DescriptionId),
|
||||
new Sub("intor", DescriptionID),
|
||||
new Sub("path", ID),
|
||||
new Sub("petname", PetNameId)
|
||||
new Sub("petname", PetNameID)
|
||||
}
|
||||
);
|
||||
lps.Add(new Line("tag", Tags));
|
||||
}
|
||||
|
||||
private void SavePetTouchHeadInfo(LPS lps)
|
||||
@ -435,10 +473,10 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("touchhead")
|
||||
{
|
||||
new Sub("px", TouchHeadRect.X),
|
||||
new Sub("py", TouchHeadRect.Y),
|
||||
new Sub("sw", TouchHeadRect.Width),
|
||||
new Sub("sh", TouchHeadRect.Height),
|
||||
new Sub("px", TouchHeadRectangleLocation.X),
|
||||
new Sub("py", TouchHeadRectangleLocation.Y),
|
||||
new Sub("sw", TouchHeadRectangleLocation.Width),
|
||||
new Sub("sh", TouchHeadRectangleLocation.Height),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -448,10 +486,10 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("touchbody")
|
||||
{
|
||||
new Sub("px", TouchBodyRect.X),
|
||||
new Sub("py", TouchBodyRect.Y),
|
||||
new Sub("sw", TouchBodyRect.Width),
|
||||
new Sub("sh", TouchBodyRect.Height),
|
||||
new Sub("px", TouchBodyRectangleLocation.X),
|
||||
new Sub("py", TouchBodyRectangleLocation.Y),
|
||||
new Sub("sw", TouchBodyRectangleLocation.Width),
|
||||
new Sub("sh", TouchBodyRectangleLocation.Height),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -461,25 +499,25 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("touchraised")
|
||||
{
|
||||
new Sub("happy_px", TouchRaisedRect.Happy.X),
|
||||
new Sub("happy_py", TouchRaisedRect.Happy.Y),
|
||||
new Sub("happy_sw", TouchRaisedRect.Happy.Width),
|
||||
new Sub("happy_sh", TouchRaisedRect.Happy.Height),
|
||||
new Sub("happy_px", TouchRaisedRectangleLocation.Happy.X),
|
||||
new Sub("happy_py", TouchRaisedRectangleLocation.Happy.Y),
|
||||
new Sub("happy_sw", TouchRaisedRectangleLocation.Happy.Width),
|
||||
new Sub("happy_sh", TouchRaisedRectangleLocation.Happy.Height),
|
||||
//
|
||||
new Sub("nomal_px", TouchRaisedRect.Nomal.X),
|
||||
new Sub("nomal_py", TouchRaisedRect.Nomal.Y),
|
||||
new Sub("nomal_sw", TouchRaisedRect.Nomal.Width),
|
||||
new Sub("nomal_sh", TouchRaisedRect.Nomal.Height),
|
||||
new Sub("nomal_px", TouchRaisedRectangleLocation.Nomal.X),
|
||||
new Sub("nomal_py", TouchRaisedRectangleLocation.Nomal.Y),
|
||||
new Sub("nomal_sw", TouchRaisedRectangleLocation.Nomal.Width),
|
||||
new Sub("nomal_sh", TouchRaisedRectangleLocation.Nomal.Height),
|
||||
//
|
||||
new Sub("poorcondition_px", TouchRaisedRect.PoorCondition.X),
|
||||
new Sub("poorcondition_py", TouchRaisedRect.PoorCondition.Y),
|
||||
new Sub("poorcondition_sw", TouchRaisedRect.PoorCondition.Width),
|
||||
new Sub("poorcondition_sh", TouchRaisedRect.PoorCondition.Height),
|
||||
new Sub("poorcondition_px", TouchRaisedRectangleLocation.PoorCondition.X),
|
||||
new Sub("poorcondition_py", TouchRaisedRectangleLocation.PoorCondition.Y),
|
||||
new Sub("poorcondition_sw", TouchRaisedRectangleLocation.PoorCondition.Width),
|
||||
new Sub("poorcondition_sh", TouchRaisedRectangleLocation.PoorCondition.Height),
|
||||
//
|
||||
new Sub("ill_px", TouchRaisedRect.Ill.X),
|
||||
new Sub("ill_py", TouchRaisedRect.Ill.Y),
|
||||
new Sub("ill_sw", TouchRaisedRect.Ill.Width),
|
||||
new Sub("ill_sh", TouchRaisedRect.Ill.Height),
|
||||
new Sub("ill_px", TouchRaisedRectangleLocation.Ill.X),
|
||||
new Sub("ill_py", TouchRaisedRectangleLocation.Ill.Y),
|
||||
new Sub("ill_sw", TouchRaisedRectangleLocation.Ill.Width),
|
||||
new Sub("ill_sh", TouchRaisedRectangleLocation.Ill.Height),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -507,7 +545,7 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class I18nPetInfoModel : ObservableObjectX<I18nPetInfoModel>
|
||||
public class I18nPetInfoModel : ObservableObjectX<I18nPetInfoModel>, ICloneable<I18nPetInfoModel>
|
||||
{
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -540,7 +578,7 @@ public class I18nPetInfoModel : ObservableObjectX<I18nPetInfoModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nPetInfoModel Copy()
|
||||
public I18nPetInfoModel Clone()
|
||||
{
|
||||
var result = new I18nPetInfoModel();
|
||||
result.Name = Name;
|
||||
@ -548,15 +586,18 @@ public class I18nPetInfoModel : ObservableObjectX<I18nPetInfoModel>
|
||||
result.Description = Description;
|
||||
return result;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
||||
public class ObservableMultiStateRect
|
||||
: ObservableObjectX<ObservableMultiStateRect>,
|
||||
IEquatable<ObservableMultiStateRect>
|
||||
public class ObservableMultiStateRectangleLocation
|
||||
: ObservableObjectX<ObservableMultiStateRectangleLocation>,
|
||||
IEquatable<ObservableMultiStateRectangleLocation>,
|
||||
ICloneable<ObservableMultiStateRectangleLocation>
|
||||
{
|
||||
#region Happy
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _happy;
|
||||
private ObservableRectangleLocation<double> _happy = null!;
|
||||
public ObservableRectangleLocation<double> Happy
|
||||
{
|
||||
get => _happy;
|
||||
@ -565,9 +606,9 @@ public class ObservableMultiStateRect
|
||||
#endregion
|
||||
|
||||
#region Nomal
|
||||
private ObservableRectangleLocation<double> _nomal;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _nomal = null!;
|
||||
|
||||
public ObservableRectangleLocation<double> Nomal
|
||||
{
|
||||
get => _nomal;
|
||||
@ -577,7 +618,7 @@ public class ObservableMultiStateRect
|
||||
|
||||
#region PoorCondition
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _poorCondition;
|
||||
private ObservableRectangleLocation<double> _poorCondition = null!;
|
||||
public ObservableRectangleLocation<double> PoorCondition
|
||||
{
|
||||
get => _poorCondition;
|
||||
@ -587,7 +628,7 @@ public class ObservableMultiStateRect
|
||||
|
||||
#region Ill
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _ill;
|
||||
private ObservableRectangleLocation<double> _ill = null!;
|
||||
public ObservableRectangleLocation<double> Ill
|
||||
{
|
||||
get => _ill;
|
||||
@ -595,7 +636,7 @@ public class ObservableMultiStateRect
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableMultiStateRect()
|
||||
public ObservableMultiStateRectangleLocation()
|
||||
{
|
||||
Happy = new();
|
||||
Nomal = new();
|
||||
@ -603,7 +644,7 @@ public class ObservableMultiStateRect
|
||||
Ill = new();
|
||||
}
|
||||
|
||||
public ObservableMultiStateRect(
|
||||
public ObservableMultiStateRectangleLocation(
|
||||
ObservableRectangleLocation<double> happy,
|
||||
ObservableRectangleLocation<double> nomal,
|
||||
ObservableRectangleLocation<double> poorCondition,
|
||||
@ -616,7 +657,7 @@ public class ObservableMultiStateRect
|
||||
Ill = ill;
|
||||
}
|
||||
|
||||
public ObservableMultiStateRect Copy()
|
||||
public ObservableMultiStateRectangleLocation Clone()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
@ -627,6 +668,8 @@ public class ObservableMultiStateRect
|
||||
};
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
|
||||
#region Other
|
||||
|
||||
/// <inheritdoc/>
|
||||
@ -638,36 +681,32 @@ public class ObservableMultiStateRect
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservableMultiStateRect temp
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(
|
||||
Happy,
|
||||
temp.Happy
|
||||
)
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(
|
||||
Nomal,
|
||||
temp.Nomal
|
||||
)
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(
|
||||
PoorCondition,
|
||||
temp.PoorCondition
|
||||
)
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(Ill, temp.Ill);
|
||||
return Equals(obj as ObservableMultiStateRectangleLocation);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableMultiStateRect? other)
|
||||
public bool Equals(ObservableMultiStateRectangleLocation? other)
|
||||
{
|
||||
return Equals(obj: other);
|
||||
return Happy.Equals(other?.Happy)
|
||||
&& Nomal.Equals(other?.Nomal)
|
||||
&& PoorCondition.Equals(other?.PoorCondition)
|
||||
&& Ill.Equals(other?.Ill);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator ==(ObservableMultiStateRect a, ObservableMultiStateRect b)
|
||||
public static bool operator ==(
|
||||
ObservableMultiStateRectangleLocation a,
|
||||
ObservableMultiStateRectangleLocation b
|
||||
)
|
||||
{
|
||||
return Equals(a, b);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator !=(ObservableMultiStateRect a, ObservableMultiStateRect b)
|
||||
public static bool operator !=(
|
||||
ObservableMultiStateRectangleLocation a,
|
||||
ObservableMultiStateRectangleLocation b
|
||||
)
|
||||
{
|
||||
return Equals(a, b) is not true;
|
||||
}
|
||||
@ -677,11 +716,12 @@ public class ObservableMultiStateRect
|
||||
|
||||
public class ObservableMultiStatePoint
|
||||
: ObservableObjectX<ObservableMultiStatePoint>,
|
||||
IEquatable<ObservableMultiStatePoint>
|
||||
IEquatable<ObservableMultiStatePoint>,
|
||||
ICloneable<ObservableMultiStatePoint>
|
||||
{
|
||||
#region Happy
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _happy;
|
||||
private ObservablePoint<double> _happy = null!;
|
||||
public ObservablePoint<double> Happy
|
||||
{
|
||||
get => _happy;
|
||||
@ -691,7 +731,7 @@ public class ObservableMultiStatePoint
|
||||
|
||||
#region Nomal
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _nomal;
|
||||
private ObservablePoint<double> _nomal = null!;
|
||||
public ObservablePoint<double> Nomal
|
||||
{
|
||||
get => _nomal;
|
||||
@ -701,7 +741,7 @@ public class ObservableMultiStatePoint
|
||||
|
||||
#region PoorCondition
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _poorCondition;
|
||||
private ObservablePoint<double> _poorCondition = null!;
|
||||
public ObservablePoint<double> PoorCondition
|
||||
{
|
||||
get => _poorCondition;
|
||||
@ -711,7 +751,7 @@ public class ObservableMultiStatePoint
|
||||
|
||||
#region Ill
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _ill;
|
||||
private ObservablePoint<double> _ill = null!;
|
||||
public ObservablePoint<double> Ill
|
||||
{
|
||||
get => _ill;
|
||||
@ -739,7 +779,7 @@ public class ObservableMultiStatePoint
|
||||
Ill = ill;
|
||||
}
|
||||
|
||||
public ObservableMultiStatePoint Copy()
|
||||
public ObservableMultiStatePoint Clone()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
@ -750,6 +790,8 @@ public class ObservableMultiStatePoint
|
||||
};
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
|
||||
#region Other
|
||||
|
||||
/// <inheritdoc/>
|
||||
@ -761,20 +803,16 @@ public class ObservableMultiStatePoint
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservableMultiStatePoint temp
|
||||
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(Happy, temp.Happy)
|
||||
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(Nomal, temp.Nomal)
|
||||
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(
|
||||
PoorCondition,
|
||||
temp.PoorCondition
|
||||
)
|
||||
&& EqualityComparer<ObservablePoint<double>>.Default.Equals(Ill, temp.Ill);
|
||||
return Equals(obj as ObservableMultiStatePoint);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableMultiStatePoint? other)
|
||||
{
|
||||
return Equals(obj: other);
|
||||
return Happy.Equals(other?.Happy)
|
||||
&& Nomal.Equals(other?.Nomal)
|
||||
&& PoorCondition.Equals(other?.PoorCondition)
|
||||
&& Ill.Equals(other?.Ill);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -119,7 +119,6 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
/// <summary>
|
||||
/// 选择Id
|
||||
/// </summary>
|
||||
|
||||
public string ChooseID
|
||||
{
|
||||
get => _chooseId;
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -8,6 +10,8 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using Mapster;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
@ -16,23 +20,105 @@ namespace VPet.ModMaker.Models;
|
||||
/// </summary>
|
||||
public class WorkModel : I18nModel<I18nWorkModel>
|
||||
{
|
||||
public WorkModel()
|
||||
{
|
||||
PropertyChanged += WorkModel_PropertyChanged;
|
||||
}
|
||||
|
||||
private static readonly FrozenSet<string> _notifyIsOverLoad = FrozenSet.ToFrozenSet(
|
||||
[
|
||||
nameof(WorkType),
|
||||
nameof(MoneyBase),
|
||||
nameof(StrengthFood),
|
||||
nameof(StrengthDrink),
|
||||
nameof(Feeling),
|
||||
nameof(Feeling),
|
||||
nameof(LevelLimit),
|
||||
nameof(FinishBonus)
|
||||
]
|
||||
);
|
||||
|
||||
private void WorkModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName is not null && _notifyIsOverLoad.Contains(e.PropertyName))
|
||||
{
|
||||
IsOverLoad = VPet_Simulator.Windows.Interface.ExtensionFunction.IsOverLoad(ToWork());
|
||||
}
|
||||
}
|
||||
|
||||
public WorkModel(WorkModel model)
|
||||
: this()
|
||||
{
|
||||
WorkType = model.WorkType;
|
||||
ID = model.ID;
|
||||
Graph = model.Graph;
|
||||
//MoneyLevel = model.MoneyLevel;
|
||||
MoneyBase = model.MoneyBase;
|
||||
StrengthFood = model.StrengthFood;
|
||||
StrengthDrink = model.StrengthDrink;
|
||||
Feeling = model.Feeling;
|
||||
LevelLimit = model.LevelLimit;
|
||||
Time = model.Time;
|
||||
FinishBonus = model.FinishBonus;
|
||||
|
||||
BorderBrush = model.BorderBrush;
|
||||
Background = model.Background;
|
||||
ButtonBackground = model.ButtonBackground;
|
||||
ButtonForeground = model.ButtonForeground;
|
||||
Foreground = model.Foreground;
|
||||
Left = model.Left;
|
||||
Top = model.Top;
|
||||
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)
|
||||
: this()
|
||||
{
|
||||
WorkType = work.Type;
|
||||
ID = work.Name;
|
||||
Graph = work.Graph;
|
||||
//MoneyLevel = work.MoneyLevel;
|
||||
MoneyBase = work.MoneyBase;
|
||||
StrengthFood = work.StrengthFood;
|
||||
StrengthDrink = work.StrengthDrink;
|
||||
Feeling = work.Feeling;
|
||||
LevelLimit = work.LevelLimit;
|
||||
Time = work.Time;
|
||||
FinishBonus = work.FinishBonus;
|
||||
|
||||
BorderBrush = new((Color)ColorConverter.ConvertFromString("#FF" + work.BorderBrush));
|
||||
Background = new((Color)ColorConverter.ConvertFromString("#FF" + work.Background));
|
||||
Foreground = new((Color)ColorConverter.ConvertFromString("#FF" + work.Foreground));
|
||||
ButtonBackground = new(
|
||||
(Color)ColorConverter.ConvertFromString("#AA" + work.ButtonBackground)
|
||||
);
|
||||
ButtonForeground = new(
|
||||
(Color)ColorConverter.ConvertFromString("#FF" + work.ButtonForeground)
|
||||
);
|
||||
Left = work.Left;
|
||||
Top = work.Top;
|
||||
Width = work.Width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 工作类型
|
||||
/// </summary>
|
||||
public static ObservableCollection<VPet_Simulator.Core.GraphHelper.Work.WorkType> WorkTypes { get; } =
|
||||
new(
|
||||
Enum.GetValues(typeof(VPet_Simulator.Core.GraphHelper.Work.WorkType))
|
||||
.Cast<VPet_Simulator.Core.GraphHelper.Work.WorkType>()
|
||||
);
|
||||
public static FrozenSet<VPet_Simulator.Core.GraphHelper.Work.WorkType> WorkTypes { get; } =
|
||||
Enum.GetValues<VPet_Simulator.Core.GraphHelper.Work.WorkType>().ToFrozenSet();
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public string Id
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
@ -41,12 +127,11 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph;
|
||||
private string _graph = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 指定动画
|
||||
/// </summary>
|
||||
|
||||
public string Graph
|
||||
{
|
||||
get => _graph;
|
||||
@ -180,19 +265,19 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
//#region Image
|
||||
//[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
//private BitmapImage? _image;
|
||||
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
///// <summary>
|
||||
///// 图片
|
||||
///// </summary>
|
||||
//public BitmapImage? Image
|
||||
//{
|
||||
// get => _image;
|
||||
// set => SetProperty(ref _image, value);
|
||||
//}
|
||||
//#endregion
|
||||
|
||||
#region WorkType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -224,13 +309,13 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 背景色
|
||||
/// </summary>
|
||||
#region Background
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _background = new((Color)ColorConverter.ConvertFromString("#FF81D4FA"));
|
||||
|
||||
/// <summary>
|
||||
/// 背景色
|
||||
/// </summary>
|
||||
public SolidColorBrush Background
|
||||
{
|
||||
get => _background;
|
||||
@ -238,13 +323,13 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 前景色
|
||||
/// </summary>
|
||||
#region Foreground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _foreground = new((Color)ColorConverter.ConvertFromString("#FF0286C6"));
|
||||
|
||||
/// <summary>
|
||||
/// 前景色
|
||||
/// </summary>
|
||||
public SolidColorBrush Foreground
|
||||
{
|
||||
get => _foreground;
|
||||
@ -252,14 +337,14 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 按钮背景色
|
||||
/// </summary>
|
||||
#region ButtonBackground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _buttonBackground =
|
||||
new((Color)ColorConverter.ConvertFromString("#AA0286C6"));
|
||||
|
||||
/// <summary>
|
||||
/// 按钮背景色
|
||||
/// </summary>
|
||||
public SolidColorBrush ButtonBackground
|
||||
{
|
||||
get => _buttonBackground;
|
||||
@ -267,135 +352,67 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ButtonForeground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _buttonForeground =
|
||||
new((Color)ColorConverter.ConvertFromString("#FFFFFFFF"));
|
||||
|
||||
/// <summary>
|
||||
/// 按钮前景色
|
||||
/// </summary>
|
||||
#region ButtonForeground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _buttonForeground;
|
||||
|
||||
public SolidColorBrush ButtonForeground
|
||||
{
|
||||
get => _buttonForeground;
|
||||
set => SetProperty(ref _buttonForeground, value);
|
||||
}
|
||||
#endregion
|
||||
#region Left
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _left;
|
||||
|
||||
/// <summary>
|
||||
/// X位置
|
||||
/// </summary>
|
||||
#region Left
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Left;
|
||||
|
||||
public double Left
|
||||
{
|
||||
get => _Left;
|
||||
set => SetProperty(ref _Left, value);
|
||||
get => _left;
|
||||
set => SetProperty(ref _left, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Top
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _top;
|
||||
|
||||
/// <summary>
|
||||
/// Y位置
|
||||
/// </summary>
|
||||
#region Top
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Top;
|
||||
|
||||
public double Top
|
||||
{
|
||||
get => _Top;
|
||||
set => SetProperty(ref _Top, value);
|
||||
get => _top;
|
||||
set => SetProperty(ref _top, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Width
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _width;
|
||||
|
||||
/// <summary>
|
||||
/// 宽度
|
||||
/// </summary>
|
||||
#region Width
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Width;
|
||||
|
||||
public double Width
|
||||
{
|
||||
get => _Width;
|
||||
set => SetProperty(ref _Width, value);
|
||||
get => _width;
|
||||
set => SetProperty(ref _width, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public WorkModel()
|
||||
{ //TODO
|
||||
//IsOverLoad.AddNotifySender(
|
||||
// WorkType,
|
||||
// MoneyBase,
|
||||
// //MoneyLevel,
|
||||
// StrengthFood,
|
||||
// StrengthDrink,
|
||||
// Feeling,
|
||||
// LevelLimit,
|
||||
// FinishBonus
|
||||
//);
|
||||
//IsOverLoad.SenderPropertyChanged += (s, _) =>
|
||||
//{
|
||||
// s.Value = VPet_Simulator.Windows.Interface.ExtensionFunction.IsOverLoad(ToWork());
|
||||
//};
|
||||
}
|
||||
|
||||
public WorkModel(WorkModel model)
|
||||
: this()
|
||||
public void FixOverLoad()
|
||||
{
|
||||
WorkType = model.WorkType;
|
||||
Id = model.Id;
|
||||
Graph = model.Graph;
|
||||
//MoneyLevel = model.MoneyLevel;
|
||||
MoneyBase = model.MoneyBase;
|
||||
StrengthFood = model.StrengthFood;
|
||||
StrengthDrink = model.StrengthDrink;
|
||||
Feeling = model.Feeling;
|
||||
LevelLimit = model.LevelLimit;
|
||||
Time = model.Time;
|
||||
FinishBonus = model.FinishBonus;
|
||||
|
||||
BorderBrush = model.BorderBrush;
|
||||
Background = model.Background;
|
||||
ButtonBackground = model.ButtonBackground;
|
||||
ButtonForeground = model.ButtonForeground;
|
||||
Foreground = model.Foreground;
|
||||
Left = model.Left;
|
||||
Top = model.Top;
|
||||
Width = model.Width;
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public WorkModel(VPet_Simulator.Core.GraphHelper.Work work)
|
||||
: this()
|
||||
{
|
||||
WorkType = work.Type;
|
||||
Id = work.Name;
|
||||
Graph = work.Graph;
|
||||
//MoneyLevel = work.MoneyLevel;
|
||||
MoneyBase = work.MoneyBase;
|
||||
StrengthFood = work.StrengthFood;
|
||||
StrengthDrink = work.StrengthDrink;
|
||||
Feeling = work.Feeling;
|
||||
LevelLimit = work.LevelLimit;
|
||||
Time = work.Time;
|
||||
FinishBonus = work.FinishBonus;
|
||||
|
||||
BorderBrush = new((Color)ColorConverter.ConvertFromString("#FF" + work.BorderBrush));
|
||||
Background = new((Color)ColorConverter.ConvertFromString("#FF" + work.Background));
|
||||
Foreground = new((Color)ColorConverter.ConvertFromString("#FF" + work.Foreground));
|
||||
ButtonBackground = new(
|
||||
(Color)ColorConverter.ConvertFromString("#AA" + work.ButtonBackground)
|
||||
);
|
||||
ButtonForeground = new(
|
||||
(Color)ColorConverter.ConvertFromString("#FF" + work.ButtonForeground)
|
||||
);
|
||||
Left = work.Left;
|
||||
Top = work.Top;
|
||||
Width = work.Width;
|
||||
var work = ToWork();
|
||||
work.FixOverLoad();
|
||||
work.Adapt(this);
|
||||
}
|
||||
|
||||
public VPet_Simulator.Core.GraphHelper.Work ToWork()
|
||||
@ -403,7 +420,7 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
return new()
|
||||
{
|
||||
Type = WorkType,
|
||||
Name = Id,
|
||||
Name = ID,
|
||||
Graph = Graph,
|
||||
//MoneyLevel = MoneyLevel,
|
||||
MoneyBase = MoneyBase,
|
||||
@ -428,15 +445,15 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image.CloseStream();
|
||||
//Image?.CloseStream();
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nWorkModel : ObservableObjectX<I18nWorkModel>
|
||||
public class I18nWorkModel : ObservableObjectX<I18nWorkModel>, ICloneable<I18nWorkModel>
|
||||
{
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name;
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
@ -445,10 +462,12 @@ public class I18nWorkModel : ObservableObjectX<I18nWorkModel>
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nWorkModel Copy()
|
||||
public I18nWorkModel Clone()
|
||||
{
|
||||
var result = new I18nWorkModel();
|
||||
result.Name = Name;
|
||||
return result;
|
||||
}
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
|
@ -285,6 +285,24 @@ public static class NativeExtensions
|
||||
catch { }
|
||||
};
|
||||
}
|
||||
|
||||
public static void SetDataContext(
|
||||
this Window window,
|
||||
object viewModel,
|
||||
Action? closedAction = null
|
||||
)
|
||||
{
|
||||
window.DataContext = viewModel;
|
||||
window.Closed += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
closedAction?.Invoke();
|
||||
window.DataContext = null;
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -27,7 +27,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="HKW.Utils" Version="1.2.4" />
|
||||
<PackageReference Include="HKW.Utils" Version="1.2.5" />
|
||||
<PackageReference Include="HKW.WPF" Version="1.0.3" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
</ItemGroup>
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -21,24 +22,70 @@ namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
{
|
||||
public AnimeEditWindowVM()
|
||||
{
|
||||
_playerTask = new(Play);
|
||||
PropertyChangedX += AnimeEditWindowVM_PropertyChangedX;
|
||||
|
||||
PlayCommand.ExecuteAsyncCommand += PlayCommand_ExecuteAsyncCommand;
|
||||
StopCommand.ExecuteCommand += StopCommand_ExecuteCommand;
|
||||
AddAnimeCommand.ExecuteCommand += AddAnimeCommand_ExecuteCommand;
|
||||
RemoveAnimeCommand.ExecuteCommand += RemoveAnimeCommand_ExecuteCommand;
|
||||
AddImageCommand.ExecuteCommand += AddImageCommand_ExecuteCommand;
|
||||
RemoveImageCommand.ExecuteCommand += RemoveImageCommand_ExecuteCommand;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImageCommand_ExecuteCommand;
|
||||
ClearImageCommand.ExecuteCommand += ClearImageCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
private void AnimeEditWindowVM_PropertyChangedX(
|
||||
AnimeEditWindowVM sender,
|
||||
PropertyChangedXEventArgs e
|
||||
)
|
||||
{
|
||||
if (e.PropertyName == nameof(CurrentAnimeModel))
|
||||
{
|
||||
var newModel = e.NewValue as AnimeModel;
|
||||
var oldModel = e.OldValue as AnimeModel;
|
||||
StopCommand_ExecuteCommand();
|
||||
if (oldModel is not null)
|
||||
oldModel.Images.CollectionChanged -= Images_CollectionChanged;
|
||||
if (newModel is not null)
|
||||
newModel.Images.CollectionChanged += Images_CollectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
/// </summary>
|
||||
public PetModel CurrentPet { get; set; }
|
||||
public PetModel CurrentPet { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 旧动画
|
||||
/// </summary>
|
||||
public AnimeTypeModel OldAnime { get; set; }
|
||||
public AnimeTypeModel? OldAnime { get; set; }
|
||||
|
||||
#region Anime
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private AnimeTypeModel _anime = new();
|
||||
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableValue<AnimeTypeModel> Anime { get; } = new(new());
|
||||
public AnimeTypeModel Anime
|
||||
{
|
||||
get => _anime;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _anime, value) is false)
|
||||
return;
|
||||
CheckGraphType(Anime);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CurrentImageModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ImageModel _currentImageModel;
|
||||
private ImageModel _currentImageModel = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 当前图像模型
|
||||
@ -52,7 +99,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
|
||||
#region CurrentAnimeModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private AnimeModel _currentAnimeModel;
|
||||
private AnimeModel _currentAnimeModel = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 当前动画模型
|
||||
@ -164,32 +211,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// </summary>
|
||||
private Task _playerTask;
|
||||
|
||||
public AnimeEditWindowVM()
|
||||
{
|
||||
_playerTask = new(Play);
|
||||
//TODO
|
||||
//CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||
|
||||
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||
AddAnimeCommand.ExecuteCommand += AddAnimeCommand_ExecuteEvent;
|
||||
RemoveAnimeCommand.ExecuteCommand += RemoveAnimeCommand_ExecuteEvent;
|
||||
AddImageCommand.ExecuteCommand += AddImageCommand_ExecuteEvent;
|
||||
RemoveImageCommand.ExecuteCommand += RemoveImageCommand_ExecuteEvent;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImageCommand_ExecuteEvent;
|
||||
ClearImageCommand.ExecuteCommand += ClearImageCommand_ExecuteEvent;
|
||||
|
||||
Anime.ValueChanged += Anime_ValueChanged;
|
||||
}
|
||||
|
||||
#region LoadAnime
|
||||
private void Anime_ValueChanged(
|
||||
ObservableValue<AnimeTypeModel> sender,
|
||||
ValueChangedEventArgs<AnimeTypeModel> e
|
||||
)
|
||||
{
|
||||
CheckGraphType(e.NewValue);
|
||||
}
|
||||
|
||||
private void CheckGraphType(AnimeTypeModel model)
|
||||
{
|
||||
@ -206,16 +228,16 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// 添加动画
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void AddAnimeCommand_ExecuteEvent()
|
||||
private void AddAnimeCommand_ExecuteCommand()
|
||||
{
|
||||
if (CurrentMode is ModeType.Happy)
|
||||
Anime.Value.HappyAnimes.Add(new());
|
||||
Anime.HappyAnimes.Add(new());
|
||||
else if (CurrentMode is ModeType.Nomal)
|
||||
Anime.Value.NomalAnimes.Add(new());
|
||||
Anime.NomalAnimes.Add(new());
|
||||
else if (CurrentMode is ModeType.PoorCondition)
|
||||
Anime.Value.PoorConditionAnimes.Add(new());
|
||||
Anime.PoorConditionAnimes.Add(new());
|
||||
else if (CurrentMode is ModeType.Ill)
|
||||
Anime.Value.IllAnimes.Add(new());
|
||||
Anime.IllAnimes.Add(new());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -223,20 +245,20 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
|
||||
private void RemoveAnimeCommand_ExecuteEvent(AnimeModel value)
|
||||
private void RemoveAnimeCommand_ExecuteCommand(AnimeModel value)
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.Yes
|
||||
)
|
||||
{
|
||||
if (CurrentMode is ModeType.Happy)
|
||||
Anime.Value.HappyAnimes.Remove(value);
|
||||
Anime.HappyAnimes.Remove(value);
|
||||
else if (CurrentMode is ModeType.Nomal)
|
||||
Anime.Value.NomalAnimes.Remove(value);
|
||||
Anime.NomalAnimes.Remove(value);
|
||||
else if (CurrentMode is ModeType.PoorCondition)
|
||||
Anime.Value.PoorConditionAnimes.Remove(value);
|
||||
Anime.PoorConditionAnimes.Remove(value);
|
||||
else if (CurrentMode is ModeType.Ill)
|
||||
Anime.Value.IllAnimes.Remove(value);
|
||||
Anime.IllAnimes.Remove(value);
|
||||
value.Close();
|
||||
}
|
||||
}
|
||||
@ -248,7 +270,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// 添加图片
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void AddImageCommand_ExecuteEvent(AnimeModel value)
|
||||
private void AddImageCommand_ExecuteCommand(AnimeModel value)
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
@ -266,7 +288,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// 删除图片
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void RemoveImageCommand_ExecuteEvent(AnimeModel value)
|
||||
private void RemoveImageCommand_ExecuteCommand(AnimeModel value)
|
||||
{
|
||||
CurrentImageModel.Close();
|
||||
value.Images.Remove(CurrentImageModel);
|
||||
@ -277,7 +299,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void ChangeImageCommand_ExecuteEvent(AnimeModel value)
|
||||
private void ChangeImageCommand_ExecuteCommand(AnimeModel value)
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new() { Title = "选择图片".Translate(), Filter = $"图片|*.png".Translate() };
|
||||
@ -303,7 +325,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// 清空图片
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void ClearImageCommand_ExecuteEvent(AnimeModel value)
|
||||
private void ClearImageCommand_ExecuteCommand(AnimeModel value)
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("确定清空吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.Yes
|
||||
@ -319,7 +341,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// </summary>
|
||||
/// <param name="images">动画</param>
|
||||
/// <param name="paths">路径</param>
|
||||
public void AddImages(ObservableCollection<ImageModel> images, IEnumerable<string> paths)
|
||||
public void AddImages(ObservableList<ImageModel> images, IEnumerable<string> paths)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -348,27 +370,16 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
}
|
||||
#endregion
|
||||
#region Player
|
||||
private void CurrentAnimeModel_ValueChanged(
|
||||
ObservableValue<AnimeModel> sender,
|
||||
ValueChangedEventArgs<AnimeModel> e
|
||||
)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
if (e.OldValue is not null)
|
||||
e.OldValue.Images.CollectionChanged -= Images_CollectionChanged;
|
||||
if (e.NewValue is not null)
|
||||
e.NewValue.Images.CollectionChanged += Images_CollectionChanged;
|
||||
}
|
||||
|
||||
private void Images_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
private void Images_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
StopCommand_ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止播放
|
||||
/// </summary>
|
||||
private void StopCommand_ExecuteEvent()
|
||||
private void StopCommand_ExecuteCommand()
|
||||
{
|
||||
_playing = false;
|
||||
}
|
||||
@ -376,7 +387,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
/// <summary>
|
||||
/// 开始播放
|
||||
/// </summary>
|
||||
private async Task PlayCommand_AsyncExecuteEvent()
|
||||
private async Task PlayCommand_ExecuteAsyncCommand()
|
||||
{
|
||||
if (CurrentAnimeModel is null)
|
||||
{
|
||||
@ -385,7 +396,7 @@ public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
}
|
||||
_playing = true;
|
||||
_playerTask.Start();
|
||||
await Task.WhenAll(_playerTask);
|
||||
await _playerTask;
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
@ -18,51 +18,94 @@ namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
{
|
||||
public AnimePageVM()
|
||||
{
|
||||
AllAnimes = new()
|
||||
{
|
||||
Filter = (f) =>
|
||||
{
|
||||
if (f is AnimeTypeModel animeModel)
|
||||
{
|
||||
return animeModel.ID.Contains(Search, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else if (f is FoodAnimeTypeModel foodAnimeModel)
|
||||
{
|
||||
return foodAnimeModel.ID.Contains(Search, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else
|
||||
throw new Exception("???");
|
||||
},
|
||||
FilteredList = new()
|
||||
};
|
||||
PropertyChangedX += AnimePageVM_PropertyChangedX;
|
||||
|
||||
AddCommand.ExecuteCommand += AddCommand_ExecuteCommand;
|
||||
EditCommand.ExecuteCommand += EditCommand_ExecuteCommand;
|
||||
RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
private void AnimePageVM_PropertyChangedX(AnimePageVM sender, PropertyChangedXEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(CurrentPet))
|
||||
{
|
||||
InitializeAllAnimes();
|
||||
}
|
||||
else if (e.PropertyName == nameof(Search))
|
||||
{
|
||||
AllAnimes.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
#region Value
|
||||
#region Property
|
||||
/// <summary>
|
||||
/// 显示的动画
|
||||
/// 所有动画
|
||||
/// </summary>
|
||||
#region ShowAnimes
|
||||
#region AllAnimes
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<object> _showAnimes;
|
||||
private ObservableFilterList<object, ObservableList<object>> _allAnimes = null!;
|
||||
|
||||
public ObservableCollection<object> ShowAnimes
|
||||
public ObservableFilterList<object, ObservableList<object>> AllAnimes
|
||||
{
|
||||
get => _showAnimes;
|
||||
set => SetProperty(ref _showAnimes, value);
|
||||
get => _allAnimes;
|
||||
set => SetProperty(ref _allAnimes, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 所有动画
|
||||
/// </summary>
|
||||
public ObservableCollection<object> AllAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeTypeModel> Animes => CurrentPet.Value.Animes;
|
||||
public ObservableList<AnimeTypeModel> Animes => CurrentPet.Animes;
|
||||
|
||||
/// <summary>
|
||||
/// 食物动画
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeTypeModel> FoodAnimes => CurrentPet.Value.FoodAnimes;
|
||||
public ObservableList<FoodAnimeTypeModel> FoodAnimes => CurrentPet.FoodAnimes;
|
||||
|
||||
/// <summary>
|
||||
/// 宠物列表
|
||||
/// </summary>
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public static ObservableList<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
|
||||
#region CurrentPEt
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private PetModel _currentPet = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
/// </summary>
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
public PetModel CurrentPet
|
||||
{
|
||||
get => _currentPet;
|
||||
set => SetProperty(ref _currentPet, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
private string _search = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 搜索
|
||||
@ -90,18 +133,6 @@ public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
/// </summary>
|
||||
public ObservableCommand<object> RemoveCommand { get; } = new();
|
||||
#endregion
|
||||
public AnimePageVM()
|
||||
{
|
||||
ShowAnimes = AllAnimes;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
}
|
||||
|
||||
private void InitializeAllAnimes()
|
||||
{
|
||||
AllAnimes.Clear();
|
||||
@ -109,70 +140,32 @@ public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
AllAnimes.Add(item);
|
||||
foreach (var item in FoodAnimes)
|
||||
AllAnimes.Add(item);
|
||||
Animes.CollectionChanged -= Animes_CollectionChanged;
|
||||
Animes.CollectionChanged += Animes_CollectionChanged;
|
||||
FoodAnimes.CollectionChanged -= Animes_CollectionChanged;
|
||||
FoodAnimes.CollectionChanged += Animes_CollectionChanged;
|
||||
}
|
||||
|
||||
private void Animes_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
private void Animes_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
AllAnimes.Add(e.NewItems[0]);
|
||||
AllAnimes.Add(e.NewItems![0]!);
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
AllAnimes.Remove(e.OldItems[0]);
|
||||
AllAnimes.Remove(e.OldItems![0]!);
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
AllAnimes[AllAnimes.IndexOf(e.OldItems[0])] = e.NewItems[0];
|
||||
}
|
||||
|
||||
private void CurrentPet_ValueChanged(
|
||||
ObservableValue<PetModel> sender,
|
||||
ValueChangedEventArgs<PetModel> e
|
||||
)
|
||||
{
|
||||
InitializeAllAnimes();
|
||||
ShowAnimes = AllAnimes;
|
||||
}
|
||||
|
||||
private void Search_ValueChanged(
|
||||
ObservableValue<string> sender,
|
||||
ValueChangedEventArgs<string> e
|
||||
)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowAnimes = AllAnimes;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowAnimes = new(
|
||||
AllAnimes.Where(m =>
|
||||
{
|
||||
if (m is AnimeTypeModel animeTypeModel)
|
||||
return animeTypeModel.Id.Contains(
|
||||
e.NewValue,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
else if (m is FoodAnimeTypeModel foodAnimeTypeModel)
|
||||
return foodAnimeTypeModel.Id.Contains(
|
||||
e.NewValue,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
else
|
||||
throw new Exception("???");
|
||||
})
|
||||
);
|
||||
}
|
||||
AllAnimes[AllAnimes.IndexOf(e.OldItems![0]!)] = e.NewItems![0]!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加动画
|
||||
/// </summary>
|
||||
private void Add()
|
||||
private void AddCommand_ExecuteCommand()
|
||||
{
|
||||
var selectGraphTypeWindow = new SelectGraphTypeWindow();
|
||||
selectGraphTypeWindow.CurrentPet.Value = CurrentPet.Value;
|
||||
selectGraphTypeWindow.ViewModel.CurrentPet = CurrentPet;
|
||||
selectGraphTypeWindow.ShowDialog();
|
||||
var graphType = selectGraphTypeWindow.GraphType.Value;
|
||||
var animeName = selectGraphTypeWindow.AnimeName.Value;
|
||||
var graphType = selectGraphTypeWindow.ViewModel.GraphType;
|
||||
var animeName = selectGraphTypeWindow.ViewModel.AnimeName;
|
||||
if (selectGraphTypeWindow.IsCancel)
|
||||
return;
|
||||
if (
|
||||
@ -182,24 +175,24 @@ public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
{
|
||||
var window = new FoodAnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.Anime.Value.Name = animeName;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
vm.Anime.Name = animeName;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
FoodAnimes.Add(vm.Anime.Value);
|
||||
FoodAnimes.Add(vm.Anime);
|
||||
}
|
||||
else
|
||||
{
|
||||
var window = new AnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.Anime.Value.GraphType = graphType;
|
||||
vm.Anime.Value.Name = animeName;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
vm.Anime.GraphType = graphType;
|
||||
vm.Anime.Name = animeName;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Animes.Add(vm.Anime.Value);
|
||||
Animes.Add(vm.Anime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,38 +200,34 @@ public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
/// 编辑动画
|
||||
/// </summary>
|
||||
/// <param name="model">动画类型模型</param>
|
||||
public void Edit(object model)
|
||||
public void EditCommand_ExecuteCommand(object model)
|
||||
{
|
||||
var pendingHandler = PendingBox.Show("载入中".Translate());
|
||||
if (model is AnimeTypeModel animeTypeModel)
|
||||
{
|
||||
var window = new AnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
vm.OldAnime = animeTypeModel;
|
||||
var newAnime = vm.Anime.Value = new(animeTypeModel);
|
||||
var newAnime = vm.Anime = new(animeTypeModel);
|
||||
pendingHandler.Close();
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Animes[Animes.IndexOf(animeTypeModel)] = newAnime;
|
||||
if (ShowAnimes.Count != Animes.Count)
|
||||
ShowAnimes[ShowAnimes.IndexOf(animeTypeModel)] = newAnime;
|
||||
}
|
||||
else if (model is FoodAnimeTypeModel foodAnimeTypeModel)
|
||||
{
|
||||
var window = new FoodAnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
vm.OldAnime = foodAnimeTypeModel;
|
||||
var newAnime = vm.Anime.Value = new(foodAnimeTypeModel);
|
||||
var newAnime = vm.Anime = new(foodAnimeTypeModel);
|
||||
pendingHandler.Close();
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
FoodAnimes[FoodAnimes.IndexOf(foodAnimeTypeModel)] = newAnime;
|
||||
if (ShowAnimes.Count != FoodAnimes.Count)
|
||||
ShowAnimes[ShowAnimes.IndexOf(foodAnimeTypeModel)] = newAnime;
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,11 +235,11 @@ public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
/// 删除动画
|
||||
/// </summary>
|
||||
/// <param name="model">动画类型模型</param>
|
||||
private void Remove(object model)
|
||||
private void RemoveCommand_ExecuteCommand(object model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
ShowAnimes.Remove(model);
|
||||
AllAnimes.Remove(model);
|
||||
if (model is AnimeTypeModel animeTypeModel)
|
||||
{
|
||||
Animes.Remove(animeTypeModel);
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
@ -20,6 +21,62 @@ namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
{
|
||||
public FoodAnimeEditWindowVM()
|
||||
{
|
||||
_frontPlayerTask = new(FrontPlay);
|
||||
_backPlayerTask = new(BackPlay);
|
||||
_foodPlayerTask = new(FoodPlay);
|
||||
PropertyChangedX += FoodAnimeEditWindowVM_PropertyChangedX;
|
||||
;
|
||||
|
||||
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||
ReplaceFoodImageCommand.ExecuteCommand += ChangeFoodImageCommand_ExecuteEvent;
|
||||
ResetFoodImageCommand.ExecuteCommand += ResetFoodImageCommand_ExecuteEvent;
|
||||
|
||||
AddAnimeCommand.ExecuteCommand += AddAnimeCommand_ExecuteEvent;
|
||||
RemoveAnimeCommand.ExecuteCommand += RemoveAnimeCommand_ExecuteEvent;
|
||||
|
||||
AddFrontImageCommand.ExecuteCommand += AddFrontImageCommand_ExecuteEvent;
|
||||
RemoveFrontImageCommand.ExecuteCommand += RemoveFrontImageCommand_ExecuteEvent;
|
||||
ClearFrontImageCommand.ExecuteCommand += ClearFrontImageCommand_ExecuteEvent;
|
||||
ChangeFrontImageCommand.ExecuteCommand += ChangeFrontImageCommand_ExecuteEvent;
|
||||
|
||||
AddBackImageCommand.ExecuteCommand += AddBackImageCommand_ExecuteEvent;
|
||||
RemoveBackImageCommand.ExecuteCommand += RemoveBackImageCommand_ExecuteEvent;
|
||||
ClearBackImageCommand.ExecuteCommand += ClearBackImageCommand_ExecuteEvent;
|
||||
ChangeBackImageCommand.ExecuteCommand += ChangeBackImageCommand_ExecuteEvent;
|
||||
|
||||
AddFoodLocationCommand.ExecuteCommand += AddeFoodLocationCommand_ExecuteEvent;
|
||||
RemoveFoodLocationCommand.ExecuteCommand += RemoveFoodLocationCommand_ExecuteEvent;
|
||||
ClearFoodLocationCommand.ExecuteCommand += ClearFoodLocationCommand_ExecuteEvent;
|
||||
}
|
||||
|
||||
private void FoodAnimeEditWindowVM_PropertyChangedX(
|
||||
FoodAnimeEditWindowVM sender,
|
||||
PropertyChangedXEventArgs e
|
||||
)
|
||||
{
|
||||
if (e.PropertyName == nameof(CurrentAnimeModel))
|
||||
{
|
||||
var newModel = e.NewValue as FoodAnimeModel;
|
||||
var oldModel = e.OldValue as FoodAnimeModel;
|
||||
StopCommand_ExecuteEvent();
|
||||
if (oldModel is not null)
|
||||
{
|
||||
oldModel.FrontImages.CollectionChanged -= Images_CollectionChanged;
|
||||
oldModel.BackImages.CollectionChanged -= Images_CollectionChanged;
|
||||
oldModel.FoodLocations.CollectionChanged -= Images_CollectionChanged;
|
||||
}
|
||||
if (newModel is not null)
|
||||
{
|
||||
newModel.FrontImages.CollectionChanged += Images_CollectionChanged;
|
||||
newModel.BackImages.CollectionChanged += Images_CollectionChanged;
|
||||
newModel.FoodLocations.CollectionChanged += Images_CollectionChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
/// </summary>
|
||||
@ -67,7 +124,16 @@ public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableValue<FoodAnimeTypeModel> Anime { get; } = new(new());
|
||||
#region Anime
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private FoodAnimeTypeModel _anime = new();
|
||||
|
||||
public FoodAnimeTypeModel Anime
|
||||
{
|
||||
get => _anime;
|
||||
set => SetProperty(ref _anime, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CurrentFrontImageModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -284,37 +350,6 @@ public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
/// </summary>
|
||||
private Task _foodPlayerTask;
|
||||
|
||||
public FoodAnimeEditWindowVM()
|
||||
{
|
||||
_frontPlayerTask = new(FrontPlay);
|
||||
_backPlayerTask = new(BackPlay);
|
||||
_foodPlayerTask = new(FoodPlay);
|
||||
//TODO
|
||||
//CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||
|
||||
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||
ReplaceFoodImageCommand.ExecuteCommand += ChangeFoodImageCommand_ExecuteEvent;
|
||||
ResetFoodImageCommand.ExecuteCommand += ResetFoodImageCommand_ExecuteEvent;
|
||||
|
||||
AddAnimeCommand.ExecuteCommand += AddAnimeCommand_ExecuteEvent;
|
||||
RemoveAnimeCommand.ExecuteCommand += RemoveAnimeCommand_ExecuteEvent;
|
||||
|
||||
AddFrontImageCommand.ExecuteCommand += AddFrontImageCommand_ExecuteEvent;
|
||||
RemoveFrontImageCommand.ExecuteCommand += RemoveFrontImageCommand_ExecuteEvent;
|
||||
ClearFrontImageCommand.ExecuteCommand += ClearFrontImageCommand_ExecuteEvent;
|
||||
ChangeFrontImageCommand.ExecuteCommand += ChangeFrontImageCommand_ExecuteEvent;
|
||||
|
||||
AddBackImageCommand.ExecuteCommand += AddBackImageCommand_ExecuteEvent;
|
||||
RemoveBackImageCommand.ExecuteCommand += RemoveBackImageCommand_ExecuteEvent;
|
||||
ClearBackImageCommand.ExecuteCommand += ClearBackImageCommand_ExecuteEvent;
|
||||
ChangeBackImageCommand.ExecuteCommand += ChangeBackImageCommand_ExecuteEvent;
|
||||
|
||||
AddFoodLocationCommand.ExecuteCommand += AddeFoodLocationCommand_ExecuteEvent;
|
||||
RemoveFoodLocationCommand.ExecuteCommand += RemoveFoodLocationCommand_ExecuteEvent;
|
||||
ClearFoodLocationCommand.ExecuteCommand += ClearFoodLocationCommand_ExecuteEvent;
|
||||
}
|
||||
|
||||
private void ResetFoodImageCommand_ExecuteEvent()
|
||||
{
|
||||
if (FoodImage != DefaultFoodImage)
|
||||
@ -353,13 +388,13 @@ public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
private void AddAnimeCommand_ExecuteEvent()
|
||||
{
|
||||
if (CurrentMode is ModeType.Happy)
|
||||
Anime.Value.HappyAnimes.Add(new());
|
||||
Anime.HappyAnimes.Add(new());
|
||||
else if (CurrentMode is ModeType.Nomal)
|
||||
Anime.Value.NomalAnimes.Add(new());
|
||||
Anime.NomalAnimes.Add(new());
|
||||
else if (CurrentMode is ModeType.PoorCondition)
|
||||
Anime.Value.PoorConditionAnimes.Add(new());
|
||||
Anime.PoorConditionAnimes.Add(new());
|
||||
else if (CurrentMode is ModeType.Ill)
|
||||
Anime.Value.IllAnimes.Add(new());
|
||||
Anime.IllAnimes.Add(new());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -374,13 +409,13 @@ public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
)
|
||||
{
|
||||
if (CurrentMode is ModeType.Happy)
|
||||
Anime.Value.HappyAnimes.Remove(value);
|
||||
Anime.HappyAnimes.Remove(value);
|
||||
else if (CurrentMode is ModeType.Nomal)
|
||||
Anime.Value.NomalAnimes.Remove(value);
|
||||
Anime.NomalAnimes.Remove(value);
|
||||
else if (CurrentMode is ModeType.PoorCondition)
|
||||
Anime.Value.PoorConditionAnimes.Remove(value);
|
||||
Anime.PoorConditionAnimes.Remove(value);
|
||||
else if (CurrentMode is ModeType.Ill)
|
||||
Anime.Value.IllAnimes.Remove(value);
|
||||
Anime.IllAnimes.Remove(value);
|
||||
value.Close();
|
||||
}
|
||||
}
|
||||
@ -540,7 +575,7 @@ public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
/// </summary>
|
||||
/// <param name="images">动画</param>
|
||||
/// <param name="paths">路径</param>
|
||||
public void AddImages(ObservableCollection<ImageModel> images, IEnumerable<string> paths)
|
||||
public void AddImages(ObservableList<ImageModel> images, IEnumerable<string> paths)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -591,27 +626,8 @@ public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
}
|
||||
#endregion
|
||||
#region FrontPlayer
|
||||
private void CurrentAnimeModel_ValueChanged(
|
||||
ObservableValue<FoodAnimeModel> sender,
|
||||
ValueChangedEventArgs<FoodAnimeModel> e
|
||||
)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
if (e.OldValue is not null)
|
||||
{
|
||||
e.OldValue.FrontImages.CollectionChanged -= Images_CollectionChanged;
|
||||
e.OldValue.BackImages.CollectionChanged -= Images_CollectionChanged;
|
||||
e.OldValue.FoodLocations.CollectionChanged -= Images_CollectionChanged;
|
||||
}
|
||||
if (e.NewValue is not null)
|
||||
{
|
||||
e.NewValue.FrontImages.CollectionChanged += Images_CollectionChanged;
|
||||
e.NewValue.BackImages.CollectionChanged += Images_CollectionChanged;
|
||||
e.NewValue.FoodLocations.CollectionChanged += Images_CollectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void Images_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
private void Images_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class SelectGraphTypeWindowVM : ObservableObjectX<SelectGraphTypeWindowVM>
|
||||
{
|
||||
public SelectGraphTypeWindowVM()
|
||||
{
|
||||
PropertyChanged += SelectGraphTypeWindowVM_PropertyChanged;
|
||||
}
|
||||
|
||||
private void SelectGraphTypeWindowVM_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(CurrentPet))
|
||||
{
|
||||
GraphTypes = new(
|
||||
AnimeTypeModel.GraphTypes.Except(CurrentPet.Animes.Select(m => m.GraphType))
|
||||
);
|
||||
// 可添加多个项的类型
|
||||
GraphTypes.AddRange(AnimeTypeModel.HasNameAnimes);
|
||||
}
|
||||
else if (e.PropertyName == nameof(GraphType))
|
||||
{
|
||||
if (GraphType.IsHasNameAnime())
|
||||
HasNameAnime = true;
|
||||
else
|
||||
HasNameAnime = false;
|
||||
}
|
||||
}
|
||||
|
||||
#region CurrentPet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private PetModel _currentPet = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
/// </summary>
|
||||
public PetModel CurrentPet
|
||||
{
|
||||
get => _currentPet;
|
||||
set => SetProperty(ref _currentPet, value);
|
||||
}
|
||||
#endregion
|
||||
#region GraphType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private GraphInfo.GraphType _graphType;
|
||||
|
||||
/// <summary>
|
||||
/// 动画类型
|
||||
/// </summary>
|
||||
public GraphInfo.GraphType GraphType
|
||||
{
|
||||
get => _graphType;
|
||||
set => SetProperty(ref _graphType, value);
|
||||
}
|
||||
#endregion
|
||||
#region GraphTypes
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableSet<GraphInfo.GraphType> _graphTypes = new();
|
||||
|
||||
/// <summary>
|
||||
/// 动画类型列表
|
||||
/// </summary>
|
||||
public ObservableSet<GraphInfo.GraphType> GraphTypes
|
||||
{
|
||||
get => _graphTypes;
|
||||
set => SetProperty(ref _graphTypes, value);
|
||||
}
|
||||
#endregion
|
||||
#region AnimeName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _animeName = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 动画名称
|
||||
/// </summary>
|
||||
public string AnimeName
|
||||
{
|
||||
get => _animeName;
|
||||
set => SetProperty(ref _animeName, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HasNameAnime
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _hasNameAnime = true;
|
||||
|
||||
/// <summary>
|
||||
/// 具有动画名称
|
||||
/// </summary>
|
||||
public bool HasNameAnime
|
||||
{
|
||||
get => _hasNameAnime;
|
||||
set => SetProperty(ref _hasNameAnime, value);
|
||||
}
|
||||
#endregion
|
||||
}
|
@ -35,16 +35,16 @@ public class I18nEditWindowVM : ObservableObjectX<I18nEditWindowVM> { }
|
||||
// /// <summary>
|
||||
// /// 全部I18n数据
|
||||
// /// </summary>
|
||||
// public ObservableCollection<I18nData> I18nDatas { get; } = new();
|
||||
// public ObservableList<I18nData> I18nDatas { get; } = new();
|
||||
|
||||
// /// <summary>
|
||||
// /// 显示的I18n数据
|
||||
// /// </summary>
|
||||
// #region ShowI18nDatas
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
// private ObservableCollection<I18nData> _showI18nDatas;
|
||||
// private ObservableList<I18nData> _showI18nDatas;
|
||||
|
||||
// public ObservableCollection<I18nData> ShowI18nDatas
|
||||
// public ObservableList<I18nData> ShowI18nDatas
|
||||
// {
|
||||
// get => _showI18nDatas;
|
||||
// set => SetProperty(ref _showI18nDatas, value);
|
||||
@ -54,7 +54,7 @@ public class I18nEditWindowVM : ObservableObjectX<I18nEditWindowVM> { }
|
||||
// /// <summary>
|
||||
// /// 搜索目标列表
|
||||
// /// </summary>
|
||||
// public ObservableCollection<string> SearchTargets { get; } = new() { nameof(ModInfoModel.Id) };
|
||||
// public ObservableList<string> SearchTargets { get; } = new() { nameof(ModInfoModel.Id) };
|
||||
|
||||
// /// <summary>
|
||||
// /// 搜索目标
|
||||
@ -117,7 +117,7 @@ public class I18nEditWindowVM : ObservableObjectX<I18nEditWindowVM> { }
|
||||
// /// </summary>
|
||||
// /// <param name="sender"></param>
|
||||
// /// <param name="e"></param>
|
||||
// private void CultureNames_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
// private void CultureNames_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
|
@ -26,7 +26,8 @@ public class ModEditWindowVM : ObservableObjectX<ModEditWindowVM>
|
||||
{
|
||||
public ModEditWindowVM(ModEditWindow window)
|
||||
{
|
||||
I18nEditWindow.Initialize();
|
||||
//TODO
|
||||
//I18nEditWindow.Initialize();
|
||||
ModEditWindow = window;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImageCommand_ExecuteCommand;
|
||||
AddCultureCommand.ExecuteCommand += AddCultureCommand_ExecuteCommand;
|
||||
@ -210,8 +211,8 @@ public class ModEditWindowVM : ObservableObjectX<ModEditWindowVM>
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
ModInfo.I18nDatas[culture].Name = ModInfo.Id;
|
||||
ModInfo.I18nDatas[culture].Description = ModInfo.DescriptionId;
|
||||
ModInfo.I18nDatas[culture].Name = ModInfo.ID;
|
||||
ModInfo.I18nDatas[culture].Description = ModInfo.DescriptionID;
|
||||
foreach (var food in ModInfo.Foods)
|
||||
{
|
||||
food.I18nDatas[culture].Name = food.ID;
|
||||
@ -229,10 +230,10 @@ public class ModEditWindowVM : ObservableObjectX<ModEditWindowVM>
|
||||
foreach (var pet in ModInfo.Pets)
|
||||
{
|
||||
pet.I18nDatas[culture].Name = pet.ID;
|
||||
pet.I18nDatas[culture].PetName = pet.PetNameId;
|
||||
pet.I18nDatas[culture].Description = pet.DescriptionId;
|
||||
pet.I18nDatas[culture].PetName = pet.PetNameID;
|
||||
pet.I18nDatas[culture].Description = pet.DescriptionID;
|
||||
foreach (var work in pet.Works)
|
||||
work.I18nDatas[culture].Name = work.Id;
|
||||
work.I18nDatas[culture].Name = work.ID;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@ -311,7 +312,7 @@ public class ModEditWindowVM : ObservableObjectX<ModEditWindowVM>
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(model.Id))
|
||||
if (string.IsNullOrWhiteSpace(model.ID))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return false;
|
||||
|
@ -14,9 +14,16 @@ namespace VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
|
||||
|
||||
public class MoveEditWindowVM : ObservableObjectX<MoveEditWindowVM>
|
||||
{
|
||||
#region Value
|
||||
public PetModel CurrentPet { get; set; }
|
||||
public MoveModel OldMove { get; set; }
|
||||
public MoveEditWindowVM()
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImageCommand_ExecuteCommand;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImageCommand_ExecuteCommand;
|
||||
//Image.ValueChanged += Image_ValueChanged;
|
||||
}
|
||||
|
||||
#region Property
|
||||
public PetModel CurrentPet { get; set; } = null!;
|
||||
public MoveModel? OldMove { get; set; }
|
||||
|
||||
#region Move
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -51,9 +58,9 @@ public class MoveEditWindowVM : ObservableObjectX<MoveEditWindowVM>
|
||||
#endregion
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
private BitmapImage? _image;
|
||||
|
||||
public BitmapImage Image
|
||||
public BitmapImage? Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
@ -63,13 +70,6 @@ public class MoveEditWindowVM : ObservableObjectX<MoveEditWindowVM>
|
||||
public ObservableCommand AddImageCommand { get; } = new();
|
||||
public ObservableCommand ChangeImageCommand { get; } = new();
|
||||
#endregion
|
||||
public MoveEditWindowVM()
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImage;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImage;
|
||||
//TODO
|
||||
//Image.ValueChanged += Image_ValueChanged;
|
||||
}
|
||||
|
||||
private void Image_ValueChanged(
|
||||
ObservableValue<BitmapImage> sender,
|
||||
@ -84,28 +84,26 @@ public class MoveEditWindowVM : ObservableObjectX<MoveEditWindowVM>
|
||||
Image?.StreamSource?.Close();
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
private void AddImageCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeImage()
|
||||
private void ChangeImageCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image?.StreamSource?.Close();
|
||||
|
@ -1,11 +1,13 @@
|
||||
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 System.Windows;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
@ -15,27 +17,50 @@ namespace VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
|
||||
|
||||
public class MovePageVM : ObservableObjectX<MovePageVM>
|
||||
{
|
||||
public MovePageVM()
|
||||
{
|
||||
Moves = new()
|
||||
{
|
||||
Filter = f => f.Graph.Contains(Search, StringComparison.OrdinalIgnoreCase),
|
||||
FilteredList = new()
|
||||
};
|
||||
PropertyChanged += MovePageVM_PropertyChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += AddCommand_ExecuteCommand;
|
||||
EditCommand.ExecuteCommand += EditCommand_ExecuteCommand;
|
||||
RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
#region Value
|
||||
#region Property
|
||||
#region ShowMoves
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<MoveModel> _showMoves;
|
||||
private ObservableFilterList<MoveModel, ObservableList<MoveModel>> _moves;
|
||||
|
||||
public ObservableCollection<MoveModel> ShowMoves
|
||||
public ObservableFilterList<MoveModel, ObservableList<MoveModel>> Moves
|
||||
{
|
||||
get => _showMoves;
|
||||
set => SetProperty(ref _showMoves, value);
|
||||
get => _moves;
|
||||
set => SetProperty(ref _moves, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<MoveModel> Moves => CurrentPet.Value.Moves;
|
||||
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
public static ObservableList<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
|
||||
#region CurrentPet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private PetModel _currentPet;
|
||||
|
||||
public PetModel CurrentPet
|
||||
{
|
||||
get => _currentPet;
|
||||
set => SetProperty(ref _currentPet, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
private string _search = string.Empty;
|
||||
|
||||
public string Search
|
||||
{
|
||||
@ -49,83 +74,49 @@ public class MovePageVM : ObservableObjectX<MovePageVM>
|
||||
public ObservableCommand<MoveModel> EditCommand { get; } = new();
|
||||
public ObservableCommand<MoveModel> RemoveCommand { get; } = new();
|
||||
#endregion
|
||||
public MovePageVM()
|
||||
private void MovePageVM_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
ShowMoves = Moves;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
}
|
||||
|
||||
private void CurrentPet_ValueChanged(
|
||||
ObservableValue<PetModel> sender,
|
||||
ValueChangedEventArgs<PetModel> e
|
||||
)
|
||||
{
|
||||
//ShowMoves.Value = e.NewValue.Moves;
|
||||
}
|
||||
|
||||
private void Search_ValueChanged(
|
||||
ObservableValue<string> sender,
|
||||
ValueChangedEventArgs<string> e
|
||||
)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
if (e.PropertyName == nameof(CurrentPet))
|
||||
{
|
||||
ShowMoves = Moves;
|
||||
Moves.Clear();
|
||||
Moves.AddRange(CurrentPet.Moves);
|
||||
}
|
||||
else
|
||||
else if (e.PropertyName == nameof(Search))
|
||||
{
|
||||
ShowMoves = new(
|
||||
Moves.Where(m => m.Graph.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
Moves.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
private void Add()
|
||||
private void AddCommand_ExecuteCommand()
|
||||
{
|
||||
var window = new MoveEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Moves.Add(vm.Move);
|
||||
}
|
||||
|
||||
public void Edit(MoveModel model)
|
||||
public void EditCommand_ExecuteCommand(MoveModel model)
|
||||
{
|
||||
var window = new MoveEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
vm.OldMove = model;
|
||||
var newMove = vm.Move = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Moves[Moves.IndexOf(model)] = newMove;
|
||||
if (ShowMoves.Count != Moves.Count)
|
||||
ShowMoves[ShowMoves.IndexOf(model)] = newMove;
|
||||
}
|
||||
|
||||
private void Remove(MoveModel model)
|
||||
private void RemoveCommand_ExecuteCommand(MoveModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowMoves.Count == Moves.Count)
|
||||
{
|
||||
Moves.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMoves.Remove(model);
|
||||
Moves.Remove(model);
|
||||
}
|
||||
Moves.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -15,17 +15,25 @@ namespace VPet.ModMaker.ViewModels.ModEdit.PetEdit;
|
||||
|
||||
public class PetEditWindowVM : ObservableObjectX<PetEditWindowVM>
|
||||
{
|
||||
public I18nHelper I18nData => I18nHelper.Current;
|
||||
public PetModel OldPet { get; set; }
|
||||
public PetEditWindowVM()
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImageCommand_ExecuteCommand;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImageCommand_ExecuteCommand;
|
||||
//Image.ValueChanged += Image_ValueChanged;
|
||||
}
|
||||
|
||||
#region Property
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
public PetModel? OldPet { get; set; }
|
||||
|
||||
#region Pet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private PetModel _Pet;
|
||||
private PetModel _pet = new();
|
||||
|
||||
public PetModel Pet
|
||||
{
|
||||
get => _Pet;
|
||||
set => SetProperty(ref _Pet, value);
|
||||
get => _pet;
|
||||
set => SetProperty(ref _pet, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -41,7 +49,7 @@ public class PetEditWindowVM : ObservableObjectX<PetEditWindowVM>
|
||||
#endregion
|
||||
#region LengthRatio
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _lengthRatio = 250 / 500;
|
||||
private double _lengthRatio = 0.5;
|
||||
|
||||
public double LengthRatio
|
||||
{
|
||||
@ -51,26 +59,20 @@ public class PetEditWindowVM : ObservableObjectX<PetEditWindowVM>
|
||||
#endregion
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
private BitmapImage? _image;
|
||||
|
||||
public BitmapImage Image
|
||||
public BitmapImage? Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
public ObservableCommand AddImageCommand { get; } = new();
|
||||
public ObservableCommand ChangeImageCommand { get; } = new();
|
||||
#endregion
|
||||
public PetEditWindowVM()
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImage;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImage;
|
||||
//TODO
|
||||
//Image.ValueChanged += Image_ValueChanged;
|
||||
}
|
||||
|
||||
private void Image_ValueChanged(
|
||||
ObservableValue<BitmapImage> sender,
|
||||
ValueChangedEventArgs<BitmapImage> e
|
||||
@ -84,28 +86,26 @@ public class PetEditWindowVM : ObservableObjectX<PetEditWindowVM>
|
||||
Image?.CloseStream();
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
private void AddImageCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeImage()
|
||||
private void ChangeImageCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image?.StreamSource?.Close();
|
||||
|
@ -24,9 +24,9 @@ public class PetPageVM : ObservableObjectX<PetPageVM>
|
||||
FilteredList = new()
|
||||
};
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
AddCommand.ExecuteCommand += AddCommand_ExecuteCommand;
|
||||
EditCommand.ExecuteCommand += EditCommand_ExecuteCommand;
|
||||
RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
@ -66,7 +66,7 @@ public class PetPageVM : ObservableObjectX<PetPageVM>
|
||||
|
||||
public void Close() { }
|
||||
|
||||
private void Add()
|
||||
private void AddCommand_ExecuteCommand()
|
||||
{
|
||||
var window = new PetEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
@ -76,7 +76,7 @@ public class PetPageVM : ObservableObjectX<PetPageVM>
|
||||
Pets.Add(vm.Pet);
|
||||
}
|
||||
|
||||
public void Edit(PetModel model)
|
||||
public void EditCommand_ExecuteCommand(PetModel model)
|
||||
{
|
||||
if (model.FromMain)
|
||||
{
|
||||
@ -106,7 +106,7 @@ public class PetPageVM : ObservableObjectX<PetPageVM>
|
||||
model.Close();
|
||||
}
|
||||
|
||||
private void Remove(PetModel model)
|
||||
private void RemoveCommand_ExecuteCommand(PetModel model)
|
||||
{
|
||||
if (model.FromMain)
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ public class SaveTranslationModWindowVM : ObservableObjectX<SaveTranslationModWi
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableCollection<CheckCultureModel> CheckCultures { get; } = [];
|
||||
public ObservableList<CheckCultureModel> CheckCultures { get; } = [];
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
|
@ -1,29 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media.Imaging;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.WorkEdit;
|
||||
|
||||
public class WorkEditWindowVM : ObservableObjectX<WorkEditWindowVM>
|
||||
{
|
||||
public WorkEditWindowVM()
|
||||
{
|
||||
PropertyChangedX += WorkEditWindowVM_PropertyChangedX;
|
||||
Work.PropertyChanged += NewWork_PropertyChanged;
|
||||
AddImageCommand.ExecuteCommand += AddImageCommand_ExecuteCommand;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImageCommand_ExecuteCommand;
|
||||
FixOverLoadCommand.ExecuteCommand += FixOverLoadCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
private void WorkEditWindowVM_PropertyChangedX(
|
||||
WorkEditWindowVM sender,
|
||||
PropertyChangedXEventArgs e
|
||||
)
|
||||
{
|
||||
if (e.PropertyName == nameof(Work))
|
||||
{
|
||||
var newWork = e.NewValue as WorkModel;
|
||||
var oldWork = e.OldValue as WorkModel;
|
||||
if (oldWork is not null)
|
||||
{
|
||||
oldWork.PropertyChanged -= NewWork_PropertyChanged;
|
||||
}
|
||||
if (newWork is not null)
|
||||
{
|
||||
newWork.PropertyChanged -= NewWork_PropertyChanged;
|
||||
newWork.PropertyChanged += NewWork_PropertyChanged;
|
||||
SetGraphImage(newWork);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NewWork_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (sender is not WorkModel workModel)
|
||||
return;
|
||||
if (e.PropertyName == nameof(WorkModel.Graph))
|
||||
{
|
||||
SetGraphImage(workModel);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetGraphImage(WorkModel workModel)
|
||||
{
|
||||
if (CurrentPet is null)
|
||||
return;
|
||||
var graph = workModel.Graph;
|
||||
Image?.CloseStream();
|
||||
Image = null;
|
||||
// 随机挑一张图片
|
||||
if (
|
||||
CurrentPet.Animes.FirstOrDefault(
|
||||
a =>
|
||||
a.GraphType is VPet_Simulator.Core.GraphInfo.GraphType.Work
|
||||
&& a.Name.Equals(graph, StringComparison.OrdinalIgnoreCase),
|
||||
null!
|
||||
)
|
||||
is not AnimeTypeModel anime
|
||||
)
|
||||
return;
|
||||
if (anime.HappyAnimes.HasValue())
|
||||
{
|
||||
Image = anime.HappyAnimes.Random().Images.Random().Image.CloneStream();
|
||||
}
|
||||
else if (anime.NomalAnimes.HasValue())
|
||||
{
|
||||
Image = anime.NomalAnimes.Random().Images.Random().Image.CloneStream();
|
||||
}
|
||||
else if (anime.PoorConditionAnimes.HasValue())
|
||||
{
|
||||
Image = anime.PoorConditionAnimes.Random().Images.Random().Image.CloneStream();
|
||||
}
|
||||
else if (anime.IllAnimes.HasValue())
|
||||
{
|
||||
Image = anime.IllAnimes.Random().Images.Random().Image.CloneStream();
|
||||
}
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
#region Value
|
||||
public PetModel CurrentPet { get; set; }
|
||||
public WorkModel OldWork { get; set; }
|
||||
#region Property
|
||||
public PetModel CurrentPet { get; set; } = null!;
|
||||
public WorkModel? OldWork { get; set; }
|
||||
|
||||
#region Work
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private WorkModel _work;
|
||||
private WorkModel _work = new();
|
||||
|
||||
public WorkModel Work
|
||||
{
|
||||
@ -52,52 +132,59 @@ public class WorkEditWindowVM : ObservableObjectX<WorkEditWindowVM>
|
||||
set => SetProperty(ref _lengthRatio, value);
|
||||
}
|
||||
#endregion
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage? _image;
|
||||
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public BitmapImage? Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddImageCommand { get; } = new();
|
||||
public ObservableCommand ChangeImageCommand { get; } = new();
|
||||
|
||||
public ObservableCommand FixOverLoadCommand { get; } = new();
|
||||
#endregion
|
||||
public WorkEditWindowVM()
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImage;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImage;
|
||||
FixOverLoadCommand.ExecuteCommand += FixOverLoadCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
private void FixOverLoadCommand_ExecuteCommand()
|
||||
{
|
||||
//var work = Work.ToWork();
|
||||
//work.FixOverLoad();
|
||||
//Work = new(work);
|
||||
Work.FixOverLoad();
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
private void AddImageCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Work.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeImage()
|
||||
private void ChangeImageCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Work.Image?.CloseStream();
|
||||
Work.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Image?.CloseStream();
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image?.CloseStream();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
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 System.Windows;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
@ -15,22 +17,34 @@ namespace VPet.ModMaker.ViewModels.ModEdit.WorkEdit;
|
||||
|
||||
public class WorkPageVM : ObservableObjectX<WorkPageVM>
|
||||
{
|
||||
public WorkPageVM()
|
||||
{
|
||||
Works = new()
|
||||
{
|
||||
Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase),
|
||||
FilteredList = new()
|
||||
};
|
||||
PropertyChanged += WorkPageVM_PropertyChanged;
|
||||
AddCommand.ExecuteCommand += AddCommand_ExecuteCommand;
|
||||
EditCommand.ExecuteCommand += EditCommand_ExecuteCommand;
|
||||
RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
#region Value
|
||||
#region ShowWorks
|
||||
#region Property
|
||||
#region Works
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<WorkModel> _showWorks;
|
||||
private ObservableFilterList<WorkModel, ObservableList<WorkModel>> _works;
|
||||
|
||||
public ObservableCollection<WorkModel> ShowWorks
|
||||
public ObservableFilterList<WorkModel, ObservableList<WorkModel>> Works
|
||||
{
|
||||
get => _showWorks;
|
||||
set => SetProperty(ref _showWorks, value);
|
||||
get => _works;
|
||||
set => SetProperty(ref _works, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<WorkModel> Works => CurrentPet.Works;
|
||||
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public static ObservableList<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
|
||||
#region CurrentPet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
@ -45,7 +59,7 @@ public class WorkPageVM : ObservableObjectX<WorkPageVM>
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
private string _search = string.Empty;
|
||||
|
||||
public string Search
|
||||
{
|
||||
@ -59,44 +73,20 @@ public class WorkPageVM : ObservableObjectX<WorkPageVM>
|
||||
public ObservableCommand<WorkModel> EditCommand { get; } = new();
|
||||
public ObservableCommand<WorkModel> RemoveCommand { get; } = new();
|
||||
#endregion
|
||||
public WorkPageVM()
|
||||
private void WorkPageVM_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
ShowWorks = Works;
|
||||
//TODO
|
||||
//CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
}
|
||||
|
||||
private void CurrentPet_ValueChanged(
|
||||
ObservableValue<PetModel> sender,
|
||||
ValueChangedEventArgs<PetModel> e
|
||||
)
|
||||
{
|
||||
ShowWorks = e.NewValue.Works;
|
||||
}
|
||||
|
||||
private void Search_ValueChanged(
|
||||
ObservableValue<string> sender,
|
||||
ValueChangedEventArgs<string> e
|
||||
)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
if (e.PropertyName == nameof(CurrentPet))
|
||||
{
|
||||
ShowWorks = Works;
|
||||
Works.Clear();
|
||||
Works.AddRange(CurrentPet.Works);
|
||||
}
|
||||
else
|
||||
else if (e.PropertyName == nameof(Search))
|
||||
{
|
||||
ShowWorks = new(
|
||||
Works.Where(m => m.Id.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
Works.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void Add()
|
||||
private void AddCommand_ExecuteCommand()
|
||||
{
|
||||
var window = new WorkEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
@ -107,7 +97,7 @@ public class WorkPageVM : ObservableObjectX<WorkPageVM>
|
||||
Works.Add(vm.Work);
|
||||
}
|
||||
|
||||
public void Edit(WorkModel model)
|
||||
public void EditCommand_ExecuteCommand(WorkModel model)
|
||||
{
|
||||
var window = new WorkEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
@ -118,22 +108,14 @@ public class WorkPageVM : ObservableObjectX<WorkPageVM>
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Works[Works.IndexOf(model)] = newWork;
|
||||
if (ShowWorks.Count != Works.Count)
|
||||
ShowWorks[ShowWorks.IndexOf(model)] = newWork;
|
||||
model.Close();
|
||||
}
|
||||
|
||||
private void Remove(WorkModel model)
|
||||
private void RemoveCommand_ExecuteCommand(WorkModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowWorks.Count == Works.Count)
|
||||
{
|
||||
Works.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowWorks.Remove(model);
|
||||
Works.Remove(model);
|
||||
}
|
||||
Works.Remove(model);
|
||||
model.Close();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -8,6 +9,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript;
|
||||
using LinePutScript.Converter;
|
||||
@ -23,43 +25,63 @@ namespace VPet.ModMaker.ViewModels;
|
||||
|
||||
public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
{
|
||||
#region Value
|
||||
public ModMakerWindow ModMakerWindow { get; }
|
||||
public ModMakerWindowVM(ModMakerWindow window)
|
||||
{
|
||||
Histories = new()
|
||||
{
|
||||
Filter = f => f.ID.Contains(Search, StringComparison.OrdinalIgnoreCase),
|
||||
FilteredList = new()
|
||||
};
|
||||
LoadHistories();
|
||||
ModMakerWindow = window;
|
||||
PropertyChanged += ModMakerWindowVM_PropertyChanged;
|
||||
CreateNewModCommand.ExecuteCommand += CreateNewModCommand_ExecuteCommand;
|
||||
LoadModFromFileCommand.ExecuteCommand += LoadModFromFileCommand_ExecuteCommand;
|
||||
ClearHistoriesCommand.ExecuteCommand += ClearHistoriesCommand_ExecuteCommand;
|
||||
RemoveHistoryCommand.ExecuteCommand += RemoveHistoryCommand_ExecuteCommand;
|
||||
}
|
||||
|
||||
public ModEditWindow ModEditWindow { get; private set; }
|
||||
private void ModMakerWindowVM_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(Search))
|
||||
{
|
||||
Histories.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
#region Property
|
||||
public ModMakerWindow ModMakerWindow { get; } = null!;
|
||||
|
||||
public ModEditWindow ModEditWindow { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 历史搜索文本
|
||||
/// </summary>
|
||||
#region HistoriesSearchText
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _historiesSearchText;
|
||||
private string _search = string.Empty;
|
||||
|
||||
public string HistoriesSearchText
|
||||
public string Search
|
||||
{
|
||||
get => _historiesSearchText;
|
||||
set => SetProperty(ref _historiesSearchText, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 显示的历史
|
||||
/// </summary>
|
||||
#region ShowHistories
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<ModMakeHistory> _showHistories;
|
||||
|
||||
public ObservableCollection<ModMakeHistory> ShowHistories
|
||||
{
|
||||
get => _showHistories;
|
||||
set => SetProperty(ref _showHistories, value);
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 历史
|
||||
/// </summary>
|
||||
public ObservableCollection<ModMakeHistory> Histories { get; set; } = new();
|
||||
#region Histories
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableFilterList<ModMakeHistory, ObservableList<ModMakeHistory>> _histories = null!;
|
||||
|
||||
public ObservableFilterList<ModMakeHistory, ObservableList<ModMakeHistory>> Histories
|
||||
{
|
||||
get => _histories;
|
||||
set => SetProperty(ref _histories, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
#region Command
|
||||
/// <summary>
|
||||
@ -83,32 +105,8 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
public ObservableCommand<ModMakeHistory> RemoveHistoryCommand { get; } = new();
|
||||
#endregion
|
||||
|
||||
public ModMakerWindowVM(ModMakerWindow window)
|
||||
{
|
||||
LoadHistories();
|
||||
ModMakerWindow = window;
|
||||
//TODO
|
||||
ShowHistories = Histories;
|
||||
CreateNewModCommand.ExecuteCommand += CreateNewMod;
|
||||
LoadModFromFileCommand.ExecuteCommand += LoadModFromFile;
|
||||
ClearHistoriesCommand.ExecuteCommand += ClearHistories;
|
||||
RemoveHistoryCommand.ExecuteCommand += RemoveHistory;
|
||||
//HistoriesSearchText.ValueChanged += HistoriesSearchText_ValueChanged;
|
||||
}
|
||||
|
||||
private void HistoriesSearchText_ValueChanged(
|
||||
ObservableValue<string> sender,
|
||||
ValueChangedEventArgs<string> e
|
||||
)
|
||||
{
|
||||
if (string.IsNullOrEmpty(e.NewValue))
|
||||
ShowHistories = Histories;
|
||||
else
|
||||
ShowHistories = new(Histories.Where(i => i.Id.Contains(e.NewValue)));
|
||||
}
|
||||
|
||||
#region History
|
||||
private void RemoveHistory(ModMakeHistory value)
|
||||
private void RemoveHistoryCommand_ExecuteCommand(ModMakeHistory value)
|
||||
{
|
||||
Histories.Remove(value);
|
||||
SaveHistories();
|
||||
@ -122,14 +120,14 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
if (File.Exists(ModMakerInfo.HistoryFile) is false)
|
||||
return;
|
||||
var lps = new LPS(File.ReadAllText(ModMakerInfo.HistoryFile));
|
||||
var set = new HashSet<ModMakeHistory>();
|
||||
foreach (var line in lps)
|
||||
{
|
||||
if (LPSConvert.DeserializeObject<ModMakeHistory>(line) is not ModMakeHistory history)
|
||||
continue;
|
||||
if (Histories.All(h => h.InfoFile != history.InfoFile))
|
||||
Histories.Add(history);
|
||||
set.Add(history);
|
||||
}
|
||||
Histories = new(Histories.OrderByDescending(h => h.LastTime));
|
||||
Histories.AddRange(set.OrderByDescending(h => h.LastTime));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -158,7 +156,7 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
is ModMakeHistory history
|
||||
)
|
||||
{
|
||||
history.Id = modInfo.Id;
|
||||
history.ID = modInfo.ID;
|
||||
history.SourcePath = modInfo.SourcePath;
|
||||
history.LastTime = DateTime.Now;
|
||||
}
|
||||
@ -167,7 +165,7 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
Histories.Add(
|
||||
new()
|
||||
{
|
||||
Id = modInfo.Id,
|
||||
ID = modInfo.ID,
|
||||
SourcePath = modInfo.SourcePath,
|
||||
LastTime = DateTime.Now,
|
||||
}
|
||||
@ -175,14 +173,14 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearHistories()
|
||||
private void ClearHistoriesCommand_ExecuteCommand()
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("确定要清空吗?".Translate(), "", MessageBoxButton.YesNo)
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
ShowHistories.Clear();
|
||||
Histories.Clear();
|
||||
Histories.Clear();
|
||||
File.WriteAllText(ModMakerInfo.HistoryFile, string.Empty);
|
||||
}
|
||||
@ -192,7 +190,7 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
/// <summary>
|
||||
/// 创建新模组
|
||||
/// </summary>
|
||||
public void CreateNewMod()
|
||||
public void CreateNewModCommand_ExecuteCommand()
|
||||
{
|
||||
ModInfoModel.Current = new();
|
||||
ShowEditWindow();
|
||||
@ -241,18 +239,17 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
/// <summary>
|
||||
/// 从文件载入模组
|
||||
/// </summary>
|
||||
public void LoadModFromFile()
|
||||
public void LoadModFromFileCommand_ExecuteCommand()
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "模组信息文件".Translate(),
|
||||
Filter = $"LPS文件|*.lps;".Translate(),
|
||||
FileName = "info.lps"
|
||||
};
|
||||
var openFileDialog = new OpenFileDialog()
|
||||
{
|
||||
Title = "模组信息文件".Translate(),
|
||||
Filter = $"LPS文件|*.lps;".Translate(),
|
||||
FileName = "info.lps"
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
LoadMod(Path.GetDirectoryName(openFileDialog.FileName));
|
||||
LoadMod(Path.GetDirectoryName(openFileDialog.FileName)!);
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,19 +276,40 @@ public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
{
|
||||
var modInfo = new ModInfoModel(loader);
|
||||
EditMod(modInfo);
|
||||
// 更新模组
|
||||
if (ModUpdataHelper.CanUpdata(modInfo))
|
||||
{
|
||||
pendingHandler.Hide();
|
||||
if (
|
||||
MessageBox.Show(
|
||||
ModEditWindow.Current,
|
||||
"是否更新模组\n当前版本: {0}\n最新版本: {1}".Translate(
|
||||
modInfo.ModVersion,
|
||||
ModUpdataHelper.LastVersion
|
||||
),
|
||||
"更新模组".Translate(),
|
||||
MessageBoxButton.YesNo
|
||||
) is MessageBoxResult.Yes
|
||||
)
|
||||
{
|
||||
if (ModUpdataHelper.Updata(modInfo))
|
||||
MessageBox.Show("更新完成, 请手动保存".Translate());
|
||||
}
|
||||
}
|
||||
pendingHandler.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
pendingHandler.Close();
|
||||
ModEditWindow?.Close();
|
||||
ModEditWindow = null;
|
||||
ModEditWindow = null!;
|
||||
ModInfoModel.Current?.Close();
|
||||
I18nHelper.Current = new();
|
||||
I18nEditWindow.Current?.Close(true);
|
||||
ModMakerWindow.Show();
|
||||
ModMakerWindow.Activate();
|
||||
MessageBox.Show(ModMakerWindow, "模组载入失败:\n{0}".Translate(ex));
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -39,12 +39,12 @@ public partial class AddCultureWindow : WindowX
|
||||
TextBox_Lang.Dispatcher.InvokeAsync(TextBox_Lang.SelectAll);
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Culture))
|
||||
{
|
||||
@ -60,7 +60,7 @@ public partial class AddCultureWindow : WindowX
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Hyperlink_Click(object sender, RoutedEventArgs e)
|
||||
private void Hyperlink_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start(
|
||||
new ProcessStartInfo(
|
||||
|
@ -68,9 +68,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(非必要)}" -->
|
||||
<ComboBox
|
||||
Grid.Column="2"
|
||||
Margin="10,0,0,0"
|
||||
|
@ -43,18 +43,18 @@ public partial class AnimeEditWindow : Window
|
||||
|
||||
public bool IsCancel { get; private set; } = true;
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
IsCancel = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void TabControl_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (
|
||||
sender is not TabControl tabControl
|
||||
@ -70,7 +70,7 @@ public partial class AnimeEditWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
private void ListBox_PreviewMouseWheel(object? sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
|
||||
{
|
||||
@ -84,7 +84,7 @@ public partial class AnimeEditWindow : Window
|
||||
|
||||
private object _dropSender;
|
||||
|
||||
private void ListBox_PreviewMouseMove(object sender, MouseEventArgs e)
|
||||
private void ListBox_PreviewMouseMove(object? sender, MouseEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
@ -102,7 +102,7 @@ public partial class AnimeEditWindow : Window
|
||||
DragDrop.DoDragDrop(listBox, dataObj, DragDropEffects.Move);
|
||||
}
|
||||
|
||||
private void ListBox_Drop(object sender, DragEventArgs e)
|
||||
private void ListBox_Drop(object? sender, DragEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
@ -136,7 +136,7 @@ public partial class AnimeEditWindow : Window
|
||||
list[targetIndex] = temp;
|
||||
}
|
||||
|
||||
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void ListBox_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
@ -146,7 +146,7 @@ public partial class AnimeEditWindow : Window
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void ListBox_Animes_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void ListBox_Animes_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}" Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索ID}" Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox.Style>
|
||||
<Style BasedOn="{StaticResource StandardTextBoxStyle}" TargetType="TextBox">
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
@ -61,7 +61,7 @@
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Id}" />
|
||||
<TextBlock Text="{Binding ID}" />
|
||||
<TextBlock Text="{ll:Str {} (来自本体)}" Visibility="{Binding FromMain, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
@ -85,7 +85,7 @@
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowAnimes}"
|
||||
ItemsSource="{Binding AllAnimes.FilteredList}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="50"
|
||||
@ -100,40 +100,40 @@
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Id}"
|
||||
Binding="{Binding ID}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 动画类型}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id" />
|
||||
SortMemberPath="ID" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding HappyAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 开心状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id" />
|
||||
SortMemberPath="HappyAnimes.Count" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding NomalAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 普通状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id" />
|
||||
SortMemberPath="NomalAnimes.Count" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding PoorConditionAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 不开心状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id" />
|
||||
SortMemberPath="PoorConditionAnimes.Count" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding IllAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 生病状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id" />
|
||||
SortMemberPath="IllAnimes.Count" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button
|
||||
|
@ -30,10 +30,10 @@ public partial class AnimePage : Page
|
||||
|
||||
public AnimePageVM ViewModel => (AnimePageVM)DataContext;
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is null)
|
||||
return;
|
||||
ViewModel.Edit(dataGrid.SelectedItem);
|
||||
ViewModel.EditCommand_ExecuteCommand(dataGrid.SelectedItem);
|
||||
}
|
||||
}
|
||||
|
@ -44,18 +44,18 @@ public partial class FoodAnimeEditWindow : Window
|
||||
|
||||
public bool IsCancel { get; private set; } = true;
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
IsCancel = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void TabControl_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (ViewModel is null)
|
||||
return;
|
||||
@ -75,7 +75,7 @@ public partial class FoodAnimeEditWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
private void ListBox_PreviewMouseWheel(object? sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
|
||||
{
|
||||
@ -89,7 +89,7 @@ public partial class FoodAnimeEditWindow : Window
|
||||
|
||||
private object _dropSender;
|
||||
|
||||
private void ListBox_PreviewMouseMove(object sender, MouseEventArgs e)
|
||||
private void ListBox_PreviewMouseMove(object? sender, MouseEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
@ -107,7 +107,7 @@ public partial class FoodAnimeEditWindow : Window
|
||||
DragDrop.DoDragDrop(listBox, dataObj, DragDropEffects.Move);
|
||||
}
|
||||
|
||||
private void ListBox_Drop(object sender, DragEventArgs e)
|
||||
private void ListBox_Drop(object? sender, DragEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
@ -156,7 +156,7 @@ public partial class FoodAnimeEditWindow : Window
|
||||
list[targetIndex] = temp;
|
||||
}
|
||||
|
||||
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void ListBox_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
@ -166,7 +166,7 @@ public partial class FoodAnimeEditWindow : Window
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void ListBox_Animes_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void ListBox_Animes_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
xmlns:local="clr-namespace:VPet.ModMaker.Views.ModEdit.AnimeEdit"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:pu="https://opensource.panuon.com/wpf-ui"
|
||||
xmlns:vm="clr-namespace:VPet.ModMaker.ViewModels.ModEdit.AnimeEdit"
|
||||
Title="SelectGraphTypeWindow"
|
||||
Width="500"
|
||||
Height="300"
|
||||
@ -15,7 +16,7 @@
|
||||
<ResourceDictionary Source="/VPet-Simulator.Windows.Interface;component/ResourceStyle.xaml" />
|
||||
</Window.Resources>
|
||||
<d:Window.DataContext>
|
||||
<local:SelectGraphTypeWindow />
|
||||
<vm:SelectGraphTypeWindowVM />
|
||||
</d:Window.DataContext>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@ -38,19 +39,19 @@
|
||||
<Label Content="{ll:Str 动画类型}" />
|
||||
<ComboBox
|
||||
Grid.Column="1"
|
||||
ItemsSource="{Binding GraphTypes.Value}"
|
||||
SelectedItem="{Binding GraphType.Value}"
|
||||
ItemsSource="{Binding GraphTypes}"
|
||||
SelectedItem="{Binding GraphType}"
|
||||
Style="{DynamicResource StandardComboBoxStyle}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Content="{ll:Str 动画名称}"
|
||||
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
Visibility="{Binding HasNameAnime, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding AnimeName.Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
Text="{Binding AnimeName, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasNameAnime, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -16,6 +17,7 @@ using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
namespace VPet.ModMaker.Views.ModEdit.AnimeEdit;
|
||||
@ -25,63 +27,22 @@ namespace VPet.ModMaker.Views.ModEdit.AnimeEdit;
|
||||
/// </summary>
|
||||
public partial class SelectGraphTypeWindow : Window
|
||||
{
|
||||
public SelectGraphTypeWindowVM ViewModel => (SelectGraphTypeWindowVM)DataContext;
|
||||
|
||||
public SelectGraphTypeWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
GraphType.ValueChanged += GraphType_ValueChanged;
|
||||
Closed += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
DataContext = null;
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
this.SetDataContext<SelectGraphTypeWindowVM>();
|
||||
}
|
||||
|
||||
private void GraphType_ValueChanged(
|
||||
ObservableValue<GraphInfo.GraphType> sender,
|
||||
ValueChangedEventArgs<GraphInfo.GraphType> e
|
||||
)
|
||||
{
|
||||
if (e.NewValue.IsHasNameAnime())
|
||||
HasNameAnime.Value = true;
|
||||
else
|
||||
HasNameAnime.Value = false;
|
||||
}
|
||||
|
||||
private void CurrentPet_ValueChanged(
|
||||
ObservableValue<PetModel> sender,
|
||||
ValueChangedEventArgs<PetModel> e
|
||||
)
|
||||
{
|
||||
GraphTypes.Value = new(
|
||||
AnimeTypeModel.GraphTypes.Except(CurrentPet.Value.Animes.Select(m => m.GraphType))
|
||||
);
|
||||
// 可添加多个项的类型
|
||||
foreach (var graphType in AnimeTypeModel.HasNameAnimes)
|
||||
if (GraphTypes.Value.Contains(graphType) is false)
|
||||
GraphTypes.Value.Add(graphType);
|
||||
}
|
||||
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new();
|
||||
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
||||
public ObservableValue<ObservableCollection<GraphInfo.GraphType>> GraphTypes { get; } =
|
||||
new(new());
|
||||
public ObservableValue<string> AnimeName { get; } = new();
|
||||
|
||||
public ObservableValue<bool> HasNameAnime { get; } = new(true);
|
||||
|
||||
public bool IsCancel { get; private set; } = true;
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
//if (string.IsNullOrWhiteSpace(AnimeName.Value))
|
||||
//{
|
||||
|
@ -31,12 +31,12 @@ public partial class ClickTextEditWindow : Window
|
||||
this.SetDataContext<ClickTextEditWindowVM>();
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.ID))
|
||||
{
|
||||
|
@ -60,12 +60,12 @@
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Text" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Mode.EnumValue}"
|
||||
Binding="{Binding Mode.Value}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 状态}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Mode.EnumValue" />
|
||||
SortMemberPath="Mode.Value" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Working}"
|
||||
CanUserSort="True"
|
||||
@ -81,12 +81,12 @@
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="WorkingState" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding DayTime.EnumValue}"
|
||||
Binding="{Binding DayTime.Value}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 时间}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="DayTime.EnumValue" />
|
||||
SortMemberPath="DayTime.Value" />
|
||||
<DataGridTextColumn
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
|
@ -30,7 +30,7 @@ public partial class ClickTextPage : Page
|
||||
DataContext = new ClickTextPageVM();
|
||||
}
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not ClickTextModel model)
|
||||
return;
|
||||
|
@ -38,12 +38,12 @@ public partial class FoodEditWindow : Window
|
||||
});
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Food.ID))
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ public partial class FoodPage : Page
|
||||
DataContext = new FoodPageVM();
|
||||
}
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not FoodModel model)
|
||||
return;
|
||||
|
@ -20,7 +20,7 @@ public partial class I18nEditWindow : WindowX
|
||||
{
|
||||
public bool IsCancel { get; private set; } = true;
|
||||
|
||||
public static I18nEditWindow Current { get; private set; }
|
||||
public static I18nEditWindow Current { get; private set; } = null!;
|
||||
|
||||
public I18nEditWindowVM ViewModel => (I18nEditWindowVM)DataContext;
|
||||
|
||||
@ -64,7 +64,7 @@ public partial class I18nEditWindow : WindowX
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ViewModel_CultureChanged(object sender, string newCulture)
|
||||
private void ViewModel_CultureChanged(object? sender, string newCulture)
|
||||
{
|
||||
var oldCulture = sender as string;
|
||||
if (string.IsNullOrEmpty(oldCulture))
|
||||
|
@ -32,12 +32,12 @@ public partial class LowTextEditWindow : Window
|
||||
this.SetDataContext<LowTextEditWindowVM>();
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.LowText.ID))
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ public partial class LowTextPage : Page
|
||||
DataContext = new LowTextPageVM();
|
||||
}
|
||||
|
||||
private void DataGrid_LowText_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_LowText_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not LowTextModel lowText)
|
||||
return;
|
||||
|
@ -92,7 +92,7 @@
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="ID"
|
||||
Text="{Binding ModInfo.Id, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding ModInfo.ID, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="1" Content="{ll:Str 作者}" />
|
||||
<TextBox
|
||||
x:Name="TextBox_Author"
|
||||
@ -311,6 +311,7 @@
|
||||
<Button
|
||||
Command="{Binding EditI18nCommand}"
|
||||
Content="{ll:Str 编辑多语言内容}"
|
||||
IsEnabled="False"
|
||||
Style="{DynamicResource ThemedButtonStyle}" />
|
||||
<Button
|
||||
Command="{Binding SaveCommand}"
|
||||
@ -320,9 +321,11 @@
|
||||
Command="{Binding SaveToCommand}"
|
||||
Content="{ll:Str 保存至}"
|
||||
Style="{DynamicResource ThemedButtonStyle}" />
|
||||
<!-- TODO -->
|
||||
<Button
|
||||
Command="{Binding SaveAsTranslationModCommand}"
|
||||
Content="{ll:Str 保存为翻译模组}"
|
||||
IsEnabled="False"
|
||||
Style="{DynamicResource ThemedButtonStyle}" />
|
||||
<!--<Menu
|
||||
x:Name="Button_SaveAs"
|
||||
|
@ -39,6 +39,7 @@ namespace VPet.ModMaker.Views.ModEdit;
|
||||
/// </summary>
|
||||
public partial class ModEditWindow : WindowX
|
||||
{
|
||||
public static ModEditWindow Current { get; private set; } = null!;
|
||||
public ModEditWindowVM ViewModel => (ModEditWindowVM)DataContext;
|
||||
public FoodPage FoodPage { get; } = null!;
|
||||
public LowTextPage LowTextPage { get; } = null!;
|
||||
@ -51,6 +52,7 @@ public partial class ModEditWindow : WindowX
|
||||
|
||||
public ModEditWindow()
|
||||
{
|
||||
Current = this;
|
||||
InitializeComponent();
|
||||
DataContext = new ModEditWindowVM(this);
|
||||
Closing += ModEditWindow_Closing;
|
||||
@ -60,10 +62,9 @@ public partial class ModEditWindow : WindowX
|
||||
ClickTextPage = new();
|
||||
SelectTextPage = new();
|
||||
PetPage = new();
|
||||
//TODO
|
||||
//WorkPage = new();
|
||||
//MovePage = new();
|
||||
//AnimePage = new();
|
||||
WorkPage = new();
|
||||
MovePage = new();
|
||||
AnimePage = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -39,12 +39,12 @@ public partial class MoveEditWindow : Window
|
||||
};
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.Move.Graph))
|
||||
{
|
||||
|
@ -61,7 +61,7 @@
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Id}" />
|
||||
<TextBlock Text="{Binding ID}" />
|
||||
<TextBlock Text="{ll:Str {} (来自本体)}" Visibility="{Binding FromMain, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
@ -85,7 +85,7 @@
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowMoves}"
|
||||
ItemsSource="{Binding Moves.FilteredList}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="50"
|
||||
@ -107,26 +107,26 @@
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Graph" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding LocateType.EnumValue}"
|
||||
Binding="{Binding LocateType.Value}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 定位类型}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="LocateType.EnumValue" />
|
||||
SortMemberPath="LocateType.Value" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding TriggerType.EnumValue}"
|
||||
Binding="{Binding TriggerType.Value}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 触发类型}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="TriggerType.EnumValue" />
|
||||
SortMemberPath="TriggerType.Value" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding ModeType.EnumValue}"
|
||||
Binding="{Binding ModeType.Value}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 状态类型}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="ModeType.EnumValue" />
|
||||
SortMemberPath="ModeType.Value" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Distance}"
|
||||
CanUserSort="True"
|
||||
|
@ -30,10 +30,10 @@ public partial class MovePage : Page
|
||||
|
||||
public MovePageVM ViewModel => (MovePageVM)DataContext;
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not MoveModel model)
|
||||
return;
|
||||
ViewModel.Edit(model);
|
||||
ViewModel.EditCommand_ExecuteCommand(model);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
<ResourceDictionary Source="/VPet-Simulator.Windows.Interface;component/ResourceStyle.xaml" />
|
||||
<ResourceDictionary>
|
||||
<Style
|
||||
x:Key="Label_ThouchRect"
|
||||
x:Key="Label_ThouchRectangleLocation"
|
||||
BasedOn="{StaticResource {x:Type Label}}"
|
||||
TargetType="Label">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
@ -40,7 +40,6 @@
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -68,11 +67,11 @@
|
||||
<Grid>
|
||||
<Label Content="{ll:Str 头部触碰范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchHead}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchHeadRect.Width" />
|
||||
<Binding Path="Pet.TouchHeadRectangleLocation.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -80,7 +79,7 @@
|
||||
<Setter Property="Height">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchHeadRect.Height" />
|
||||
<Binding Path="Pet.TouchHeadRectangleLocation.Height" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -89,8 +88,8 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="Pet.TouchHeadRect.X" />
|
||||
<Binding Path="Pet.TouchHeadRect.Y" />
|
||||
<Binding Path="Pet.TouchHeadRectangleLocation.X" />
|
||||
<Binding Path="Pet.TouchHeadRectangleLocation.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@ -99,11 +98,11 @@
|
||||
</Label>
|
||||
<Label Content="{ll:Str 身体触碰范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchBody}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchBodyRect.Width" />
|
||||
<Binding Path="Pet.TouchBodyRectangleLocation.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -111,7 +110,7 @@
|
||||
<Setter Property="Height">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchBodyRect.Height" />
|
||||
<Binding Path="Pet.TouchBodyRectangleLocation.Height" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -120,21 +119,21 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="Pet.TouchBodyRect.X" />
|
||||
<Binding Path="Pet.TouchBodyRect.Y" />
|
||||
<Binding Path="Pet.TouchBodyRectangleLocation.X" />
|
||||
<Binding Path="Pet.TouchBodyRectangleLocation.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Label.Style>
|
||||
</Label>
|
||||
<Label Content="{ll:Str 开心状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRect_HappyState}">
|
||||
<Label Content="{ll:Str 开心状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRectangleLocation_HappyState}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.Happy.Width" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Happy.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -142,7 +141,7 @@
|
||||
<Setter Property="Height">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.Happy.Height" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Happy.Height" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -151,21 +150,21 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="Pet.TouchRaisedRect.Happy.X" />
|
||||
<Binding Path="Pet.TouchRaisedRect.Happy.Y" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Happy.X" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Happy.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Label.Style>
|
||||
</Label>
|
||||
<Label Content="{ll:Str 普通状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRect_NomalState}">
|
||||
<Label Content="{ll:Str 普通状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRectangleLocation_NomalState}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.Nomal.Width" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Nomal.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -173,7 +172,7 @@
|
||||
<Setter Property="Height">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.Nomal.Height" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Nomal.Height" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -182,21 +181,21 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="Pet.TouchRaisedRect.Nomal.X" />
|
||||
<Binding Path="Pet.TouchRaisedRect.Nomal.Y" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Nomal.X" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Nomal.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Label.Style>
|
||||
</Label>
|
||||
<Label Content="{ll:Str 低状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRect_PoorConditionState}">
|
||||
<Label Content="{ll:Str 低状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRectangleLocation_PoorConditionState}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.PoorCondition.Width" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.PoorCondition.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -204,7 +203,7 @@
|
||||
<Setter Property="Height">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.PoorCondition.Height" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.PoorCondition.Height" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -213,21 +212,21 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="Pet.TouchRaisedRect.PoorCondition.X" />
|
||||
<Binding Path="Pet.TouchRaisedRect.PoorCondition.Y" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.PoorCondition.X" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.PoorCondition.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Label.Style>
|
||||
</Label>
|
||||
<Label Content="{ll:Str 生病状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRect_IllState}">
|
||||
<Label Content="{ll:Str 生病状态提起范围}" Tag="{Binding IsChecked, ElementName=ToggleButton_TouchRaisedRectangleLocation_IllState}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.Ill.Width" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Ill.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -235,7 +234,7 @@
|
||||
<Setter Property="Height">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="Pet.TouchRaisedRect.Ill.Height" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Ill.Height" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -244,8 +243,8 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="Pet.TouchRaisedRect.Ill.X" />
|
||||
<Binding Path="Pet.TouchRaisedRect.Ill.Y" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Ill.X" />
|
||||
<Binding Path="Pet.TouchRaisedRectangleLocation.Ill.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@ -259,7 +258,7 @@
|
||||
Content="{ll:Str 开心状态提起点位}"
|
||||
Tag="{Binding IsChecked, ElementName=ToggleButton_RaisePoint_Happy}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Margin">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
@ -279,7 +278,7 @@
|
||||
Content="{ll:Str 普通状态提起点位}"
|
||||
Tag="{Binding IsChecked, ElementName=ToggleButton_RaisePoint_Nomal}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Margin">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
@ -299,7 +298,7 @@
|
||||
Content="{ll:Str 低状态提起点位}"
|
||||
Tag="{Binding IsChecked, ElementName=ToggleButton_RaisePoint_PoorCondition}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Margin">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
@ -319,7 +318,7 @@
|
||||
Content="{ll:Str 生病状态提起点位}"
|
||||
Tag="{Binding IsChecked, ElementName=ToggleButton_RaisePoint_Ill}">
|
||||
<Label.Style>
|
||||
<Style BasedOn="{StaticResource Label_ThouchRect}" TargetType="Label">
|
||||
<Style BasedOn="{StaticResource Label_ThouchRectangleLocation}" TargetType="Label">
|
||||
<Setter Property="Margin">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
@ -358,6 +357,12 @@
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="ID"
|
||||
Text="{Binding Pet.ID, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="1" Content="{ll:Str 标签}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str '标签, 用英文逗号分隔'}"
|
||||
Text="{Binding Pet.Tags, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<!--<Label Grid.Row="1" Content="{ll:Str 名称}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
@ -401,6 +406,7 @@
|
||||
x:Name="ToggleButton_TouchHead"
|
||||
Padding="5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
d:IsChecked="True"
|
||||
Content="{ll:Str 头部触碰范围}" />
|
||||
<Grid Grid.Column="1" Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
@ -414,12 +420,18 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="{x:Null}" Content="x:" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchHeadRect.X}" />
|
||||
<pu:NumberInput
|
||||
Grid.Column="1"
|
||||
d:Value="100"
|
||||
Value="{Binding Pet.TouchHeadRectangleLocation.X}" />
|
||||
<Label
|
||||
Grid.Column="2"
|
||||
Background="{x:Null}"
|
||||
Content="y:" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchHeadRect.Y, Mode=TwoWay}" />
|
||||
<pu:NumberInput
|
||||
Grid.Column="3"
|
||||
d:Value="100"
|
||||
Value="{Binding Pet.TouchHeadRectangleLocation.Y, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Background="{x:Null}"
|
||||
@ -427,7 +439,8 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Pet.TouchHeadRect.Width, Mode=TwoWay}" />
|
||||
d:Value="100"
|
||||
Value="{Binding Pet.TouchHeadRectangleLocation.Width, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
@ -436,7 +449,8 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Value="{Binding Pet.TouchHeadRect.Height, Mode=TwoWay}" />
|
||||
d:Value="100"
|
||||
Value="{Binding Pet.TouchHeadRectangleLocation.Height, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid>
|
||||
@ -461,12 +475,12 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="{x:Null}" Content="x:" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchBodyRect.X}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchBodyRectangleLocation.X}" />
|
||||
<Label
|
||||
Grid.Column="2"
|
||||
Background="{x:Null}"
|
||||
Content="y:" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchBodyRect.Y, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchBodyRectangleLocation.Y, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Background="{x:Null}"
|
||||
@ -474,7 +488,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Pet.TouchBodyRect.Width, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchBodyRectangleLocation.Width, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
@ -483,7 +497,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Value="{Binding Pet.TouchBodyRect.Height, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchBodyRectangleLocation.Height, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Expander Header="{ll:Str 提起范围}">
|
||||
@ -499,7 +513,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ToggleButton
|
||||
x:Name="ToggleButton_TouchRaisedRect_HappyState"
|
||||
x:Name="ToggleButton_TouchRaisedRectangleLocation_HappyState"
|
||||
Padding="5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
d:IsChecked="True"
|
||||
@ -516,12 +530,12 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="{x:Null}" Content="x:" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRect.Happy.X, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRectangleLocation.Happy.X, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Column="2"
|
||||
Background="{x:Null}"
|
||||
Content="y:" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRect.Happy.Y, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRectangleLocation.Happy.Y, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Background="{x:Null}"
|
||||
@ -529,7 +543,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Pet.TouchRaisedRect.Happy.Width, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.Happy.Width, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
@ -538,10 +552,10 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Value="{Binding Pet.TouchRaisedRect.Happy.Height, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.Happy.Height, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<ToggleButton
|
||||
x:Name="ToggleButton_TouchRaisedRect_NomalState"
|
||||
x:Name="ToggleButton_TouchRaisedRectangleLocation_NomalState"
|
||||
Grid.Row="1"
|
||||
Padding="5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
@ -562,12 +576,12 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="{x:Null}" Content="x:" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRect.Nomal.X, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRectangleLocation.Nomal.X, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Column="2"
|
||||
Background="{x:Null}"
|
||||
Content="y:" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRect.Nomal.Y, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRectangleLocation.Nomal.Y, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Background="{x:Null}"
|
||||
@ -575,7 +589,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Pet.TouchRaisedRect.Nomal.Width, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.Nomal.Width, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
@ -584,10 +598,10 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Value="{Binding Pet.TouchRaisedRect.Nomal.Height, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.Nomal.Height, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<ToggleButton
|
||||
x:Name="ToggleButton_TouchRaisedRect_PoorConditionState"
|
||||
x:Name="ToggleButton_TouchRaisedRectangleLocation_PoorConditionState"
|
||||
Grid.Row="2"
|
||||
Padding="5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
@ -608,12 +622,12 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="{x:Null}" Content="x:" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRect.PoorCondition.X, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRectangleLocation.PoorCondition.X, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Column="2"
|
||||
Background="{x:Null}"
|
||||
Content="y:" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRect.PoorCondition.Y, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRectangleLocation.PoorCondition.Y, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Background="{x:Null}"
|
||||
@ -621,7 +635,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Pet.TouchRaisedRect.PoorCondition.Width, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.PoorCondition.Width, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
@ -630,10 +644,10 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Value="{Binding Pet.TouchRaisedRect.PoorCondition.Height, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.PoorCondition.Height, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<ToggleButton
|
||||
x:Name="ToggleButton_TouchRaisedRect_IllState"
|
||||
x:Name="ToggleButton_TouchRaisedRectangleLocation_IllState"
|
||||
Grid.Row="3"
|
||||
Padding="5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
@ -654,12 +668,12 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Background="{x:Null}" Content="x:" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRect.Ill.X, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Pet.TouchRaisedRectangleLocation.Ill.X, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Column="2"
|
||||
Background="{x:Null}"
|
||||
Content="y:" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRect.Ill.Y, Mode=TwoWay}" />
|
||||
<pu:NumberInput Grid.Column="3" Value="{Binding Pet.TouchRaisedRectangleLocation.Ill.Y, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Background="{x:Null}"
|
||||
@ -667,7 +681,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Pet.TouchRaisedRect.Ill.Width, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.Ill.Width, Mode=TwoWay}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
@ -676,7 +690,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Value="{Binding Pet.TouchRaisedRect.Ill.Height, Mode=TwoWay}" />
|
||||
Value="{Binding Pet.TouchRaisedRectangleLocation.Ill.Height, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Expander>
|
||||
|
@ -40,12 +40,12 @@ public partial class PetEditWindow : Window
|
||||
};
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Pet.ID))
|
||||
{
|
||||
|
@ -95,6 +95,13 @@
|
||||
Header="{ll:Str 宠物名称}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Name" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Tags}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 标签}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Tags" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Description}"
|
||||
CanUserSort="True"
|
||||
|
@ -30,10 +30,10 @@ public partial class PetPage : Page
|
||||
DataContext = new PetPageVM();
|
||||
}
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not PetModel model)
|
||||
return;
|
||||
ViewModel.Edit(model);
|
||||
ViewModel.EditCommand_ExecuteCommand(model);
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,12 @@ public partial class SelectTextEditWindow : Window
|
||||
};
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.SelectText.ID))
|
||||
{
|
||||
|
@ -84,12 +84,12 @@
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="ToTags" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Mode.EnumValue}"
|
||||
Binding="{Binding Mode.Value}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 状态}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Mode.EnumValue" />
|
||||
SortMemberPath="Mode.Value" />
|
||||
<DataGridTextColumn
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
|
@ -30,7 +30,7 @@ public partial class SelectTextPage : Page
|
||||
DataContext = new SelectTextPageVM();
|
||||
}
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not SelectTextModel model)
|
||||
return;
|
||||
|
@ -126,8 +126,8 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="Id" />
|
||||
<TextBox Grid.Column="1" Text="{Binding Work.Id}" />
|
||||
<Label Content="ID" />
|
||||
<TextBox Grid.Column="1" Text="{Binding Work.ID}" />
|
||||
<Label Grid.Row="1" Content="{ll:Str 名称}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
@ -143,7 +143,7 @@
|
||||
<TextBox
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Text="{Binding Work.Graph}" />
|
||||
Text="{Binding Work.Graph, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="4" Content="{ll:Str 是否超模}" />
|
||||
<Grid Grid.Row="4" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -154,7 +154,10 @@
|
||||
d:Text="True"
|
||||
Style="{DynamicResource TextBlock_LeftCenter}"
|
||||
Text="{Binding Work.IsOverLoad}" />
|
||||
<Button Grid.Column="1" Content="{ll:Str 修复超模}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Command="{Binding FixOverLoadCommand}"
|
||||
Content="{ll:Str 修复超模}" />
|
||||
</Grid>
|
||||
<!--<Label Grid.Row="3" Content="{ll:Str 宠物描述}" />
|
||||
<TextBox
|
||||
|
@ -28,27 +28,20 @@ public partial class WorkEditWindow : Window
|
||||
public WorkEditWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = new WorkEditWindowVM();
|
||||
Closed += (s, e) =>
|
||||
{
|
||||
this.SetDataContext<WorkEditWindowVM>(() => {
|
||||
//TODO
|
||||
//ViewModel.Close();
|
||||
try
|
||||
{
|
||||
DataContext = null;
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Cancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
private void Button_Yes_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.Work.Id))
|
||||
if (string.IsNullOrEmpty(ViewModel.Work.ID))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
@ -64,8 +57,8 @@ public partial class WorkEditWindow : Window
|
||||
return;
|
||||
}
|
||||
if (
|
||||
ViewModel.OldWork?.Id != ViewModel.Work.Id
|
||||
&& ViewModel.CurrentPet.Works.Any(i => i.Id == ViewModel.Work.Id)
|
||||
ViewModel.OldWork?.ID != ViewModel.Work.ID
|
||||
&& ViewModel.CurrentPet.Works.Any(i => i.ID == ViewModel.Work.ID)
|
||||
)
|
||||
{
|
||||
MessageBox.Show("此Id已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
|
@ -26,7 +26,7 @@
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}" Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索ID}" Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox.Style>
|
||||
<Style BasedOn="{StaticResource StandardTextBoxStyle}" TargetType="TextBox">
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
@ -65,7 +65,7 @@
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Id}" />
|
||||
<TextBlock Text="{Binding ID}" />
|
||||
<TextBlock Text="{ll:Str {} (来自本体)}" Visibility="{Binding FromMain, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
@ -89,7 +89,7 @@
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowWorks}"
|
||||
ItemsSource="{Binding Works.FilteredList}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="64"
|
||||
@ -104,12 +104,12 @@
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Id}"
|
||||
Binding="{Binding ID}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="Id"
|
||||
Header="ID"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id" />
|
||||
SortMemberPath="ID" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Name}"
|
||||
CanUserSort="True"
|
||||
|
@ -30,10 +30,10 @@ public partial class WorkPage : Page
|
||||
DataContext = new WorkPageVM();
|
||||
}
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void DataGrid_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not WorkModel model)
|
||||
return;
|
||||
ViewModel.Edit(model);
|
||||
ViewModel.EditCommand_ExecuteCommand(model);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
<TextBox
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 最近的内容}"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding HistoriesSearchText}" />
|
||||
Text="{Binding Search}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Command="{Binding ClearHistoriesCommand}"
|
||||
@ -47,7 +47,7 @@
|
||||
<ListBox
|
||||
Grid.Row="2"
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
ItemsSource="{Binding ShowHistories}"
|
||||
ItemsSource="{Binding Histories.FilteredList}"
|
||||
Style="{DynamicResource SideMenuListBoxStyle}">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="ListBoxItem">
|
||||
@ -82,7 +82,7 @@
|
||||
<TextBlock
|
||||
d:Text="{ll:Str Mod名称}"
|
||||
FontWeight="Bold"
|
||||
Text="{Binding Id}"
|
||||
Text="{Binding ID}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Right"
|
||||
|
@ -41,7 +41,7 @@ public partial class ModMakerWindow : WindowX
|
||||
//new AnimeEditWindow().Show();
|
||||
}
|
||||
|
||||
private void ModMakerWindow_Closed(object sender, EventArgs e)
|
||||
private void ModMakerWindow_Closed(object? sender, EventArgs e)
|
||||
{
|
||||
// 当模组载入错误时, 会产生野窗口, 需要手动关闭
|
||||
foreach (var item in Application.Current.Windows)
|
||||
@ -51,7 +51,7 @@ public partial class ModMakerWindow : WindowX
|
||||
}
|
||||
}
|
||||
|
||||
private void ListBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
private void ListBoxItem_MouseDoubleClick(object? sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not ListBoxItem item)
|
||||
return;
|
||||
@ -65,13 +65,12 @@ public partial class ModMakerWindow : WindowX
|
||||
)
|
||||
{
|
||||
ViewModel.Histories.Remove(history);
|
||||
ViewModel.ShowHistories.Remove(history);
|
||||
}
|
||||
}
|
||||
ViewModel.LoadMod(history.SourcePath);
|
||||
}
|
||||
|
||||
private void Hyperlink_Click(object sender, RoutedEventArgs e)
|
||||
private void Hyperlink_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start(new ProcessStartInfo("https://github.com/LorisYounger/VPet.ModMaker/wiki"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user