mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
856 lines
24 KiB
C#
856 lines
24 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Media.Imaging;
|
|
using HKW.HKWUtils;
|
|
using HKW.HKWUtils.Observable;
|
|
using LinePutScript;
|
|
using LinePutScript.Converter;
|
|
using LinePutScript.Localization.WPF;
|
|
using Mapster;
|
|
using VPet.ModMaker.Models.ModModel;
|
|
using VPet_Simulator.Core;
|
|
|
|
namespace VPet.ModMaker.Models;
|
|
|
|
/// <summary>
|
|
/// 宠物模型
|
|
/// </summary>
|
|
public class PetModel : ObservableObjectX
|
|
{
|
|
public PetModel()
|
|
{
|
|
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;
|
|
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);
|
|
}
|
|
|
|
public PetModel(PetLoader loader, bool fromMain = false)
|
|
: this()
|
|
{
|
|
ID = loader.Name;
|
|
PetNameID = loader.PetName;
|
|
DescriptionID = loader.Intor;
|
|
Tags = loader.Config.Data["tag"].Info;
|
|
|
|
TouchHeadRectangleLocation = new(
|
|
loader.Config.TouchHeadLocate.X,
|
|
loader.Config.TouchHeadLocate.Y,
|
|
loader.Config.TouchHeadSize.Width,
|
|
loader.Config.TouchHeadSize.Height
|
|
);
|
|
|
|
TouchBodyRectangleLocation = new(
|
|
loader.Config.TouchBodyLocate.X,
|
|
loader.Config.TouchBodyLocate.Y,
|
|
loader.Config.TouchBodySize.Width,
|
|
loader.Config.TouchBodySize.Height
|
|
);
|
|
|
|
TouchRaisedRectangleLocation.Happy = new(
|
|
loader.Config.TouchRaisedLocate[0].X,
|
|
loader.Config.TouchRaisedLocate[0].Y,
|
|
loader.Config.TouchRaisedSize[0].Width,
|
|
loader.Config.TouchRaisedSize[0].Height
|
|
);
|
|
TouchRaisedRectangleLocation.Nomal = new(
|
|
loader.Config.TouchRaisedLocate[1].X,
|
|
loader.Config.TouchRaisedLocate[1].Y,
|
|
loader.Config.TouchRaisedSize[1].Width,
|
|
loader.Config.TouchRaisedSize[1].Height
|
|
);
|
|
TouchRaisedRectangleLocation.PoorCondition = new(
|
|
loader.Config.TouchRaisedLocate[2].X,
|
|
loader.Config.TouchRaisedLocate[2].Y,
|
|
loader.Config.TouchRaisedSize[2].Width,
|
|
loader.Config.TouchRaisedSize[2].Height
|
|
);
|
|
TouchRaisedRectangleLocation.Ill = new(
|
|
loader.Config.TouchRaisedLocate[3].X,
|
|
loader.Config.TouchRaisedLocate[3].Y,
|
|
loader.Config.TouchRaisedSize[3].Width,
|
|
loader.Config.TouchRaisedSize[3].Height
|
|
);
|
|
|
|
RaisePoint.Happy = new(loader.Config.RaisePoint[0].X, loader.Config.RaisePoint[0].Y);
|
|
RaisePoint.Nomal = new(loader.Config.RaisePoint[1].X, loader.Config.RaisePoint[1].Y);
|
|
RaisePoint.PoorCondition = new(
|
|
loader.Config.RaisePoint[2].X,
|
|
loader.Config.RaisePoint[2].Y
|
|
);
|
|
RaisePoint.Ill = new(loader.Config.RaisePoint[3].X, loader.Config.RaisePoint[3].Y);
|
|
// 如果这个宠物数据来自本体, 则不载入 Work 和 Move
|
|
if (FromMain = fromMain)
|
|
return;
|
|
|
|
foreach (var work in loader.Config.Works)
|
|
Works.Add(new(work) { I18nResource = I18nResource! });
|
|
foreach (var move in loader.Config.Moves)
|
|
Moves.Add(new(move));
|
|
}
|
|
|
|
public static PetModel Default { get; } = new() { I18nResource = 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 = 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 I18nData
|
|
[AdaptIgnore]
|
|
private I18nResource<string, string> _i18nResource = null!;
|
|
|
|
[AdaptIgnore]
|
|
public required I18nResource<string, string> I18nResource
|
|
{
|
|
get => _i18nResource;
|
|
set
|
|
{
|
|
if (_i18nResource is not null)
|
|
I18nResource.I18nObjectInfos.Remove(this);
|
|
_i18nResource = value;
|
|
InitializeI18nResource();
|
|
}
|
|
}
|
|
|
|
public void InitializeI18nResource()
|
|
{
|
|
I18nResource.I18nObjectInfos.Add(
|
|
this,
|
|
new I18nObjectInfo<string, string>(this, OnPropertyChanged).AddPropertyInfo(
|
|
[
|
|
(nameof(ID), ID, nameof(Name)),
|
|
(nameof(PetNameID), PetNameID, nameof(PetName)),
|
|
(nameof(DescriptionID), DescriptionID, nameof(Description))
|
|
],
|
|
true
|
|
)
|
|
);
|
|
foreach (var work in Works)
|
|
work.I18nResource = I18nResource;
|
|
if (FromMain)
|
|
{
|
|
foreach (var cultureName in LocalizeCore.AvailableCultures)
|
|
{
|
|
if (CultureUtils.TryGetCultureInfo(cultureName, out var culture) is false)
|
|
continue;
|
|
if (LocalizeCore.Localizations.TryGetValue(cultureName, out var data) is false)
|
|
continue;
|
|
foreach (var line in data)
|
|
{
|
|
if (line?.Name == ID)
|
|
{
|
|
I18nResource.AddCultureData(culture, ID, line.Info);
|
|
}
|
|
else if (line?.Name == PetNameID)
|
|
{
|
|
I18nResource.AddCultureData(culture, PetNameID, line.Info);
|
|
}
|
|
else if (line?.Name == DescriptionID)
|
|
{
|
|
I18nResource.AddCultureData(culture, DescriptionID, line.Info);
|
|
}
|
|
}
|
|
I18nResource.AddCultureData(culture, ID, ID);
|
|
I18nResource.AddCultureData(culture, PetNameID, PetNameID);
|
|
I18nResource.AddCultureData(culture, DescriptionID, DescriptionID);
|
|
}
|
|
}
|
|
}
|
|
|
|
[AdaptIgnore]
|
|
public string Name
|
|
{
|
|
get => I18nResource.GetCurrentCultureDataOrDefault(ID);
|
|
set => I18nResource.SetCurrentCultureData(ID, value);
|
|
}
|
|
|
|
[AdaptIgnore]
|
|
public string PetName
|
|
{
|
|
get => I18nResource.GetCurrentCultureDataOrDefault(PetNameID);
|
|
set => I18nResource.SetCurrentCultureData(PetNameID, value);
|
|
}
|
|
|
|
[AdaptIgnore]
|
|
public string Description
|
|
{
|
|
get => I18nResource.GetCurrentCultureDataOrDefault(DescriptionID);
|
|
set => I18nResource.SetCurrentCultureData(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 ObservableRectangle<double> _touchHeadRectangleLocation = new(159, 16, 189, 178);
|
|
|
|
/// <summary>
|
|
/// 头部点击区域
|
|
/// </summary>
|
|
public ObservableRectangle<double> TouchHeadRectangleLocation
|
|
{
|
|
get => _touchHeadRectangleLocation;
|
|
set => SetProperty(ref _touchHeadRectangleLocation, value);
|
|
}
|
|
#endregion
|
|
|
|
#region TouchBodyRect
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservableRectangle<double> _touchBodyRectangleLocation = new(166, 206, 163, 136);
|
|
|
|
/// <summary>
|
|
/// 身体区域
|
|
/// </summary>
|
|
public ObservableRectangle<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()
|
|
{
|
|
foreach (var anime in Animes)
|
|
anime.Close();
|
|
foreach (var anime in FoodAnimes)
|
|
anime.Close();
|
|
}
|
|
|
|
public void CloseI18nResource()
|
|
{
|
|
I18nResource.I18nObjectInfos.Remove(this);
|
|
}
|
|
|
|
#region Save
|
|
|
|
/// <summary>
|
|
/// 能被保存
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool CanSave()
|
|
{
|
|
if (
|
|
FromMain
|
|
&& Works.Count == 0
|
|
&& Moves.Count == 0
|
|
&& Animes.Count == 0
|
|
&& FoodAnimes.Count == 0
|
|
)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存宠物
|
|
/// </summary>
|
|
/// <param name="path">路径</param>
|
|
public void Save(string path)
|
|
{
|
|
var petFile = Path.Combine(path, $"{ID}.lps");
|
|
if (File.Exists(petFile) is false)
|
|
File.Create(petFile).Close();
|
|
var lps = new LPS();
|
|
// 如果本体中存在相同的宠物, 则只保存差异信息
|
|
if (ModMakerInfo.MainPets.TryGetValue(ID, out var mainPet))
|
|
SaveDifferentPetInfo(lps, mainPet);
|
|
else
|
|
SavePetInfo(lps);
|
|
SaveWorksInfo(lps);
|
|
SaveMoveInfo(lps);
|
|
File.WriteAllText(petFile, lps.ToString());
|
|
|
|
// 保存图片
|
|
SaveAnime(path);
|
|
}
|
|
|
|
private void SaveAnime(string path)
|
|
{
|
|
var petAnimePath = Path.Combine(path, ID);
|
|
foreach (var anime in Animes)
|
|
anime.Save(petAnimePath);
|
|
foreach (var anime in FoodAnimes)
|
|
anime.Save(petAnimePath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存移动信息
|
|
/// </summary>
|
|
/// <param name="lps"></param>
|
|
void SaveMoveInfo(LPS lps)
|
|
{
|
|
foreach (var move in Moves)
|
|
{
|
|
lps.Add(LPSConvert.SerializeObjectToLine<Line>(move.ToMove(), "move"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存工作信息
|
|
/// </summary>
|
|
/// <param name="lps"></param>
|
|
void SaveWorksInfo(LPS lps)
|
|
{
|
|
foreach (var work in Works)
|
|
{
|
|
lps.Add(LPSConvert.SerializeObjectToLine<Line>(work.ToWork(), "work"));
|
|
}
|
|
}
|
|
|
|
#region SavePetInfo
|
|
/// <summary>
|
|
/// 保存宠物信息
|
|
/// </summary>
|
|
/// <param name="lps"></param>
|
|
private void SavePetInfo(LPS lps)
|
|
{
|
|
SavePetBasicInfo(lps);
|
|
SavePetTouchHeadInfo(lps);
|
|
SavePetTouchBodyInfo(lps);
|
|
SavePetTouchRaisedInfo(lps);
|
|
SavePetRaisePointInfo(lps);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存差异宠物信息
|
|
/// <para>
|
|
/// 用于本体存在同名宠物的情况下
|
|
/// </para>
|
|
/// </summary>
|
|
/// <param name="lps"></param>
|
|
/// <param name="mainPet">本体宠物</param>
|
|
private void SaveDifferentPetInfo(LPS lps, PetModel mainPet)
|
|
{
|
|
SavePetBasicInfo(lps);
|
|
// 如果值不为默认并且不与本体值相同, 则保存
|
|
if (
|
|
TouchHeadRectangleLocation != Default.TouchHeadRectangleLocation
|
|
&& TouchHeadRectangleLocation != mainPet.TouchHeadRectangleLocation
|
|
)
|
|
SavePetTouchHeadInfo(lps);
|
|
if (
|
|
TouchBodyRectangleLocation != Default.TouchBodyRectangleLocation
|
|
&& TouchBodyRectangleLocation != mainPet.TouchBodyRectangleLocation
|
|
)
|
|
SavePetTouchBodyInfo(lps);
|
|
if (
|
|
TouchRaisedRectangleLocation != Default.TouchRaisedRectangleLocation
|
|
&& TouchRaisedRectangleLocation != mainPet.TouchRaisedRectangleLocation
|
|
)
|
|
SavePetTouchRaisedInfo(lps);
|
|
if (RaisePoint != Default.RaisePoint && RaisePoint != mainPet.RaisePoint)
|
|
SavePetRaisePointInfo(lps);
|
|
}
|
|
|
|
private void SavePetBasicInfo(LPS lps)
|
|
{
|
|
lps.Add(
|
|
new Line("pet", ID)
|
|
{
|
|
new Sub("intor", DescriptionID),
|
|
new Sub("path", ID),
|
|
new Sub("petname", PetNameID)
|
|
}
|
|
);
|
|
if (string.IsNullOrWhiteSpace(Tags) is false)
|
|
lps.Add(new Line("tag", Tags));
|
|
}
|
|
|
|
private void SavePetTouchHeadInfo(LPS lps)
|
|
{
|
|
lps.Add(
|
|
new Line("touchhead")
|
|
{
|
|
new Sub("px", TouchHeadRectangleLocation.X),
|
|
new Sub("py", TouchHeadRectangleLocation.Y),
|
|
new Sub("sw", TouchHeadRectangleLocation.Width),
|
|
new Sub("sh", TouchHeadRectangleLocation.Height),
|
|
}
|
|
);
|
|
}
|
|
|
|
private void SavePetTouchBodyInfo(LPS lps)
|
|
{
|
|
lps.Add(
|
|
new Line("touchbody")
|
|
{
|
|
new Sub("px", TouchBodyRectangleLocation.X),
|
|
new Sub("py", TouchBodyRectangleLocation.Y),
|
|
new Sub("sw", TouchBodyRectangleLocation.Width),
|
|
new Sub("sh", TouchBodyRectangleLocation.Height),
|
|
}
|
|
);
|
|
}
|
|
|
|
private void SavePetTouchRaisedInfo(LPS lps)
|
|
{
|
|
lps.Add(
|
|
new Line("touchraised")
|
|
{
|
|
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", 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", 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", TouchRaisedRectangleLocation.Ill.X),
|
|
new Sub("ill_py", TouchRaisedRectangleLocation.Ill.Y),
|
|
new Sub("ill_sw", TouchRaisedRectangleLocation.Ill.Width),
|
|
new Sub("ill_sh", TouchRaisedRectangleLocation.Ill.Height),
|
|
}
|
|
);
|
|
}
|
|
|
|
private void SavePetRaisePointInfo(LPS lps)
|
|
{
|
|
lps.Add(
|
|
new Line("raisepoint")
|
|
{
|
|
new Sub("happy_x", RaisePoint.Happy.X),
|
|
new Sub("happy_y", RaisePoint.Happy.Y),
|
|
//
|
|
new Sub("nomal_x", RaisePoint.Nomal.X),
|
|
new Sub("nomal_y", RaisePoint.Nomal.Y),
|
|
//
|
|
new Sub("poorcondition_x", RaisePoint.PoorCondition.X),
|
|
new Sub("poorcondition_y", RaisePoint.PoorCondition.Y),
|
|
//
|
|
new Sub("ill_x", RaisePoint.Ill.X),
|
|
new Sub("ill_y", RaisePoint.Ill.Y),
|
|
}
|
|
);
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
|
|
public class ObservableMultiStateRectangleLocation
|
|
: ObservableObjectX,
|
|
IEquatable<ObservableMultiStateRectangleLocation>,
|
|
ICloneable<ObservableMultiStateRectangleLocation>
|
|
{
|
|
#region Happy
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservableRectangle<double> _happy = null!;
|
|
public ObservableRectangle<double> Happy
|
|
{
|
|
get => _happy;
|
|
set => SetProperty(ref _happy, value);
|
|
}
|
|
#endregion
|
|
|
|
#region Nomal
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservableRectangle<double> _nomal = null!;
|
|
|
|
public ObservableRectangle<double> Nomal
|
|
{
|
|
get => _nomal;
|
|
set => SetProperty(ref _nomal, value);
|
|
}
|
|
#endregion
|
|
|
|
#region PoorCondition
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservableRectangle<double> _poorCondition = null!;
|
|
public ObservableRectangle<double> PoorCondition
|
|
{
|
|
get => _poorCondition;
|
|
set => SetProperty(ref _poorCondition, value);
|
|
}
|
|
#endregion
|
|
|
|
#region Ill
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservableRectangle<double> _ill = null!;
|
|
public ObservableRectangle<double> Ill
|
|
{
|
|
get => _ill;
|
|
set => SetProperty(ref _ill, value);
|
|
}
|
|
#endregion
|
|
|
|
public ObservableMultiStateRectangleLocation()
|
|
{
|
|
Happy = new();
|
|
Nomal = new();
|
|
PoorCondition = new();
|
|
Ill = new();
|
|
}
|
|
|
|
public ObservableMultiStateRectangleLocation(
|
|
ObservableRectangle<double> happy,
|
|
ObservableRectangle<double> nomal,
|
|
ObservableRectangle<double> poorCondition,
|
|
ObservableRectangle<double> ill
|
|
)
|
|
{
|
|
Happy = happy;
|
|
Nomal = nomal;
|
|
PoorCondition = poorCondition;
|
|
Ill = ill;
|
|
}
|
|
|
|
public ObservableMultiStateRectangleLocation Clone()
|
|
{
|
|
return new()
|
|
{
|
|
Happy = Happy.Clone(),
|
|
Nomal = Nomal.Clone(),
|
|
PoorCondition = PoorCondition.Clone(),
|
|
Ill = Ill.Clone(),
|
|
};
|
|
}
|
|
|
|
object ICloneable.Clone() => Clone();
|
|
|
|
#region Other
|
|
|
|
/// <inheritdoc/>
|
|
public override int GetHashCode()
|
|
{
|
|
return HashCode.Combine(Happy, Nomal, PoorCondition, Ill);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override bool Equals(object? obj)
|
|
{
|
|
return Equals(obj as ObservableMultiStateRectangleLocation);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public bool Equals(ObservableMultiStateRectangleLocation? other)
|
|
{
|
|
return Happy.Equals(other?.Happy)
|
|
&& Nomal.Equals(other?.Nomal)
|
|
&& PoorCondition.Equals(other?.PoorCondition)
|
|
&& Ill.Equals(other?.Ill);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public static bool operator ==(
|
|
ObservableMultiStateRectangleLocation a,
|
|
ObservableMultiStateRectangleLocation b
|
|
)
|
|
{
|
|
return Equals(a, b);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public static bool operator !=(
|
|
ObservableMultiStateRectangleLocation a,
|
|
ObservableMultiStateRectangleLocation b
|
|
)
|
|
{
|
|
return Equals(a, b) is not true;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class ObservableMultiStatePoint
|
|
: ObservableObjectX,
|
|
IEquatable<ObservableMultiStatePoint>,
|
|
ICloneable<ObservableMultiStatePoint>
|
|
{
|
|
#region Happy
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservablePoint<double> _happy = null!;
|
|
public ObservablePoint<double> Happy
|
|
{
|
|
get => _happy;
|
|
set => SetProperty(ref _happy, value);
|
|
}
|
|
#endregion
|
|
|
|
#region Nomal
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservablePoint<double> _nomal = null!;
|
|
public ObservablePoint<double> Nomal
|
|
{
|
|
get => _nomal;
|
|
set => SetProperty(ref _nomal, value);
|
|
}
|
|
#endregion
|
|
|
|
#region PoorCondition
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservablePoint<double> _poorCondition = null!;
|
|
public ObservablePoint<double> PoorCondition
|
|
{
|
|
get => _poorCondition;
|
|
set => SetProperty(ref _poorCondition, value);
|
|
}
|
|
#endregion
|
|
|
|
#region Ill
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
private ObservablePoint<double> _ill = null!;
|
|
public ObservablePoint<double> Ill
|
|
{
|
|
get => _ill;
|
|
set => SetProperty(ref _ill, value);
|
|
}
|
|
#endregion
|
|
public ObservableMultiStatePoint()
|
|
{
|
|
Happy = new();
|
|
Nomal = new();
|
|
PoorCondition = new();
|
|
Ill = new();
|
|
}
|
|
|
|
public ObservableMultiStatePoint(
|
|
ObservablePoint<double> happy,
|
|
ObservablePoint<double> nomal,
|
|
ObservablePoint<double> poorCondition,
|
|
ObservablePoint<double> ill
|
|
)
|
|
{
|
|
Happy = happy;
|
|
Nomal = nomal;
|
|
PoorCondition = poorCondition;
|
|
Ill = ill;
|
|
}
|
|
|
|
public ObservableMultiStatePoint Clone()
|
|
{
|
|
return new()
|
|
{
|
|
Happy = Happy.Clone(),
|
|
Nomal = Nomal.Clone(),
|
|
PoorCondition = PoorCondition.Clone(),
|
|
Ill = Ill.Clone(),
|
|
};
|
|
}
|
|
|
|
object ICloneable.Clone() => Clone();
|
|
|
|
#region Other
|
|
|
|
/// <inheritdoc/>
|
|
public override int GetHashCode()
|
|
{
|
|
return HashCode.Combine(Happy, Nomal, PoorCondition, Ill);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override bool Equals(object? obj)
|
|
{
|
|
return Equals(obj as ObservableMultiStatePoint);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public bool Equals(ObservableMultiStatePoint? other)
|
|
{
|
|
return Happy.Equals(other?.Happy)
|
|
&& Nomal.Equals(other?.Nomal)
|
|
&& PoorCondition.Equals(other?.PoorCondition)
|
|
&& Ill.Equals(other?.Ill);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public static bool operator ==(ObservableMultiStatePoint a, ObservableMultiStatePoint b)
|
|
{
|
|
return Equals(a, b);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public static bool operator !=(ObservableMultiStatePoint a, ObservableMultiStatePoint b)
|
|
{
|
|
return Equals(a, b) is not true;
|
|
}
|
|
|
|
#endregion
|
|
}
|