实装 MoveEdit

This commit is contained in:
Hakoyu 2023-09-11 22:29:17 +08:00
parent 4670adf30b
commit 164a129e6a
20 changed files with 887 additions and 42 deletions

View File

@ -0,0 +1,56 @@
using HKW.HKWViewModels.SimpleObservable;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VPet.ModMaker.Models;
public class EnumFlagsVM<T>
where T : Enum
{
public ObservableValue<T> EnumValue { get; } = new();
public ObservableCommand<T> AddCommand { get; } = new();
public ObservableCommand<T> RemoveCommand { get; } = new();
public Type EnumType = typeof(T);
public Type UnderlyingType { get; } = Enum.GetUnderlyingType(typeof(T));
public EnumFlagsVM()
{
AddCommand.ExecuteEvent += AddCommand_ExecuteEvent;
RemoveCommand.ExecuteEvent += RemoveCommand_ExecuteEvent;
}
public EnumFlagsVM(T value)
: this()
{
EnumValue.Value = value;
}
private void AddCommand_ExecuteEvent(T value)
{
if (UnderlyingType == typeof(int))
{
EnumValue.Value = (T)
Enum.Parse(
EnumType,
(Convert.ToInt32(EnumValue.Value) | Convert.ToInt32(value)).ToString()
);
}
}
private void RemoveCommand_ExecuteEvent(T value)
{
if (UnderlyingType == typeof(int))
{
EnumValue.Value = (T)
Enum.Parse(
EnumType,
(Convert.ToInt32(EnumValue.Value) & ~Convert.ToInt32(value)).ToString()
);
}
}
}

View File

