mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
AnimeEdit初始化
This commit is contained in:
parent
b34d44194f
commit
63df5c128d
@ -13,7 +13,7 @@ namespace VPet.ModMaker.Converters;
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// <MultiBinding Converter="{StaticResource MarginConverter}">
|
||||
/// <Binding Path="String" />
|
||||
/// <Binding Path="StringFormat" />
|
||||
/// <Binding Path="Value1" />
|
||||
/// <Binding Path="Value2" />
|
||||
/// </MultiBinding>
|
||||
|
@ -12,151 +12,117 @@ using static VPet_Simulator.Core.GraphInfo;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class AnimeModel
|
||||
public class AnimeTypeModel
|
||||
{
|
||||
public static ObservableCollection<GraphInfo.GraphType> GraphTypes { get; } =
|
||||
new(Enum.GetValues(typeof(GraphInfo.GraphType)).Cast<GraphInfo.GraphType>());
|
||||
public static ObservableCollection<GraphInfo.AnimatType> AnimatTypes { get; } =
|
||||
new(Enum.GetValues(typeof(GraphInfo.AnimatType)).Cast<GraphInfo.AnimatType>());
|
||||
|
||||
public static ObservableCollection<GameSave.ModeType> ModeTypes { get; } =
|
||||
new(Enum.GetValues(typeof(GameSave.ModeType)).Cast<GameSave.ModeType>());
|
||||
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
|
||||
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
||||
public ObservableValue<GraphInfo.AnimatType> AnimeType { get; } = new();
|
||||
public ObservableValue<GameSave.ModeType> ModeType { get; } = new();
|
||||
|
||||
public ObservableCollection<ImageModels> MultiHappyImageModels = new();
|
||||
public ObservableCollection<ImageModels> MultiNomalImageModels = new();
|
||||
public ObservableCollection<ImageModels> MultiPoorConditionImageModels = new();
|
||||
public ObservableCollection<ImageModels> MultiIllImageModels = new();
|
||||
public ObservableCollection<AnimeModel> HappyAnimes { get; } = new();
|
||||
public ObservableCollection<AnimeModel> NomalAnimes { get; } = new();
|
||||
public ObservableCollection<AnimeModel> PoorConditionAnimes { get; } = new();
|
||||
public ObservableCollection<AnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public AnimeModel() { }
|
||||
public AnimeTypeModel() { }
|
||||
|
||||
//public AnimeModel()
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
public static AnimeModel? Load(string path)
|
||||
public AnimeTypeModel(AnimeTypeModel model)
|
||||
{
|
||||
var model = new AnimeModel();
|
||||
var infoFile = Path.Combine(path, ModMakerInfo.InfoFile);
|
||||
GraphType.Value = model.GraphType.Value;
|
||||
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());
|
||||
}
|
||||
|
||||
if (
|
||||
Enum.TryParse<GraphInfo.GraphType>(Path.GetFileName(path), true, out var graphType)
|
||||
is false
|
||||
)
|
||||
return null;
|
||||
public AnimeTypeModel(GraphInfo.GraphType graphType, string path)
|
||||
{
|
||||
GraphType.Value = graphType;
|
||||
if (graphType is GraphInfo.GraphType.Default)
|
||||
LoadDefault(path);
|
||||
}
|
||||
|
||||
private void LoadDefault(string path)
|
||||
{
|
||||
foreach (var modeDir in Directory.EnumerateDirectories(path))
|
||||
{
|
||||
foreach (var dir in Directory.EnumerateDirectories(path))
|
||||
var mode = Enum.Parse(typeof(GameSave.ModeType), Path.GetFileName(modeDir), true);
|
||||
if (mode is GameSave.ModeType.Happy)
|
||||
{
|
||||
var dirName = Path.GetFileName(dir);
|
||||
if (
|
||||
dirName.Contains(
|
||||
nameof(GameSave.ModeType.Happy),
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
)
|
||||
foreach (var imagesDir in Directory.EnumerateDirectories(modeDir))
|
||||
{
|
||||
if (Directory.GetFiles(dir).Length == 0)
|
||||
{
|
||||
foreach (var imageDir in Directory.EnumerateDirectories(dir))
|
||||
{
|
||||
model.MultiHappyImageModels.Add(new(imageDir));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model.MultiHappyImageModels.Add(new(dir));
|
||||
}
|
||||
HappyAnimes.Add(new(imagesDir));
|
||||
}
|
||||
else if (
|
||||
dirName.Contains(
|
||||
nameof(GameSave.ModeType.Nomal),
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
)
|
||||
}
|
||||
else if (mode is GameSave.ModeType.Nomal)
|
||||
{
|
||||
foreach (var imagesDir in Directory.EnumerateDirectories(modeDir))
|
||||
{
|
||||
if (Directory.GetFiles(dir).Length == 0)
|
||||
{
|
||||
foreach (var imageDir in Directory.EnumerateDirectories(dir))
|
||||
{
|
||||
model.MultiNomalImageModels.Add(new(imageDir));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model.MultiNomalImageModels.Add(new(dir));
|
||||
}
|
||||
NomalAnimes.Add(new(imagesDir));
|
||||
}
|
||||
else if (
|
||||
dirName.Contains(
|
||||
nameof(GameSave.ModeType.PoorCondition),
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
)
|
||||
}
|
||||
else if (mode is GameSave.ModeType.PoorCondition)
|
||||
{
|
||||
foreach (var imagesDir in Directory.EnumerateDirectories(modeDir))
|
||||
{
|
||||
if (Directory.GetFiles(dir).Length == 0)
|
||||
{
|
||||
foreach (var imageDir in Directory.EnumerateDirectories(dir))
|
||||
{
|
||||
model.MultiPoorConditionImageModels.Add(new(imageDir));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model.MultiPoorConditionImageModels.Add(new(dir));
|
||||
}
|
||||
PoorConditionAnimes.Add(new(imagesDir));
|
||||
}
|
||||
else if (
|
||||
dirName.Contains(
|
||||
nameof(GameSave.ModeType.Ill),
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
)
|
||||
}
|
||||
else if (mode is GameSave.ModeType.Ill)
|
||||
{
|
||||
foreach (var imagesDir in Directory.EnumerateDirectories(modeDir))
|
||||
{
|
||||
if (Directory.GetFiles(dir).Length == 0)
|
||||
{
|
||||
foreach (var imageDir in Directory.EnumerateDirectories(dir))
|
||||
{
|
||||
model.MultiIllImageModels.Add(new(imageDir));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model.MultiIllImageModels.Add(new(dir));
|
||||
}
|
||||
IllAnimes.Add(new(imagesDir));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
public class ImageModels : ObservableCollection<ImageModel>
|
||||
public class AnimeModel
|
||||
{
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
|
||||
public ObservableValue<GraphInfo.AnimatType> AnimeType { get; } = new();
|
||||
|
||||
//public ObservableValue<GameSave.ModeType> ModeType { get; } = new();
|
||||
|
||||
public ObservableCollection<ImageModel> Images { get; } = new();
|
||||
private static readonly char[] _splits = new char[] { '_' };
|
||||
|
||||
public ImageModels(string imagePath)
|
||||
public AnimeModel() { }
|
||||
|
||||
public AnimeModel(string imagesPath)
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(imagePath))
|
||||
foreach (var file in Directory.EnumerateFiles(imagesPath))
|
||||
{
|
||||
var info = Path.GetFileNameWithoutExtension(file)
|
||||
.Split(_splits, StringSplitOptions.RemoveEmptyEntries);
|
||||
var id = info[0];
|
||||
Id.Value = info[0];
|
||||
var duration = info.Last();
|
||||
var imageModel = new ImageModel();
|
||||
imageModel.Id.Value = id;
|
||||
imageModel.Image.Value = Utils.LoadImageToMemoryStream(file);
|
||||
imageModel.Duration.Value = int.Parse(duration);
|
||||
Add(imageModel);
|
||||
var imageModel = new ImageModel(
|
||||
Utils.LoadImageToMemoryStream(file),
|
||||
int.Parse(duration)
|
||||
);
|
||||
Images.Add(imageModel);
|
||||
}
|
||||
}
|
||||
|
||||
public AnimeModel Copy()
|
||||
{
|
||||
var model = new AnimeModel();
|
||||
model.Id.Value = Id.Value;
|
||||
model.AnimeType.Value = AnimeType.Value;
|
||||
foreach (var image in Images)
|
||||
model.Images.Add(image);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
Likability.Value = model.Likability.Value;
|
||||
Price.Value = model.Price.Value;
|
||||
Exp.Value = model.Exp.Value;
|
||||
Image.Value = Utils.LoadImageToStream(model.Image.Value);
|
||||
Image.Value = Utils.LoadImageToStream(model.Image.Value.GetSourceFile());
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
|
@ -10,8 +10,21 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class ImageModel
|
||||
{
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public ObservableValue<BitmapImage> Image { get; } = new();
|
||||
|
||||
public ObservableValue<int> Duration { get; } = new(100);
|
||||
|
||||
public ImageModel(BitmapImage image, int duration = 100)
|
||||
{
|
||||
Image.Value = image;
|
||||
Duration.Value = duration;
|
||||
}
|
||||
|
||||
public ImageModel Copy()
|
||||
{
|
||||
var model = new ImageModel(
|
||||
Utils.LoadImageToStream(Image.Value.GetSourceFile()),
|
||||
Duration.Value
|
||||
);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media.Imaging;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet_Simulator.Core;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
@ -74,17 +75,19 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
var petModel = new PetModel(pet);
|
||||
Pets.Add(petModel);
|
||||
// TODO: 动画加载
|
||||
//foreach (var p in pet.path)
|
||||
//{
|
||||
// foreach (var dir in Directory.EnumerateDirectories(p))
|
||||
// {
|
||||
// var animeModel = AnimeModel.Load(dir);
|
||||
// if (animeModel != null)
|
||||
// {
|
||||
// petModel.Animes.TryAdd(animeModel.GraphType.Value, animeModel);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
foreach (var p in pet.path)
|
||||
{
|
||||
foreach (var dir in Directory.EnumerateDirectories(p))
|
||||
{
|
||||
Enum.TryParse<GraphInfo.GraphType>(
|
||||
Path.GetFileName(dir),
|
||||
true,
|
||||
out var animeType
|
||||
);
|
||||
if (animeType is GraphInfo.GraphType.Default)
|
||||
petModel.Animes.Add(new(animeType, dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var lang in loader.I18nDatas)
|
||||
|
@ -25,8 +25,7 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
|
||||
public ObservableCollection<MoveModel> Moves { get; } = new();
|
||||
|
||||
public ObservableValue<AnimeModel> CurrentAnime { get; } = new();
|
||||
public Dictionary<GraphInfo.GraphType, AnimeModel> Animes { get; } = new();
|
||||
public ObservableCollection<AnimeTypeModel> Animes { get; } = new();
|
||||
|
||||
public PetModel()
|
||||
{
|
||||
|
@ -11,10 +11,14 @@ namespace VPet.ModMaker.Models;
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
public const int DecodePixelWidth = 250;
|
||||
public const int DecodePixelHeight = 250;
|
||||
|
||||
public static BitmapImage LoadImageToStream(string imagePath)
|
||||
{
|
||||
BitmapImage bitmapImage = new();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.DecodePixelWidth = DecodePixelWidth;
|
||||
try
|
||||
{
|
||||
bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream;
|
||||
@ -26,15 +30,11 @@ public static class Utils
|
||||
return bitmapImage;
|
||||
}
|
||||
|
||||
public static BitmapImage LoadImageToStream(this BitmapImage image)
|
||||
{
|
||||
return LoadImageToStream(image.GetSourceFile());
|
||||
}
|
||||
|
||||
public static BitmapImage LoadImageToMemoryStream(string imagePath)
|
||||
{
|
||||
BitmapImage bitmapImage = new();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.DecodePixelWidth = DecodePixelWidth;
|
||||
try
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
@ -48,9 +48,4 @@ public static class Utils
|
||||
}
|
||||
return bitmapImage;
|
||||
}
|
||||
|
||||
public static BitmapImage LoadImageToMemoryStream(this BitmapImage image)
|
||||
{
|
||||
return LoadImageToMemoryStream(image.GetSourceFile());
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +136,9 @@
|
||||
<Compile Include="Views\ModEdit\AnimeEdit\AnimeEditWindow.xaml.cs">
|
||||
<DependentUpon>AnimeEditWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\ModEdit\AnimeEdit\AnimePage.xaml.cs">
|
||||
<DependentUpon>AnimePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml.cs">
|
||||
<DependentUpon>ClickTextPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -238,6 +241,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\ModEdit\AnimeEdit\AnimePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -1,24 +1,34 @@
|
||||
using HKW.HKWViewModels.SimpleObservable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimeEditWindowVM
|
||||
{
|
||||
public AnimeModel OldAnime { get; set; }
|
||||
public ObservableValue<AnimeModel> Anime { get; } = new(new());
|
||||
|
||||
public PetModel CurrentPet { get; set; }
|
||||
public AnimeTypeModel OldAnime { get; set; }
|
||||
public ObservableValue<AnimeTypeModel> Anime { get; } = new(new());
|
||||
public ObservableValue<ImageModel> CurrentImageModel { get; } = new();
|
||||
public GameSave.ModeType CurrentMode { get; set; }
|
||||
#region Command
|
||||
public ObservableCommand PlayCommand { get; } = new();
|
||||
public ObservableCommand PauseCommand { get; } = new();
|
||||
|
||||
public ObservableCommand<AnimeModel> AddImageCommand { get; } = new();
|
||||
public ObservableCommand<AnimeModel> ClearImageCommand { get; } = new();
|
||||
public ObservableCommand<AnimeModel> RemoveAnimeCommand { get; } = new();
|
||||
public ObservableCommand<AnimeModel> RemoveImageCommand { get; } = new();
|
||||
#endregion
|
||||
|
||||
public bool _pause = false;
|
||||
@ -26,27 +36,67 @@ public class AnimeEditWindowVM
|
||||
|
||||
public AnimeEditWindowVM()
|
||||
{
|
||||
//foreach (
|
||||
// var file in Directory.EnumerateFiles(
|
||||
// @"C:\Users\HKW\Desktop\TestPicture\0000_core\pet\vup\Default\Happy\1"
|
||||
// )
|
||||
//)
|
||||
//{
|
||||
// Anime.Value.MultiImageModels.Add(new(Utils.LoadImageToMemoryStream(file)));
|
||||
//}
|
||||
_playerTask = new(Play);
|
||||
PlayCommand.ExecuteEvent += PlayCommand_ExecuteEvent;
|
||||
PauseCommand.ExecuteEvent += PauseCommand_ExecuteEvent;
|
||||
//_playerTask = new(Play);
|
||||
//PlayCommand.ExecuteEvent += PlayCommand_ExecuteEvent;
|
||||
//PauseCommand.ExecuteEvent += PauseCommand_ExecuteEvent;
|
||||
AddImageCommand.ExecuteEvent += AddImageCommand_ExecuteEvent;
|
||||
ClearImageCommand.ExecuteEvent += ClearImageCommand_ExecuteEvent;
|
||||
RemoveAnimeCommand.ExecuteEvent += RemoveAnimeCommand_ExecuteEvent;
|
||||
RemoveImageCommand.ExecuteEvent += RemoveImageCommand_ExecuteEvent;
|
||||
}
|
||||
|
||||
private void RemoveImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
value.Images.Remove(CurrentImageModel.Value);
|
||||
}
|
||||
|
||||
private void RemoveAnimeCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.Yes
|
||||
)
|
||||
{
|
||||
if (CurrentMode is GameSave.ModeType.Happy)
|
||||
Anime.Value.HappyAnimes.Remove(value);
|
||||
else if (CurrentMode is GameSave.ModeType.Nomal)
|
||||
Anime.Value.NomalAnimes.Remove(value);
|
||||
else if (CurrentMode is GameSave.ModeType.PoorCondition)
|
||||
Anime.Value.PoorConditionAnimes.Remove(value);
|
||||
else if (CurrentMode is GameSave.ModeType.Ill)
|
||||
Anime.Value.IllAnimes.Remove(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("确定清空吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.Yes
|
||||
)
|
||||
value.Images.Clear();
|
||||
}
|
||||
|
||||
private void AddImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
value.Images.Add(new(Utils.LoadImageToStream(openFileDialog.FileName)));
|
||||
}
|
||||
}
|
||||
|
||||
private void PauseCommand_ExecuteEvent()
|
||||
{
|
||||
_pause = true;
|
||||
//_pause = true;
|
||||
}
|
||||
|
||||
private void PlayCommand_ExecuteEvent()
|
||||
{
|
||||
_playerTask.Start();
|
||||
//_playerTask.Start();
|
||||
}
|
||||
|
||||
private void Play()
|
||||
|
@ -15,95 +15,95 @@ namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimePageVM
|
||||
{
|
||||
//#region Value
|
||||
//public ObservableValue<ObservableCollection<AnimeModel>> ShowAnimes { get; } = new();
|
||||
//public ObservableCollection<AnimeModel> Works => CurrentPet.Value.Works;
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<AnimeTypeModel>> ShowAnimes { get; } = new();
|
||||
public ObservableCollection<AnimeTypeModel> Animes => CurrentPet.Value.Animes;
|
||||
|
||||
//public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
//public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
//public ObservableValue<string> Filter { get; } = new();
|
||||
//#endregion
|
||||
//#region Command
|
||||
//public ObservableCommand AddCommand { get; } = new();
|
||||
//public ObservableCommand<AnimeModel> EditCommand { get; } = new();
|
||||
//public ObservableCommand<AnimeModel> RemoveCommand { get; } = new();
|
||||
//#endregion
|
||||
//public AnimePageVM()
|
||||
//{
|
||||
// ShowAnimes.Value = Works;
|
||||
// CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
// Filter.ValueChanged += Filter_ValueChanged;
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
public ObservableCommand<AnimeTypeModel> EditCommand { get; } = new();
|
||||
public ObservableCommand<AnimeTypeModel> RemoveCommand { get; } = new();
|
||||
#endregion
|
||||
public AnimePageVM()
|
||||
{
|
||||
ShowAnimes.Value = Animes;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
//Filter.ValueChanged += Filter_ValueChanged;
|
||||
|
||||
// AddCommand.ExecuteEvent += Add;
|
||||
// EditCommand.ExecuteEvent += Edit;
|
||||
// RemoveCommand.ExecuteEvent += Remove;
|
||||
//}
|
||||
AddCommand.ExecuteEvent += Add;
|
||||
EditCommand.ExecuteEvent += Edit;
|
||||
RemoveCommand.ExecuteEvent += Remove;
|
||||
}
|
||||
|
||||
//private void CurrentPet_ValueChanged(PetModel oldValue, PetModel newValue)
|
||||
//{
|
||||
// //ShowAnimes.Value = newValue.Animes;
|
||||
//}
|
||||
private void CurrentPet_ValueChanged(PetModel oldValue, PetModel newValue)
|
||||
{
|
||||
ShowAnimes.Value = newValue.Animes;
|
||||
}
|
||||
|
||||
//private void Filter_ValueChanged(string oldValue, string newValue)
|
||||
//{
|
||||
// if (string.IsNullOrWhiteSpace(newValue))
|
||||
// {
|
||||
// ShowAnimes.Value = Works;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ShowAnimes.Value = new(
|
||||
// Works.Where(m => m.Id.Value.Contains(newValue, StringComparison.OrdinalIgnoreCase))
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
private void Filter_ValueChanged(string oldValue, string newValue)
|
||||
{
|
||||
//if (string.IsNullOrWhiteSpace(newValue))
|
||||
//{
|
||||
// ShowAnimes.Value = Animes;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// ShowAnimes.Value = new(
|
||||
// Animes.Where(m => m.Id.Value.Contains(newValue, StringComparison.OrdinalIgnoreCase))
|
||||
// );
|
||||
//}
|
||||
}
|
||||
|
||||
//public void Close() { }
|
||||
public void Close() { }
|
||||
|
||||
//private void Add()
|
||||
//{
|
||||
// var window = new AnimeEditWindow();
|
||||
// var vm = window.ViewModel;
|
||||
// vm.CurrentPet = CurrentPet.Value;
|
||||
// window.ShowDialog();
|
||||
// if (window.IsCancel)
|
||||
// return;
|
||||
// Works.Add(vm.Work.Value);
|
||||
//}
|
||||
private void Add()
|
||||
{
|
||||
var window = new AnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Animes.Add(vm.Anime.Value);
|
||||
}
|
||||
|
||||
//public void Edit(AnimeModel model)
|
||||
//{
|
||||
// var window = new AnimeEditWindow();
|
||||
// var vm = window.ViewModel;
|
||||
// vm.CurrentPet = CurrentPet.Value;
|
||||
// vm.OldWork = model;
|
||||
// var newWork = vm.Work.Value = new(model);
|
||||
// window.ShowDialog();
|
||||
// if (window.IsCancel)
|
||||
// return;
|
||||
// if (ShowAnimes.Value.Count == Works.Count)
|
||||
// {
|
||||
// Works[Works.IndexOf(model)] = newWork;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Works[Works.IndexOf(model)] = newWork;
|
||||
// ShowAnimes.Value[ShowAnimes.Value.IndexOf(model)] = newWork;
|
||||
// }
|
||||
//}
|
||||
public void Edit(AnimeTypeModel model)
|
||||
{
|
||||
var window = new AnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.OldAnime = model;
|
||||
var newAnime = vm.Anime.Value = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
if (ShowAnimes.Value.Count == Animes.Count)
|
||||
{
|
||||
Animes[Animes.IndexOf(model)] = newAnime;
|
||||
}
|
||||
else
|
||||
{
|
||||
Animes[Animes.IndexOf(model)] = newAnime;
|
||||
ShowAnimes.Value[ShowAnimes.Value.IndexOf(model)] = newAnime;
|
||||
}
|
||||
}
|
||||
|
||||
//private void Remove(AnimeModel food)
|
||||
//{
|
||||
// if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
// return;
|
||||
// if (ShowAnimes.Value.Count == Works.Count)
|
||||
// {
|
||||
// Works.Remove(food);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ShowAnimes.Value.Remove(food);
|
||||
// Works.Remove(food);
|
||||
// }
|
||||
//}
|
||||
private void Remove(AnimeTypeModel food)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowAnimes.Value.Count == Animes.Count)
|
||||
{
|
||||
Animes.Remove(food);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowAnimes.Value.Remove(food);
|
||||
Animes.Remove(food);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,114 @@
|
||||
xmlns:pu="https://opensource.panuon.com/wpf-ui"
|
||||
xmlns:vm="clr-namespace:VPet.ModMaker.ViewModels.ModEdit.AnimeEdit"
|
||||
Title="AnimeEditWindow"
|
||||
Width="800"
|
||||
Height="450"
|
||||
Width="1000"
|
||||
Height="600"
|
||||
mc:Ignorable="d">
|
||||
<d:Window.DataContext>
|
||||
<vm:AnimeEditWindowVM />
|
||||
</d:Window.DataContext>
|
||||
<Window.Resources>
|
||||
<Style
|
||||
x:Key="ListBoxItem_Style"
|
||||
BasedOn="{StaticResource {x:Type ListBoxItem}}"
|
||||
TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
<DataTemplate x:Key="Expander_AnimeItem" DataType="ListBoxItem">
|
||||
<Expander
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
d:DataContext=""
|
||||
Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}">
|
||||
<Expander.ContextMenu>
|
||||
<ContextMenu d:DataContext="">
|
||||
<MenuItem
|
||||
Command="{Binding PlacementTarget.Tag.AddImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="添加图片" />
|
||||
<MenuItem
|
||||
Command="{Binding PlacementTarget.Tag.ClearImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="清空图片" />
|
||||
<MenuItem
|
||||
Command="{Binding PlacementTarget.Tag.RemoveAnimeCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="删除此项" />
|
||||
</ContextMenu>
|
||||
</Expander.ContextMenu>
|
||||
<Expander.Header>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox pu:TextBoxHelper.Watermark="动画Id" Text="{Binding Id.Value}" />
|
||||
<TextBlock Grid.Column="1" Margin="10,0,0,0">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}({0})">
|
||||
<Binding Path="Images.Count" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
<ListBox
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
AllowDrop="True"
|
||||
Drop="ListBox_Drop"
|
||||
ItemsSource="{Binding Images, IsAsync=True}"
|
||||
PreviewMouseMove="ListBox_PreviewMouseMove"
|
||||
PreviewMouseWheel="ListBox_PreviewMouseWheel"
|
||||
SelectedItem="{Binding DataContext.CurrentImageModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Expander, Mode=FindAncestor}}" Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem
|
||||
Command="{Binding PlacementTarget.Tag.RemoveImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="删除图片" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="150"
|
||||
Height="150"
|
||||
d:DataContext=""
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
|
||||
Source="{Binding Image.Value, IsAsync=True}">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Image.Value, IsAsync=True}" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="持续时间(ms)" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration.Value, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Expander>
|
||||
</DataTemplate>
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@ -26,10 +128,11 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Anime.Value.CurrentImageModel.Value.Image.Value}" />
|
||||
<Image Width="250" Height="250">
|
||||
<Image.ToolTip>
|
||||
<Image Width="500" Height="500" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
@ -52,10 +155,14 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="{ll:Str 动画Id}" />
|
||||
<TextBox Grid.Column="1" />
|
||||
<!--<Label Content="{ll:Str 动画Id}" />
|
||||
<TextBox Grid.Column="1" />-->
|
||||
<Label Grid.Row="1" Content="{ll:Str 动画类型}" />
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
IsEnabled="True"
|
||||
Text="{Binding Anime.Value.GraphType.Value}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
@ -63,62 +170,84 @@
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox
|
||||
x:Name="ListBox_Images"
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
d:SelectedIndex="0"
|
||||
ItemsSource="{Binding Anime.Value.ImageModels}"
|
||||
SelectedItem="{Binding Anime.Value.CurrentImageModel.Value}">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid Width="150" Height="200">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="150"
|
||||
Height="150"
|
||||
Source="{Binding Image.Value}">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Image.Value}" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="持续时间" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Duration.Value}" />
|
||||
</Grid>
|
||||
<TextBox Grid.Row="2" Text="ImageName" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<TabControl SelectionChanged="TabControl_SelectionChanged">
|
||||
<TabItem Tag="{Binding Anime.Value.ModeTypes[0]}">
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="Anime.Value.HappyAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.HappyAnimes, IsAsync=True}" />
|
||||
</TabItem>
|
||||
<TabItem d:Header="Nomal (0)" Tag="Nomal">
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="Anime.Value.NomalAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.NomalAnimes, IsAsync=True}" />
|
||||
</TabItem>
|
||||
<TabItem d:Header="PoorCondition (0)" Tag="PoorCondition">
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="Anime.Value.PoorConditionAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.PoorConditionAnimes, IsAsync=True}" />
|
||||
</TabItem>
|
||||
<TabItem d:Header="Ill (0)" Tag="Ill">
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="Anime.Value.IllAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.IllAnimes, IsAsync=True}" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button
|
||||
x:Name="Button_AddAnime"
|
||||
Margin="10"
|
||||
Click="Button_AddAnime_Click"
|
||||
Content="{ll:Str 添加动画}" />
|
||||
<Button
|
||||
x:Name="Button_Cancel"
|
||||
Grid.Column="1"
|
||||
Margin="10"
|
||||
Click="Button_Cancel_Click"
|
||||
Content="{ll:Str 取消}" />
|
||||
<Button
|
||||
x:Name="Button_Yes"
|
||||
Grid.Column="1"
|
||||
Grid.Column="2"
|
||||
Margin="10"
|
||||
Click="Button_Yes_Click"
|
||||
Content="{ll:Str 确定}" />
|
||||
|
@ -11,7 +11,9 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
namespace VPet.ModMaker.Views.ModEdit.AnimeEdit;
|
||||
|
||||
@ -22,8 +24,8 @@ public partial class AnimeEditWindow : Window
|
||||
{
|
||||
public AnimeEditWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = new AnimeEditWindowVM();
|
||||
InitializeComponent();
|
||||
Closed += (s, e) =>
|
||||
{
|
||||
try
|
||||
@ -71,4 +73,126 @@ public partial class AnimeEditWindow : Window
|
||||
IsCancel = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
//private void ListBox_Drop(object sender, DragEventArgs e)
|
||||
//{
|
||||
// var fileName = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
|
||||
//}
|
||||
|
||||
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (
|
||||
sender is not TabControl tabControl
|
||||
|| tabControl.SelectedItem is not TabItem item
|
||||
|| item.Tag is not string str
|
||||
)
|
||||
return;
|
||||
if (Enum.TryParse<GameSave.ModeType>(str, true, out var mode))
|
||||
ViewModel.CurrentMode = mode;
|
||||
}
|
||||
|
||||
private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
|
||||
{
|
||||
RoutedEvent = MouseWheelEvent,
|
||||
Source = sender
|
||||
};
|
||||
var parent = ((Control)sender).Parent as UIElement;
|
||||
parent.RaiseEvent(eventArg);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private object _dropSender;
|
||||
|
||||
private void ListBox_PreviewMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
if (e.LeftButton != MouseButtonState.Pressed)
|
||||
return;
|
||||
var pos = e.GetPosition(listBox);
|
||||
HitTestResult result = VisualTreeHelper.HitTest(listBox, pos);
|
||||
if (result is null)
|
||||
return;
|
||||
var listBoxItem = FindVisualParent<ListBoxItem>(result.VisualHit);
|
||||
if (listBoxItem == null || listBoxItem.Content != listBox.SelectedItem)
|
||||
return;
|
||||
var dataObj = new DataObject(listBoxItem.Content);
|
||||
DragDrop.DoDragDrop(listBox, dataObj, DragDropEffects.Move);
|
||||
_dropSender = sender;
|
||||
}
|
||||
|
||||
private void ListBox_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (sender.Equals(_dropSender) is false)
|
||||
{
|
||||
MessageBox.Show("无法移动不同动画的图片");
|
||||
return;
|
||||
}
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
var pos = e.GetPosition(listBox);
|
||||
var result = VisualTreeHelper.HitTest(listBox, pos);
|
||||
if (result == null)
|
||||
return;
|
||||
//查找元数据
|
||||
if (e.Data.GetData(typeof(ImageModel)) is not ImageModel sourcePerson)
|
||||
return;
|
||||
//查找目标数据
|
||||
var listBoxItem = FindVisualParent<ListBoxItem>(result.VisualHit);
|
||||
if (listBoxItem == null)
|
||||
return;
|
||||
var targetPerson = listBoxItem.Content as ImageModel;
|
||||
if (ReferenceEquals(targetPerson, sourcePerson))
|
||||
return;
|
||||
if (listBox.ItemsSource is not IList<ImageModel> list)
|
||||
return;
|
||||
var sourceIndex = list.IndexOf(sourcePerson);
|
||||
var targetIndex = list.IndexOf(targetPerson);
|
||||
var temp = list[sourceIndex];
|
||||
list[sourceIndex] = list[targetIndex];
|
||||
list[targetIndex] = temp;
|
||||
}
|
||||
|
||||
public static T? FindVisualChild<T>(DependencyObject obj)
|
||||
where T : DependencyObject
|
||||
{
|
||||
if (obj is null)
|
||||
return null;
|
||||
var count = VisualTreeHelper.GetChildrenCount(obj);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(obj, i);
|
||||
if (child is T t)
|
||||
return t;
|
||||
if (FindVisualChild<T>(child) is T childItem)
|
||||
return childItem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static T FindVisualParent<T>(DependencyObject obj)
|
||||
where T : class
|
||||
{
|
||||
while (obj != null)
|
||||
{
|
||||
if (obj is T)
|
||||
return obj as T;
|
||||
obj = VisualTreeHelper.GetParent(obj);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void Button_AddAnime_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ViewModel.CurrentMode is GameSave.ModeType.Happy)
|
||||
ViewModel.Anime.Value.HappyAnimes.Add(new());
|
||||
else if (ViewModel.CurrentMode is GameSave.ModeType.Nomal)
|
||||
ViewModel.Anime.Value.NomalAnimes.Add(new());
|
||||
else if (ViewModel.CurrentMode is GameSave.ModeType.PoorCondition)
|
||||
ViewModel.Anime.Value.PoorConditionAnimes.Add(new());
|
||||
else if (ViewModel.CurrentMode is GameSave.ModeType.Ill)
|
||||
ViewModel.Anime.Value.IllAnimes.Add(new());
|
||||
}
|
||||
}
|
||||
|
114
VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml
Normal file
114
VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml
Normal file
@ -0,0 +1,114 @@
|
||||
<Page
|
||||
x:Class="VPet.ModMaker.Views.ModEdit.AnimeEdit.AnimePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF"
|
||||
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="AnimePage"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d">
|
||||
<d:Page.DataContext>
|
||||
<vm:AnimePageVM />
|
||||
</d:Page.DataContext>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!--<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}" Text="{Binding Filter.Value, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox.Style>
|
||||
<Style BasedOn="{StaticResource {x:Type TextBox}}" TargetType="TextBox">
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectedItem, ElementName=ComboBox_Pet}" Value="{x:Null}">
|
||||
<Setter Property="IsEnabled" Value="False" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBox.Style>
|
||||
</TextBox>-->
|
||||
<ComboBox
|
||||
x:Name="ComboBox_Pet"
|
||||
Grid.Column="1"
|
||||
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
||||
DisplayMemberPath="Id.Value"
|
||||
ItemsSource="{Binding Pets}"
|
||||
SelectedItem="{Binding CurrentPet.Value}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="ComboBoxItem">
|
||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
||||
</Style>
|
||||
</ComboBox.ItemContainerStyle>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectedItem, ElementName=ComboBox_Pet}" Value="{x:Null}">
|
||||
<Setter Property="IsEnabled" Value="False" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<DataGrid
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
pu:DataGridHelper.ColumnHeaderHorizontalContentAlignment="Center"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowAnimes.Value}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="64"
|
||||
VirtualizingStackPanel.IsVirtualizing="True"
|
||||
VirtualizingStackPanel.VirtualizationMode="Recycling">
|
||||
<DataGrid.RowStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type DataGridRow}}" TargetType="DataGridRow">
|
||||
<Setter Property="Height" Value="64" />
|
||||
<Setter Property="Tag" Value="{Binding}" />
|
||||
<Setter Property="ContextMenu" Value="{StaticResource ContextMenu_DataGridRow}" />
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding GraphType.Value}"
|
||||
CanUserSort="True"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="GraphType.Value">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{ll:Str 动画类型}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<!--<DataGridTextColumn
|
||||
Binding="{Binding LocateType.EnumValue.Value}"
|
||||
CanUserSort="True"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="LocateType.EnumValue.Value">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{ll:Str 动画支持的状态}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>-->
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Command="{Binding AddCommand}"
|
||||
Content="➕"
|
||||
Style="{StaticResource AddButton}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
39
VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml.cs
Normal file
39
VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
namespace VPet.ModMaker.Views.ModEdit.AnimeEdit;
|
||||
|
||||
/// <summary>
|
||||
/// AnimePage.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class AnimePage : Page
|
||||
{
|
||||
public AnimePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = new AnimePageVM();
|
||||
}
|
||||
|
||||
public AnimePageVM ViewModel => (AnimePageVM)DataContext;
|
||||
|
||||
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not AnimeTypeModel model)
|
||||
return;
|
||||
ViewModel.Edit(model);
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@
|
||||
Height="64"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Source="{Binding Image.Value}"
|
||||
Source="{Binding Image.Value, IsAsync=True}"
|
||||
Stretch="Uniform">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
@ -70,7 +70,7 @@
|
||||
Height="256"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Source="{Binding Image.Value}"
|
||||
Source="{Binding Image.Value, IsAsync=True}"
|
||||
Stretch="Uniform" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
|
@ -212,6 +212,15 @@
|
||||
</TabItem.Header>
|
||||
<Frame Content="{Binding ModEditWindow.MovePage}" />
|
||||
</TabItem>
|
||||
<TabItem Tag="{ll:Str 动画}">
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="ModEditWindow.MovePage.ViewModel.CurrentPet.Value.Animes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<Frame Content="{Binding ModEditWindow.AnimePage}" />
|
||||
</TabItem>
|
||||
<!--<TabItem Header="物品 (0)" Tag="{ll:Str 物品}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -17,6 +17,7 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using VPet.ModMaker.ViewModels.ModEdit;
|
||||
using VPet.ModMaker.Views.ModEdit.AnimeEdit;
|
||||
using VPet.ModMaker.Views.ModEdit.ClickTextEdit;
|
||||
using VPet.ModMaker.Views.ModEdit.FoodEdit;
|
||||
using VPet.ModMaker.Views.ModEdit.LowTextEdit;
|
||||
@ -40,8 +41,8 @@ public partial class ModEditWindow : Window
|
||||
public SelectTextPage SelectTextPage { get; } = new();
|
||||
public PetPage PetPage { get; } = new();
|
||||
public WorkPage WorkPage { get; } = new();
|
||||
|
||||
public MovePage MovePage { get; } = new();
|
||||
public AnimePage AnimePage { get; } = new();
|
||||
|
||||
public ModEditWindow()
|
||||
{
|
||||
@ -63,6 +64,7 @@ public partial class ModEditWindow : Window
|
||||
PetPage.DataContext = null;
|
||||
WorkPage.DataContext = null;
|
||||
MovePage.DataContext = null;
|
||||
AnimePage.DataContext = null;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user