@ -176,10 +176,13 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
}
);
}
var imagePath = Image.Value.GetSourceFile();
var targetImagePath = Path.Combine(path, Path.GetFileName(imagePath));
if (imagePath != targetImagePath)
File.Copy(imagePath, targetImagePath, true);
if (Image.Value is not null)
{
var imagePath = Image.Value.GetSourceFile();
var targetImagePath = Path.Combine(path, Path.GetFileName(imagePath));
if (imagePath != targetImagePath)
File.Copy(imagePath, targetImagePath, true);
}
File.WriteAllText(modInfoFile, lps.ToString());
SavePets(path);
SaveFoods(path);
@ -206,10 +209,19 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
var lps = new LPS();
GetPetInfo(lps, pet);
GetWorksInfo(lps, pet);
GetMoveInfo(lps, pet);
File.WriteAllText(petFile, lps.ToString());
}
}
void GetMoveInfo(LPS lps, PetModel pet)
{
foreach (var move in pet.Moves)
{
lps.Add(LPSConvert.SerializeObjectToLine<Line>(move.ToMove(), "move"));
}
}
void GetWorksInfo(LPS lps, PetModel pet)
{
foreach (var work in pet.Works)

View File

@ -7,7 +7,7 @@ using System.Text;
using System.Threading.Tasks;
using VPet_Simulator.Core;
namespace VPet.ModMaker.Models.ModModel;
namespace VPet.ModMaker.Models;
public class MoveModel
{
@ -24,28 +24,32 @@ public class MoveModel
public ObservableValue<string> Graph { get; } = new();
public ObservableValue<int> Distance { get; } = new(5);
public ObservableValue<int> Interval { get; } = new(125);
public ObservableValue<int> LocateLength { get; } = new();
public ObservableValue<int> SpeedX { get; } = new();
public ObservableValue<int> SpeedY { get; } = new();
public ObservableValue<int> CheckLeft { get; } = new(100);
public ObservableValue<int> CheckRight { get; } = new(100);
public ObservableValue<int> CheckTop { get; } = new(100);
public ObservableValue<int> CheckBottom { get; } = new(100);
public ObservableValue<int> SpeedX { get; } = new();
public ObservableValue<int> SpeedY { get; } = new();
public ObservableValue<int> LocateLength { get; } = new();
public ObservableValue<int> TriggerLeft { get; } = new(100);
public ObservableValue<int> TriggerRight { get; } = new(100);
public ObservableValue<int> TriggerTop { get; } = new(100);
public ObservableValue<int> TriggerBottom { get; } = new(100);
public ObservableValue<GraphHelper.Move.DirectionType> DirectionType { get; } = new();
public EnumFlagsVM<GraphHelper.Move.DirectionType> LocateType { get; } =
new(GraphHelper.Move.DirectionType.None);
public EnumFlagsVM<GraphHelper.Move.DirectionType> TriggerType { get; } =
new(GraphHelper.Move.DirectionType.None);
public ObservableValue<GraphHelper.Move.ModeType> ModeType { get; } = new();
public EnumFlagsVM<GraphHelper.Move.ModeType> ModeType { get; } =
new(GraphHelper.Move.ModeType.Nomal);
public MoveModel() { }
public MoveModel(MoveModel model)
: this()
{
//Id.Value = model.Id.Value;
//Id.EnumValue = model.Id.EnumValue;
Graph.Value = model.Graph.Value;
Distance.Value = model.Distance.Value;
Interval.Value = model.Interval.Value;
@ -60,14 +64,15 @@ public class MoveModel
TriggerRight.Value = model.TriggerRight.Value;
TriggerTop.Value = model.TriggerTop.Value;
TriggerBottom.Value = model.TriggerBottom.Value;
DirectionType.Value = model.DirectionType.Value;
ModeType.Value = model.ModeType.Value;
LocateType.EnumValue.Value = model.LocateType.EnumValue.Value;
TriggerType.EnumValue.Value = model.TriggerType.EnumValue.Value;
ModeType.EnumValue.Value = model.ModeType.EnumValue.Value;
}
public MoveModel(GraphHelper.Move move)
: this()
{
//Id.Value = move.Id.Value;
//Id.EnumValue = move.Id.EnumValue;
Graph.Value = move.Graph;
Distance.Value = move.Distance;
Interval.Value = move.Interval;
@ -82,8 +87,9 @@ public class MoveModel
TriggerRight.Value = move.TriggerRight;
TriggerTop.Value = move.TriggerTop;
TriggerBottom.Value = move.TriggerBottom;
DirectionType.Value = move.TriggerType;
ModeType.Value = move.Mode;
LocateType.EnumValue.Value = move.LocateType;
TriggerType.EnumValue.Value = move.TriggerType;
ModeType.EnumValue.Value = move.Mode;
}
public GraphHelper.Move ToMove()
@ -104,8 +110,9 @@ public class MoveModel
TriggerRight = TriggerRight.Value,
TriggerTop = TriggerTop.Value,
TriggerBottom = TriggerBottom.Value,
TriggerType = DirectionType.Value,
Mode = ModeType.Value,
LocateType = LocateType.EnumValue.Value,
TriggerType = TriggerType.EnumValue.Value,
Mode = ModeType.EnumValue.Value,
};
}
}

View File

@ -22,6 +22,8 @@ public class PetModel : I18nModel<I18nPetInfoModel>
public ObservableCollection<WorkModel> Works { get; } = new();
public ObservableCollection<MoveModel> Moves { get; } = new();
public PetModel()
{
PetNameId.Value = $"{Id.Value}_{nameof(PetNameId)}";
@ -106,6 +108,8 @@ public class PetModel : I18nModel<I18nPetInfoModel>
foreach (var work in loader.Config.Works)
Works.Add(new(work));
foreach (var move in loader.Config.Moves)
Moves.Add(new(move));
}
public void Close() { }

View File

@ -59,9 +59,9 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
Mode.Value = model.Mode.Value;
Tags.Value = model.Tags.Value;
ToTags.Value = model.ToTags.Value;
//Working.Value = model.Working.Value;
//WorkingState.Value = model.WorkingState.Value;
//DayTime.Value = model.DayTime.Value;
//Working.EnumValue = model.Working.EnumValue;
//WorkingState.EnumValue = model.WorkingState.EnumValue;
//DayTime.EnumValue = model.DayTime.EnumValue;
Like = model.Like.Copy();
Health = model.Health.Copy();
Level = model.Level.Copy();
@ -84,9 +84,9 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
Mode.Value = text.Mode;
Tags.Value = text.Tags is null ? string.Empty : string.Join(", ", text.Tags);
ToTags.Value = text.ToTags is null ? string.Empty : string.Join(", ", text.ToTags);
//Working.Value = text.Working;
//WorkingState.Value = text.State;
//DayTime.Value = text.DaiTime;
//Working.EnumValue = text.Working;
//WorkingState.EnumValue = text.State;
//DayTime.EnumValue = text.DaiTime;
Like.SetValue(text.LikeMin, text.LikeMax);
Health.SetValue(text.HealthMin, text.HealthMax);
Level.SetValue(text.LevelMin, text.LevelMax);
@ -108,9 +108,9 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
Mode = Mode.Value,
Tags = new(Tags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
ToTags = new(ToTags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
//Working = Working.Value,
//State = WorkingState.Value,
//DaiTime = DayTime.Value,
//Working = Working.EnumValue,
//State = WorkingState.EnumValue,
//DaiTime = DayTime.EnumValue,
LikeMax = Like.Max.Value,
LikeMin = Like.Min.Value,
HealthMin = Health.Min.Value,

View File

@ -13,7 +13,7 @@ namespace HKW.HKWViewModels.SimpleObservable;
/// 可观察命令
/// </summary>
[DebuggerDisplay(
"CanExecute = {CanExecuteProperty.Value}, EventCount = {ExecuteEvent.GetInvocationList().Length}, AsyncEventCount = {AsyncExecuteEvent.GetInvocationList().Length}"
"CanExecute = {CanExecuteProperty.EnumValue}, EventCount = {ExecuteEvent.GetInvocationList().Length}, AsyncEventCount = {AsyncExecuteEvent.GetInvocationList().Length}"
)]
public class ObservableCommand : ICommand
{
@ -95,8 +95,8 @@ public class ObservableCommand : ICommand
/// {
/// canExecute = false; // trigger this
/// };
/// value.Value = "A"; // execute this
/// // result: value.Value == "A" , command.CanExecuteProperty == false
/// value.EnumValue = "A"; // execute this
/// // result: value.EnumValue == "A" , command.CanExecuteProperty == false
/// ]]>
/// </code></para>
/// </summary>

View File

@ -14,7 +14,7 @@ namespace HKW.HKWViewModels.SimpleObservable;
/// </summary>
/// <typeparam name="T">参数类型</typeparam>
[DebuggerDisplay(
"CanExecute = {CanExecuteProperty.Value}, EventCount = {ExecuteEvent.GetInvocationList().Length}, AsyncEventCount = {AsyncExecuteEvent.GetInvocationList().Length}"
"CanExecute = {CanExecuteProperty.EnumValue}, EventCount = {ExecuteEvent.GetInvocationList().Length}, AsyncEventCount = {AsyncExecuteEvent.GetInvocationList().Length}"
)]
public class ObservableCommand<T> : ICommand
where T : notnull

View File

@ -12,7 +12,7 @@ namespace HKW.HKWViewModels.SimpleObservable;
/// 可观察值
/// </summary>
/// <typeparam name="T"></typeparam>
[DebuggerDisplay("{Value}")]
[DebuggerDisplay("{EnumValue}")]
public class ObservableValue<T> : INotifyPropertyChanging, INotifyPropertyChanged
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
@ -93,8 +93,8 @@ public class ObservableValue<T> : INotifyPropertyChanging, INotifyPropertyChange
/// {
/// v = "B"; // trigger this
/// };
/// value1.Value = "A"; // execute this
/// // result: value1.Value == "A" , value2.Value == "B"
/// value1.EnumValue = "A"; // execute this
/// // result: value1.EnumValue == "A" , value2.EnumValue == "B"
/// ]]>
/// </code></para>
/// </summary>

View File

@ -97,6 +97,7 @@
<Compile Include="Converters\RatioMarginConverter.cs" />
<Compile Include="Converters\MaxConverter.cs" />
<Compile Include="Converters\MarginConverter.cs" />
<Compile Include="Models\EnumFlagsVM.cs" />
<Compile Include="Models\ModModel\ClickTextModel.cs" />
<Compile Include="Models\Expansions.cs" />
<Compile Include="Models\ModModel\FoodModel.cs" />
@ -120,6 +121,8 @@
<Compile Include="ViewModels\ModEdit\LowTextEdit\LowTextEditWindowVM.cs" />
<Compile Include="ViewModels\ModEdit\LowTextEdit\LowTextPageVM.cs" />
<Compile Include="ViewModels\ModEdit\ModEditWindowVM.cs" />
<Compile Include="ViewModels\ModEdit\MoveEdit\MoveEditWindowVM.cs" />
<Compile Include="ViewModels\ModEdit\MoveEdit\MovePageVM.cs" />
<Compile Include="ViewModels\ModEdit\PetEdit\PetEditWindowVM.cs" />
<Compile Include="ViewModels\ModEdit\PetEdit\PetPageVM.cs" />
<Compile Include="ViewModels\ModEdit\SelectTextEdit\SelectTextEditWindowVM.cs" />
@ -169,6 +172,12 @@
<DependentUpon>ModEditWindow.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModels\ModMakerWindowVM.cs" />
<Compile Include="Views\ModEdit\MoveEdit\MoveEditWindow.xaml.cs">
<DependentUpon>MoveEditWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModEdit\MoveEdit\MovePage.xaml.cs">
<DependentUpon>MovePage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModEdit\PetEdit\PetEditWindow.xaml.cs">
<DependentUpon>PetEditWindow.xaml</DependentUpon>
</Compile>
@ -250,6 +259,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModEdit\MoveEdit\MoveEditWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModEdit\MoveEdit\MovePage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModEdit\PetEdit\PetEditWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -0,0 +1,73 @@
using HKW.HKWViewModels.SimpleObservable;
using LinePutScript.Localization.WPF;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using VPet.ModMaker.Models;
namespace VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
public class MoveEditWindowVM
{
#region Value
public PetModel CurrentPet { get; set; }
public MoveModel OldMove { get; set; }
public ObservableValue<MoveModel> Move { get; } = new(new());
#endregion
public ObservableValue<double> BorderLength { get; } = new(250);
public ObservableValue<double> LengthRatio { get; } = new(250.0 / 500.0);
public ObservableValue<BitmapImage> Image { get; } = new();
#region Command
public ObservableCommand AddImageCommand { get; } = new();
public ObservableCommand ChangeImageCommand { get; } = new();
#endregion
public MoveEditWindowVM()
{
AddImageCommand.ExecuteEvent += AddImage;
ChangeImageCommand.ExecuteEvent += ChangeImage;
Image.ValueChanged += Image_ValueChanged;
}
private void Image_ValueChanged(BitmapImage oldValue, BitmapImage newValue)
{
//LengthRatio.EnumValue = BorderLength.EnumValue / value.PixelWidth;
}
public void Close()
{
Image.Value?.StreamSource?.Close();
}
private void AddImage()
{
OpenFileDialog openFileDialog =
new()
{
Title = "选择图片".Translate(),
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
};
if (openFileDialog.ShowDialog() is true)
{
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
}
}
private void ChangeImage()
{
OpenFileDialog openFileDialog =
new()
{
Title = "选择图片".Translate(),
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
};
if (openFileDialog.ShowDialog() is true)
{
Image.Value?.StreamSource?.Close();
Image.Value = Utils.LoadImageToStream(openFileDialog.FileName);
}
}
}

View File

@ -0,0 +1,108 @@
using HKW.HKWViewModels.SimpleObservable;
using LinePutScript.Localization.WPF;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VPet.ModMaker.Models;
using VPet.ModMaker.Views.ModEdit.MoveEdit;
namespace VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
public class MovePageVM
{
#region Value
public ObservableValue<ObservableCollection<MoveModel>> ShowMoves { get; } = new();
public ObservableCollection<MoveModel> Moves => CurrentPet.Value.Moves;
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<MoveModel> EditCommand { get; } = new();
public ObservableCommand<MoveModel> RemoveCommand { get; } = new();
#endregion
public MovePageVM()
{
ShowMoves.Value = Moves;
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
Filter.ValueChanged += Filter_ValueChanged;
AddCommand.ExecuteEvent += Add;
EditCommand.ExecuteEvent += Edit;
RemoveCommand.ExecuteEvent += Remove;
}
private void CurrentPet_ValueChanged(PetModel oldValue, PetModel newValue)
{
ShowMoves.Value = newValue.Moves;
}
private void Filter_ValueChanged(string oldValue, string newValue)
{
//if (string.IsNullOrWhiteSpace(newValue))
//{
// ShowMoves.EnumValue = Moves;
//}
//else
//{
// ShowMoves.EnumValue = new(
// Moves.Where(m => m.Id.EnumValue.Contains(newValue, StringComparison.OrdinalIgnoreCase))
// );
//}
}
public void Close() { }
private void Add()
{
var window = new MoveEditWindow();
var vm = window.ViewModel;
vm.CurrentPet = CurrentPet.Value;
window.ShowDialog();
if (window.IsCancel)
return;
Moves.Add(vm.Move.Value);
}
public void Edit(MoveModel model)
{
var window = new MoveEditWindow();
var vm = window.ViewModel;
vm.CurrentPet = CurrentPet.Value;
vm.OldMove = model;
var newMove = vm.Move.Value = new(model);
window.ShowDialog();
if (window.IsCancel)
return;
if (ShowMoves.Value.Count == Moves.Count)
{
Moves[Moves.IndexOf(model)] = newMove;
}
else
{
Moves[Moves.IndexOf(model)] = newMove;
ShowMoves.Value[ShowMoves.Value.IndexOf(model)] = newMove;
}
}
private void Remove(MoveModel food)
{
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
return;
if (ShowMoves.Value.Count == Moves.Count)
{
Moves.Remove(food);
}
else
{
ShowMoves.Value.Remove(food);
Moves.Remove(food);
}
}
}

View File

@ -33,7 +33,7 @@ public class PetEditWindowVM
private void Image_ValueChanged(BitmapImage oldValue, BitmapImage newValue)
{
//LengthRatio.Value = BorderLength.Value / value.PixelWidth;
//LengthRatio.EnumValue = BorderLength.EnumValue / value.PixelWidth;
}
public void Close()

View File

@ -34,7 +34,7 @@ public class WorkEditWindowVM
private void Image_ValueChanged(BitmapImage oldValue, BitmapImage newValue)
{
//LengthRatio.Value = BorderLength.Value / value.PixelWidth;
//LengthRatio.EnumValue = BorderLength.EnumValue / value.PixelWidth;
}
public void Close()

View File

@ -97,6 +97,7 @@
Grid.Row="4"
Grid.Column="1"
pu:TextBoxHelper.Watermark="{ll:Str 食物描述}"
Style="{StaticResource TextBox_Wrap}"
Text="{Binding Food.Value.CurrentI18nData.Value.Description.Value, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</ScrollViewer>

View File

@ -98,14 +98,14 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="{ll:Str 模组名称}" />
<Label Content="{ll:Str 模组Id}" />
<TextBox
x:Name="TextBox_ModName"
Grid.Column="1"
pu:TextBoxHelper.Watermark="{ll:Str 模组名称}"
Text="{Binding ModInfo.Value.CurrentI18nData.Value.Name.Value}" />
pu:TextBoxHelper.Watermark="{ll:Str 模组Id}"
Text="{Binding ModInfo.Value.Id.Value}" />
<Label Grid.Row="1" Content="{ll:Str 作者}" />
<TextBox
x:Name="TextBox_Author"
@ -127,10 +127,16 @@
Grid.Column="1"
pu:TextBoxHelper.Watermark="{ll:Str 模组版本}"
Text="{Binding ModInfo.Value.ModVersion.Value}" />
<Label Grid.Row="4" Content="{ll:Str 模组介绍}" />
<Label Grid.Row="4" Content="{ll:Str 模组名称}" />
<TextBox
Grid.Row="4"
Grid.Column="1"
pu:TextBoxHelper.Watermark="{ll:Str 模组名称}"
Text="{Binding ModInfo.Value.CurrentI18nData.Value.Name.Value}" />
<Label Grid.Row="5" Content="{ll:Str 模组介绍}" />
<TextBox
x:Name="TextBox_Description"
Grid.Row="4"
Grid.Row="5"
Grid.Column="1"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"
@ -197,6 +203,15 @@
</TabItem.Header>
<Frame Content="{Binding ModEditWindow.WorkPage}" />
</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.Moves.Count" />
</MultiBinding>
</TabItem.Header>
<Frame Content="{Binding ModEditWindow.MovePage}" />
</TabItem>
<!--<TabItem Header="物品 (0)" Tag="{ll:Str 物品}">
<Grid>
<Grid.RowDefinitions>

View File

@ -20,6 +20,7 @@ using VPet.ModMaker.ViewModels.ModEdit;
using VPet.ModMaker.Views.ModEdit.ClickTextEdit;
using VPet.ModMaker.Views.ModEdit.FoodEdit;
using VPet.ModMaker.Views.ModEdit.LowTextEdit;
using VPet.ModMaker.Views.ModEdit.MoveEdit;
using VPet.ModMaker.Views.ModEdit.PetEdit;
using VPet.ModMaker.Views.ModEdit.SelectTextEdit;
using VPet.ModMaker.Views.ModEdit.WorkEdit;
@ -40,6 +41,8 @@ public partial class ModEditWindow : Window
public PetPage PetPage { get; } = new();
public WorkPage WorkPage { get; } = new();
public MovePage MovePage { get; } = new();
public ModEditWindow()
{
InitializeComponent();

View File

@ -0,0 +1,293 @@
<Window
x:Class="VPet.ModMaker.Views.ModEdit.MoveEdit.MoveEditWindow"
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.MoveEdit"
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.MoveEdit"
Title="MoveEditWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<d:Window.DataContext>
<vm:MoveEditWindowVM />
</d:Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Image
Width="250"
Height="250"
Source="{Binding Image.Value}"
Stretch="Uniform">
<Image.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding ChangeImageCommand}" Header="{ll:Str 修改测试图片}" />
</ContextMenu>
</Image.ContextMenu>
</Image>
<Button
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="{Binding AddImageCommand}"
Content="{ll:Str 添加测试图片}">
<Button.Style>
<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="Button">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding Image.Value}" Value="{x:Null}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="3" Content="{ll:Str 指定动画}" />
<TextBox
Grid.Row="3"
Grid.Column="1"
Text="{Binding Move.Value.Graph.Value}" />
<!--<Label Grid.Row="3" Content="{ll:Str 宠物描述}" />
<TextBox
Grid.Row="3"
Grid.Column="1"
Text="{Binding Pet.Value.CurrentI18nData.Value.Description.Value}" />-->
</Grid>
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Content="{ll:Str 定位类型}" />
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Move.Value.LocateType.EnumValue.Value}" />
<ComboBox
x:Name="ComboBox_LocateType"
Grid.Column="1"
ItemsSource="{Binding Move.Value.DirectionTypes}"
SelectedIndex="0" />
<Button
Grid.Column="2"
Command="{Binding Move.Value.LocateType.AddCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_LocateType}"
Content="+" />
<Button
Grid.Column="3"
Command="{Binding Move.Value.LocateType.RemoveCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_LocateType}"
Content="-" />
</Grid>
<Label Grid.Row="1" Content="{ll:Str 触发类型}" />
<Grid Grid.Row="1" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Move.Value.TriggerType.EnumValue.Value}" />
<ComboBox
x:Name="ComboBox_TriggerType"
Grid.Column="1"
ItemsSource="{Binding Move.Value.DirectionTypes}"
SelectedIndex="0" />
<Button
Grid.Column="2"
Command="{Binding Move.Value.TriggerType.AddCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_TriggerType}"
Content="+" />
<Button
Grid.Column="3"
Command="{Binding Move.Value.TriggerType.RemoveCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_TriggerType}"
Content="-" />
</Grid>
<Label Grid.Row="2" Content="{ll:Str 状态类型}" />
<Grid Grid.Row="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Move.Value.ModeType.EnumValue.Value}" />
<ComboBox
x:Name="ComboBox_ModeType"
Grid.Column="1"
ItemsSource="{Binding Move.Value.DirectionTypes}"
SelectedIndex="0" />
<Button
Grid.Column="2"
Command="{Binding Move.Value.ModeType.AddCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_ModeType}"
Content="+" />
<Button
Grid.Column="3"
Command="{Binding Move.Value.ModeType.RemoveCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_ModeType}"
Content="-" />
</Grid>
<Label Grid.Row="3" Content="{ll:Str 移动距离}" />
<pu:NumberInput
Grid.Row="3"
Grid.Column="1"
Value="{Binding Move.Value.Distance.Value}" />
<Label Grid.Row="4" Content="{ll:Str 移动间隔(ms)}" />
<pu:NumberInput
Grid.Row="4"
Grid.Column="1"
Value="{Binding Move.Value.Interval.Value}" />
<Label Grid.Row="5" Content="{ll:Str 定位长度}" />
<pu:NumberInput
Grid.Row="5"
Grid.Column="1"
Value="{Binding Move.Value.LocateLength.Value}" />
<Expander
Grid.Row="6"
Grid.ColumnSpan="2"
Header="{ll:Str 触发距离}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{ll:Str 左}" />
<pu:NumberInput
Grid.Row="0"
Grid.Column="1"
Value="{Binding Move.Value.TriggerLeft.Value}" />
<Label Grid.Row="1" Content="{ll:Str 上}" />
<pu:NumberInput
Grid.Row="1"
Grid.Column="1"
Value="{Binding Move.Value.TriggerTop.Value}" />
<Label Grid.Row="2" Content="{ll:Str 右}" />
<pu:NumberInput
Grid.Row="2"
Grid.Column="1"
Value="{Binding Move.Value.TriggerRight.Value}" />
<Label Grid.Row="3" Content="{ll:Str 下}" />
<pu:NumberInput
Grid.Row="3"
Grid.Column="1"
Value="{Binding Move.Value.TriggerBottom.Value}" />
</Grid>
</Expander>
<Expander
Grid.Row="7"
Grid.ColumnSpan="2"
Header="{ll:Str 检测距离}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{ll:Str 左}" />
<pu:NumberInput
Grid.Row="0"
Grid.Column="1"
Value="{Binding Move.Value.CheckLeft.Value}" />
<Label Grid.Row="1" Content="{ll:Str 上}" />
<pu:NumberInput
Grid.Row="1"
Grid.Column="1"
Value="{Binding Move.Value.CheckTop.Value}" />
<Label Grid.Row="2" Content="{ll:Str 右}" />
<pu:NumberInput
Grid.Row="2"
Grid.Column="1"
Value="{Binding Move.Value.CheckRight.Value}" />
<Label Grid.Row="3" Content="{ll:Str 下}" />
<pu:NumberInput
Grid.Row="3"
Grid.Column="1"
Value="{Binding Move.Value.CheckBottom.Value}" />
</Grid>
</Expander>
</Grid>
</Grid>
</ScrollViewer>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="Button_Cancel"
Margin="10"
Click="Button_Cancel_Click"
Content="{ll:Str 取消}" />
<Button
x:Name="Button_Yes"
Grid.Column="1"
Margin="10"
Click="Button_Yes_Click"
Content="{ll:Str 确定}" />
</Grid>
</Grid>
</Grid>
</Window>

View File

@ -0,0 +1,57 @@
using LinePutScript.Localization.WPF;
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.Shapes;
using VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
namespace VPet.ModMaker.Views.ModEdit.MoveEdit;
/// <summary>
/// MoveEditWindow.xaml 的交互逻辑
/// </summary>
public partial class MoveEditWindow : Window
{
public bool IsCancel { get; private set; } = true;
public MoveEditWindowVM ViewModel => (MoveEditWindowVM)DataContext;
public MoveEditWindow()
{
InitializeComponent();
DataContext = new MoveEditWindowVM();
Closed += (s, e) =>
{
ViewModel.Close();
};
}
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void Button_Yes_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(ViewModel.Move.Value.Graph.Value))
{
MessageBox.Show(
"指定动画Id不可为空".Translate(),
"",
MessageBoxButton.OK,
MessageBoxImage.Warning
);
return;
}
IsCancel = false;
Close();
}
}

View File

@ -0,0 +1,160 @@
<Page
x:Class="VPet.ModMaker.Views.ModEdit.MoveEdit.MovePage"
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.MoveEdit"
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.MoveEdit"
Title="MovePage"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<d:Page.DataContext>
<vm:MovePageVM />
</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 ShowMoves.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 Graph.Value}"
CanUserSort="True"
IsReadOnly="True"
SortMemberPath="Graph.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>
<DataGridTextColumn
Binding="{Binding TriggerType.EnumValue.Value}"
CanUserSort="True"
IsReadOnly="True"
SortMemberPath="TriggerType.EnumValue.Value">
<DataGridTextColumn.Header>
<TextBlock Text="{ll:Str 触发类型}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn
Binding="{Binding ModeType.EnumValue.Value}"
CanUserSort="True"
IsReadOnly="True"
SortMemberPath="ModeType.EnumValue.Value">
<DataGridTextColumn.Header>
<TextBlock Text="{ll:Str 状态类型}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn
Binding="{Binding Distance.Value}"
CanUserSort="True"
IsReadOnly="True"
SortMemberPath="Distance.Value">
<DataGridTextColumn.Header>
<TextBlock Text="{ll:Str 移动距离}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn
Binding="{Binding Interval.Value}"
CanUserSort="True"
IsReadOnly="True"
SortMemberPath="Interval.Value">
<DataGridTextColumn.Header>
<TextBlock Text="{ll:Str 移动间隔}" />
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn
Binding="{Binding LocateLength.Value}"
CanUserSort="True"
IsReadOnly="True"
SortMemberPath="LocateLength.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>

View 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;
using VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
namespace VPet.ModMaker.Views.ModEdit.MoveEdit;
/// <summary>
/// MovePage.xaml 的交互逻辑
/// </summary>
public partial class MovePage : Page
{
public MovePage()
{
InitializeComponent();
DataContext = new MovePageVM();
}
public MovePageVM ViewModel => (MovePageVM)DataContext;
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (sender is not DataGrid dataGrid || dataGrid.SelectedItem is not MoveModel model)
return;
ViewModel.Edit(model);
}
}