mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
重构一部分
This commit is contained in:
parent
293066e940
commit
ce416a004c
@ -1,18 +1,17 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:c="clr-namespace:VPet.ModMaker.Converters">
|
||||
<c:MarginConverter x:Key="MarginConverter" />
|
||||
<c:RatioMarginConverter x:Key="RatioMarginConverter" />
|
||||
<c:CalculatorConverter x:Key="CalculatorConverter" />
|
||||
<c:StringFormatConverter x:Key="StringFormatConverter" />
|
||||
<c:BrushToMediaColorConverter x:Key="BrushToMediaColorConverter" />
|
||||
<c:MaxConverter x:Key="MaxConverter" />
|
||||
<c:FalseToHiddenConverter x:Key="FalseToHiddenConverter" />
|
||||
<c:FalseToCollapsedConverter x:Key="FalseToCollapsedConverter" />
|
||||
<c:EqualsConverter x:Key="EqualsConverter" />
|
||||
<c:NotEqualsConverter x:Key="NotEqualsConverter" />
|
||||
<c:NullToFalseConverter x:Key="NullToFalseConverter" />
|
||||
<c:AllTrueToCollapsedConverter x:Key="AllTrueToCollapsedConverter" />
|
||||
<c:BoolInverter x:Key="BoolInverter" />
|
||||
xmlns:c="https://hkw.com/wpf">
|
||||
<c:MarginMultiConverter x:Key="MarginConverter" />
|
||||
<c:MarginMultiConverter x:Key="RatioMarginConverter" HasRatio="True" />
|
||||
<c:CalculatorMultiConverter x:Key="CalculatorConverter" />
|
||||
<c:StringFormatMultiConverter x:Key="StringFormatConverter" />
|
||||
<c:SolidColorBrushToMediaColorConverter x:Key="BrushToMediaColorConverter" />
|
||||
<!--<c:MaxConverter x:Key="MaxConverter" />-->
|
||||
<c:BoolToVisibilityConverter x:Key="FalseToCollapsedConverter" />
|
||||
<c:EqualsMultiConverter x:Key="EqualsConverter" />
|
||||
<c:EqualsMultiConverter x:Key="NotEqualsConverter" IsInverted="True" />
|
||||
<c:NullToBoolConverter x:Key="NullToFalseConverter" />
|
||||
<c:AllBoolToVisibilityMultiConverter x:Key="AllTrueToCollapsedConverter" />
|
||||
<c:BoolInverteConverter x:Key="BoolInverter" />
|
||||
</ResourceDictionary>
|
@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 全部为真时设置隐藏转换器
|
||||
/// </summary>
|
||||
public class AllTrueToCollapsedConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Length == 0)
|
||||
throw new ArgumentException("No values", nameof(values));
|
||||
return values.All(i => i is true) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 任意为假时设置显示转换器
|
||||
/// </summary>
|
||||
public class AnyFalseToVisibleConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Length == 0)
|
||||
throw new ArgumentException("No values", nameof(values));
|
||||
return values.Any(i => i is not true) ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class BoolInverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not bool b)
|
||||
throw new ArgumentException("Value type not bool", nameof(value));
|
||||
return !b;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class BrushToMediaColorConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not SolidColorBrush brush)
|
||||
throw new ArgumentException("Not SolidColorBrush", nameof(value));
|
||||
return brush.Color;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not Color color)
|
||||
throw new ArgumentException("Not media color", nameof(value));
|
||||
return new SolidColorBrush(color);
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 计算器转换器
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// <MultiBinding Converter="{StaticResource CalculatorConverter}">
|
||||
/// <Binding Path="Num1" />
|
||||
/// <Binding Source="+" />
|
||||
/// <Binding Path="Num2" />
|
||||
/// <Binding Source="-" />
|
||||
/// <Binding Path="Num3" />
|
||||
/// <Binding Source="*" />
|
||||
/// <Binding Path="Num4" />
|
||||
/// <Binding Source="/" />
|
||||
/// <Binding Path="Num5" />
|
||||
/// </MultiBinding>
|
||||
/// //
|
||||
/// <MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="+-*/">
|
||||
/// <Binding Path="Num1" />
|
||||
/// <Binding Path="Num2" />
|
||||
/// <Binding Path="Num3" />
|
||||
/// <Binding Path="Num4" />
|
||||
/// <Binding Path="Num5" />
|
||||
/// </MultiBinding>
|
||||
/// ]]></code></para>
|
||||
/// </summary>
|
||||
/// <exception cref="Exception">绑定的数量不正确</exception>
|
||||
public class CalculatorConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Any(i => i == DependencyProperty.UnsetValue))
|
||||
return 0.0;
|
||||
if (values.Length == 1)
|
||||
return values[0];
|
||||
double result = System.Convert.ToDouble(values[0]);
|
||||
if (parameter is string operators)
|
||||
{
|
||||
if (operators.Length != values.Length - 1)
|
||||
throw new Exception("Parameter error: operator must be one more than parameter");
|
||||
for (int i = 1; i < values.Length - 1; i++)
|
||||
result = Operation(result, operators[i - 1], System.Convert.ToDouble(values[i]));
|
||||
result = Operation(result, operators.Last(), System.Convert.ToDouble(values.Last()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (System.Convert.ToBoolean(values.Length & 1) is false)
|
||||
throw new Exception("Parameter error: Incorrect quantity");
|
||||
bool isNumber = false;
|
||||
char currentOperator = '0';
|
||||
for (int i = 1; i < values.Length - 1; i++)
|
||||
{
|
||||
if (isNumber is false)
|
||||
{
|
||||
currentOperator = ((string)values[i])[0];
|
||||
isNumber = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var value = System.Convert.ToDouble(values[i]);
|
||||
result = Operation(result, currentOperator, value);
|
||||
isNumber = false;
|
||||
}
|
||||
}
|
||||
result = Operation(result, currentOperator, System.Convert.ToDouble(values.Last()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double Operation(double value1, char operatorChar, double value2)
|
||||
{
|
||||
return operatorChar switch
|
||||
{
|
||||
'+' => value1 + value2,
|
||||
'-' => value1 - value2,
|
||||
'*' => value1 * value2,
|
||||
'/' => value1 / value2,
|
||||
'%' => value1 % value2,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class EqualsConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(
|
||||
object[] values,
|
||||
Type targetType,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
if (values.Length != 2)
|
||||
throw new NotImplementedException("Values length must be 2");
|
||||
return values[0].Equals(values[1]);
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class FalseToCollapsedConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (bool.TryParse(value.ToString(), out var result) && result)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is Visibility visibility && visibility == Visibility.Collapsed;
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
using Panuon.WPF;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class FalseToHiddenConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (bool.TryParse(value.ToString(), out var result) && result)
|
||||
? Visibility.Visible
|
||||
: Visibility.Hidden;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is Visibility visibility && visibility == Visibility.Hidden;
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 边距转换器
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// <MultiBinding Converter="{StaticResource MarginConverter}">
|
||||
/// <Binding Path="Left" />
|
||||
/// <Binding Path="Top" />
|
||||
/// <Binding Path="Right" />
|
||||
/// <Binding Path="Bottom" />
|
||||
/// </MultiBinding>
|
||||
/// ]]></code></para>
|
||||
/// </summary>
|
||||
public class MarginConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(
|
||||
object[] values,
|
||||
Type targetType,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
if (values.Length == 0)
|
||||
{
|
||||
return new Thickness();
|
||||
}
|
||||
else if (values.Length == 1)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[0]),
|
||||
Top = default,
|
||||
Right = default,
|
||||
Bottom = default
|
||||
};
|
||||
}
|
||||
else if (values.Length == 2)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[0]),
|
||||
Top = System.Convert.ToDouble(values[1]),
|
||||
Right = default,
|
||||
Bottom = default
|
||||
};
|
||||
}
|
||||
else if (values.Length == 3)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[0]),
|
||||
Top = System.Convert.ToDouble(values[1]),
|
||||
Right = System.Convert.ToDouble(values[2]),
|
||||
Bottom = default
|
||||
};
|
||||
}
|
||||
else if (values.Length == 4)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[0]),
|
||||
Top = System.Convert.ToDouble(values[1]),
|
||||
Right = System.Convert.ToDouble(values[2]),
|
||||
Bottom = System.Convert.ToDouble(values[3])
|
||||
};
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class MaxConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(
|
||||
object[] values,
|
||||
Type targetType,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
return values.Max(i => (double)i);
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class MediaColorToBrushConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not Color color)
|
||||
throw new ArgumentException("Not media color", nameof(value));
|
||||
return new SolidColorBrush(color);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not SolidColorBrush brush)
|
||||
throw new ArgumentException("Not SolidColorBrush", nameof(value));
|
||||
return brush.Color;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class NotEqualsConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(
|
||||
object[] values,
|
||||
Type targetType,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
if (values.Length != 2)
|
||||
throw new NotImplementedException("Values length must be 2");
|
||||
return !values[0].Equals(values[1]);
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
public class NullToFalseConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is not null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 边距转换器
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// <MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
/// <Binding Path="Left" />
|
||||
/// <Binding Path="Top" />
|
||||
/// <Binding Path="Right" />
|
||||
/// <Binding Path="Bottom" />
|
||||
/// </MultiBinding>
|
||||
/// ]]></code></para>
|
||||
/// </summary>
|
||||
public class RatioMarginConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(
|
||||
object[] values,
|
||||
Type targetType,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
if (values.Any(i => i == DependencyProperty.UnsetValue))
|
||||
return new Thickness();
|
||||
if (values.Length == 0)
|
||||
{
|
||||
return new Thickness();
|
||||
}
|
||||
else if (values.Length == 1)
|
||||
{
|
||||
return new Thickness();
|
||||
}
|
||||
var ratio = System.Convert.ToDouble(values[0]);
|
||||
if (values.Length == 2)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[1]) * ratio,
|
||||
Top = default,
|
||||
Right = default,
|
||||
Bottom = default
|
||||
};
|
||||
}
|
||||
else if (values.Length == 3)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[1]) * ratio,
|
||||
Top = System.Convert.ToDouble(values[2]) * ratio,
|
||||
Right = default,
|
||||
Bottom = default
|
||||
};
|
||||
}
|
||||
else if (values.Length == 4)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[1]) * ratio,
|
||||
Top = System.Convert.ToDouble(values[2]) * ratio,
|
||||
Right = System.Convert.ToDouble(values[3]) * ratio,
|
||||
Bottom = default
|
||||
};
|
||||
}
|
||||
else if (values.Length == 5)
|
||||
{
|
||||
return new Thickness()
|
||||
{
|
||||
Left = System.Convert.ToDouble(values[1]) * ratio,
|
||||
Top = System.Convert.ToDouble(values[2]) * ratio,
|
||||
Right = System.Convert.ToDouble(values[3]) * ratio,
|
||||
Bottom = System.Convert.ToDouble(values[4]) * ratio
|
||||
};
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VPet.ModMaker.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 边距转换器
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// <MultiBinding Converter="{StaticResource MarginConverter}">
|
||||
/// <Binding Path="StringFormat" />
|
||||
/// <Binding Path="Value1" />
|
||||
/// <Binding Path="Value2" />
|
||||
/// </MultiBinding>
|
||||
/// OR
|
||||
/// <MultiBinding Converter="{StaticResource MarginConverter}" ConverterParameter="{}{0}{1}">
|
||||
/// <Binding Path="Value1" />
|
||||
/// <Binding Path="Value2" />
|
||||
/// </MultiBinding>
|
||||
/// ]]></code></para>
|
||||
/// </summary>
|
||||
public class StringFormatConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(
|
||||
object[] values,
|
||||
Type targetType,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
var formatStr = (string)parameter;
|
||||
if (string.IsNullOrWhiteSpace(formatStr))
|
||||
{
|
||||
formatStr = (string)values[0];
|
||||
return string.Format(formatStr, values.Skip(1).ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format(formatStr, values);
|
||||
}
|
||||
}
|
||||
|
||||
public object[] ConvertBack(
|
||||
object value,
|
||||
Type[] targetTypes,
|
||||
object parameter,
|
||||
System.Globalization.CultureInfo culture
|
||||
)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察的枚举标签模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ObservableEnumFlags<T>
|
||||
where T : Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 枚举值
|
||||
/// </summary>
|
||||
public ObservableValue<T> EnumValue { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加枚举命令
|
||||
/// </summary>
|
||||
public ObservableCommand<T> AddCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除枚举命令
|
||||
/// </summary>
|
||||
public ObservableCommand<T> RemoveCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 枚举类型
|
||||
/// </summary>
|
||||
public Type EnumType = typeof(T);
|
||||
|
||||
/// <summary>
|
||||
/// 枚举基类
|
||||
/// </summary>
|
||||
public Type UnderlyingType { get; } = Enum.GetUnderlyingType(typeof(T));
|
||||
|
||||
public ObservableEnumFlags()
|
||||
{
|
||||
if (Attribute.IsDefined(EnumType, typeof(FlagsAttribute)) is false)
|
||||
throw new Exception("此枚举类型未使用特性 [Flags]");
|
||||
AddCommand.ExecuteCommand += AddCommand_ExecuteEvent;
|
||||
RemoveCommand.ExecuteCommand += RemoveCommand_ExecuteEvent;
|
||||
}
|
||||
|
||||
public ObservableEnumFlags(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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +1,33 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// I18n数据
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{Id}, Count = {Datas.Count}")]
|
||||
public class I18nData
|
||||
[DebuggerDisplay("{ID}, Count = {Datas.Count}")]
|
||||
public class I18nData : ObservableObjectX<I18nData>
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 基于 <see cref="I18nHelper.Current.CultureNames"/> 的索引的数据列表
|
||||
|
@ -1,11 +1,12 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
@ -13,7 +14,7 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// I18n助手
|
||||
/// </summary>
|
||||
public class I18nHelper
|
||||
public class I18nHelper : ObservableObjectX<I18nHelper>
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前数据
|
||||
@ -23,7 +24,16 @@ public class I18nHelper
|
||||
/// <summary>
|
||||
/// 当前文化名称
|
||||
/// </summary>
|
||||
public ObservableValue<string> CultureName { get; } = new();
|
||||
#region CultureName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _cultureName;
|
||||
|
||||
public string CultureName
|
||||
{
|
||||
get => _cultureName;
|
||||
set => SetProperty(ref _cultureName, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 文化列表
|
||||
|
@ -1,9 +1,10 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
@ -11,13 +12,22 @@ namespace VPet.ModMaker.Models;
|
||||
/// I18n模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class I18nModel<T>
|
||||
public class I18nModel<T> : ObservableObjectX<I18nModel<T>>
|
||||
where T : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前I18n数据
|
||||
/// </summary>
|
||||
public ObservableValue<T> CurrentI18nData { get; } = new();
|
||||
#region CurrentI18nData
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private T _currentI18nData;
|
||||
|
||||
public T CurrentI18nData
|
||||
{
|
||||
get => _currentI18nData;
|
||||
set => SetProperty(ref _currentI18nData, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 所有I18n数据
|
||||
@ -26,7 +36,8 @@ public class I18nModel<T>
|
||||
|
||||
public I18nModel()
|
||||
{
|
||||
I18nHelper.Current.CultureName.ValueChanged += CultureChanged;
|
||||
//TODO
|
||||
//I18nHelper.Current.CultureName.ValueChanged += CultureChanged;
|
||||
I18nHelper.Current.AddCulture += AddCulture;
|
||||
I18nHelper.Current.RemoveCulture += RemoveCulture;
|
||||
I18nHelper.Current.ReplaceCulture += ReplaceCulture;
|
||||
@ -36,7 +47,7 @@ public class I18nModel<T>
|
||||
{
|
||||
I18nDatas.Add(item, new());
|
||||
}
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -47,9 +58,9 @@ public class I18nModel<T>
|
||||
private void CultureChanged(ObservableValue<string> sender, ValueChangedEventArgs<string> e)
|
||||
{
|
||||
if (e.NewValue is null)
|
||||
CurrentI18nData.Value = null;
|
||||
CurrentI18nData = null;
|
||||
else if (I18nDatas.TryGetValue(e.NewValue, out var result))
|
||||
CurrentI18nData.Value = result;
|
||||
CurrentI18nData = result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,9 +1,9 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
@ -11,20 +11,20 @@ namespace VPet.ModMaker.Models;
|
||||
/// I18n模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class I18nModelBase<T> : ObservableClass<I18nModelBase<T>>
|
||||
public class I18nModelBase<T> : ObservableObjectX<I18nModelBase<T>>
|
||||
where T : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前I18n数据
|
||||
/// </summary>
|
||||
|
||||
private T _CurrentI18nData = new();
|
||||
#region CurrentI18nData
|
||||
private T _currentI18nData = new();
|
||||
public T CurrentI18nData
|
||||
{
|
||||
get => _CurrentI18nData;
|
||||
set => SetProperty(ref _CurrentI18nData, value);
|
||||
get => _currentI18nData;
|
||||
set => SetProperty(ref _currentI18nData, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 所有I18n数据
|
||||
/// </summary>
|
||||
@ -32,7 +32,8 @@ public class I18nModelBase<T> : ObservableClass<I18nModelBase<T>>
|
||||
|
||||
public I18nModelBase()
|
||||
{
|
||||
I18nHelper.Current.CultureName.ValueChanged += CultureChanged;
|
||||
//TODO
|
||||
//I18nHelper.Current.CultureName.ValueChanged += CultureChanged;
|
||||
I18nHelper.Current.AddCulture += AddCulture;
|
||||
I18nHelper.Current.RemoveCulture += RemoveCulture;
|
||||
I18nHelper.Current.ReplaceCulture += ReplaceCulture;
|
||||
@ -40,7 +41,7 @@ public class I18nModelBase<T> : ObservableClass<I18nModelBase<T>>
|
||||
return;
|
||||
foreach (var item in I18nHelper.Current.CultureNames)
|
||||
I18nDatas.Add(item, new());
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -129,9 +129,9 @@ public class ModLoader
|
||||
foreach (var sub in line)
|
||||
{
|
||||
if (sub.Name == Name)
|
||||
i18nData.Name.Value = sub.Info;
|
||||
i18nData.Name = sub.Info;
|
||||
else if (sub.Name == Intro)
|
||||
i18nData.Description.Value = sub.Info;
|
||||
i18nData.Description = sub.Info;
|
||||
}
|
||||
I18nDatas.Add(line.Info, i18nData);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using HKW.HKWUtils.Observable;
|
||||
@ -9,17 +10,35 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
/// <summary>
|
||||
/// 动画模型
|
||||
/// </summary>
|
||||
public class AnimeModel
|
||||
public class AnimeModel : ObservableObjectX<AnimeModel>
|
||||
{
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AnimeType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private GraphInfo.AnimatType _animeType;
|
||||
|
||||
/// <summary>
|
||||
/// 动画类型
|
||||
/// </summary>
|
||||
public ObservableValue<GraphInfo.AnimatType> AnimeType { get; } = new();
|
||||
public GraphInfo.AnimatType AnimeType
|
||||
{
|
||||
get => _animeType;
|
||||
set => SetProperty(ref _animeType, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 图像列表
|
||||
@ -34,7 +53,7 @@ public class AnimeModel
|
||||
foreach (var file in Directory.EnumerateFiles(imagesPath))
|
||||
{
|
||||
var info = Path.GetFileNameWithoutExtension(file).Split(NativeUtils.Separator);
|
||||
Id.Value = info[0];
|
||||
Id = info[0];
|
||||
var duration = info.Last();
|
||||
var imageModel = new ImageModel(
|
||||
NativeUtils.LoadImageToMemoryStream(file),
|
||||
@ -51,8 +70,8 @@ public class AnimeModel
|
||||
public AnimeModel Copy()
|
||||
{
|
||||
var model = new AnimeModel();
|
||||
model.Id.Value = Id.Value;
|
||||
model.AnimeType.Value = AnimeType.Value;
|
||||
model.Id = Id;
|
||||
model.AnimeType = AnimeType;
|
||||
foreach (var image in Images)
|
||||
model.Images.Add(image.Copy());
|
||||
return model;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -13,7 +14,7 @@ using static VPet_Simulator.Core.IGameSave;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class AnimeTypeModel
|
||||
public class AnimeTypeModel : ObservableObjectX<AnimeTypeModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// 动作类型
|
||||
@ -65,20 +66,47 @@ public class AnimeTypeModel
|
||||
GraphInfo.GraphType.Say
|
||||
};
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public ObservableValue<string> Name { get; } = new();
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GraphType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private GraphInfo.GraphType _GraphType;
|
||||
|
||||
/// <summary>
|
||||
/// 动作类型
|
||||
/// </summary>
|
||||
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
||||
public GraphInfo.GraphType GraphType
|
||||
{
|
||||
get => _GraphType;
|
||||
set => SetProperty(ref _GraphType, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 开心动画
|
||||
@ -101,19 +129,19 @@ public class AnimeTypeModel
|
||||
public ObservableCollection<AnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public AnimeTypeModel()
|
||||
{
|
||||
Name.ValueChanged += (_, _) =>
|
||||
{
|
||||
Id.Value = $"{GraphType.Value}_{Name.Value}";
|
||||
};
|
||||
{ //TODO
|
||||
//Name.ValueChanged += (_, _) =>
|
||||
//{
|
||||
// Id.Value = $"{GraphType.Value}_{Name.Value}";
|
||||
//};
|
||||
}
|
||||
|
||||
public AnimeTypeModel(AnimeTypeModel model)
|
||||
: this()
|
||||
{
|
||||
Id.Value = model.Id.Value;
|
||||
Name.Value = model.Name.Value;
|
||||
GraphType.Value = model.GraphType.Value;
|
||||
Id = model.Id;
|
||||
Name = model.Name;
|
||||
GraphType = model.GraphType;
|
||||
foreach (var anime in model.HappyAnimes)
|
||||
HappyAnimes.Add(anime.Copy());
|
||||
foreach (var anime in model.NomalAnimes)
|
||||
@ -165,13 +193,13 @@ public class AnimeTypeModel
|
||||
|
||||
public AnimeTypeModel(GraphInfo.GraphType graphType, string path)
|
||||
{
|
||||
Name.Value = Path.GetFileName(path);
|
||||
Name = Path.GetFileName(path);
|
||||
// 为带有名字的类型设置Id
|
||||
if (graphType.IsHasNameAnime())
|
||||
Id.Value = $"{graphType}_{Name.Value}";
|
||||
Id = $"{graphType}_{Name}";
|
||||
else
|
||||
Id.Value = graphType.ToString();
|
||||
GraphType.Value = graphType;
|
||||
Id = graphType.ToString();
|
||||
GraphType = graphType;
|
||||
if (
|
||||
graphType
|
||||
is GraphInfo.GraphType.Default
|
||||
@ -370,7 +398,7 @@ public class AnimeTypeModel
|
||||
{
|
||||
// 如果没有文件夹 则载入全部文件
|
||||
var animeModel = new AnimeModel(path);
|
||||
animeModel.AnimeType.Value = animatType;
|
||||
animeModel.AnimeType = animatType;
|
||||
collection.Add(animeModel);
|
||||
}
|
||||
else
|
||||
@ -379,7 +407,7 @@ public class AnimeTypeModel
|
||||
foreach (var imagesDir in Directory.EnumerateDirectories(path))
|
||||
{
|
||||
var animeModel = new AnimeModel(imagesDir);
|
||||
animeModel.AnimeType.Value = animatType;
|
||||
animeModel.AnimeType = animatType;
|
||||
collection.Add(animeModel);
|
||||
}
|
||||
}
|
||||
@ -393,21 +421,21 @@ public class AnimeTypeModel
|
||||
public void Save(string path)
|
||||
{
|
||||
if (
|
||||
GraphType.Value
|
||||
GraphType
|
||||
is GraphInfo.GraphType.Default
|
||||
or GraphInfo.GraphType.Shutdown
|
||||
or GraphInfo.GraphType.StartUP
|
||||
)
|
||||
SaveDefault(path, this);
|
||||
else if (
|
||||
GraphType.Value
|
||||
GraphType
|
||||
is GraphInfo.GraphType.Touch_Head
|
||||
or GraphInfo.GraphType.Touch_Body
|
||||
or GraphInfo.GraphType.Sleep
|
||||
)
|
||||
SaveMultiType(path, this);
|
||||
else if (
|
||||
GraphType.Value
|
||||
GraphType
|
||||
is GraphInfo.GraphType.Switch_Up
|
||||
or GraphInfo.GraphType.Switch_Down
|
||||
or GraphInfo.GraphType.Switch_Thirsty
|
||||
@ -415,16 +443,14 @@ public class AnimeTypeModel
|
||||
)
|
||||
SaveSwitch(path, this);
|
||||
else if (
|
||||
GraphType.Value
|
||||
is GraphInfo.GraphType.Raised_Dynamic
|
||||
or GraphInfo.GraphType.Raised_Static
|
||||
GraphType is GraphInfo.GraphType.Raised_Dynamic or GraphInfo.GraphType.Raised_Static
|
||||
)
|
||||
SaveRaised(path, this);
|
||||
else if (GraphType.Value is GraphInfo.GraphType.StateONE or GraphInfo.GraphType.StateTWO)
|
||||
else if (GraphType is GraphInfo.GraphType.StateONE or GraphInfo.GraphType.StateTWO)
|
||||
SaveState(path, this);
|
||||
else if (GraphType.Value is GraphInfo.GraphType.Common)
|
||||
else if (GraphType is GraphInfo.GraphType.Common)
|
||||
SaveCommon(path, this);
|
||||
else if (GraphType.Value.IsHasNameAnime())
|
||||
else if (GraphType.IsHasNameAnime())
|
||||
SaveHasNameAnime(path, this);
|
||||
}
|
||||
|
||||
@ -435,9 +461,9 @@ public class AnimeTypeModel
|
||||
/// <param name="animeTypeModel">动画模型</param>
|
||||
void SaveHasNameAnime(string path, AnimeTypeModel animeTypeModel)
|
||||
{
|
||||
var animeTypePath = Path.Combine(path, animeTypeModel.GraphType.Value.ToString());
|
||||
var animeTypePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
||||
Directory.CreateDirectory(animeTypePath);
|
||||
var animePath = Path.Combine(animeTypePath, animeTypeModel.Name.Value);
|
||||
var animePath = Path.Combine(animeTypePath, animeTypeModel.Name);
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveWithModeType(animePath, animeTypeModel);
|
||||
}
|
||||
@ -449,7 +475,7 @@ public class AnimeTypeModel
|
||||
/// <param name="animeTypeModel">模型</param>
|
||||
void SaveCommon(string path, AnimeTypeModel animeTypeModel)
|
||||
{
|
||||
var animePath = Path.Combine(path, animeTypeModel.Name.Value);
|
||||
var animePath = Path.Combine(path, animeTypeModel.Name);
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveWithModeType(animePath, animeTypeModel);
|
||||
}
|
||||
@ -475,9 +501,9 @@ public class AnimeTypeModel
|
||||
{
|
||||
var animePath = Path.Combine(path, "Raise");
|
||||
Directory.CreateDirectory(animePath);
|
||||
if (animeTypeModel.GraphType.Value is GraphInfo.GraphType.Raised_Dynamic)
|
||||
if (animeTypeModel.GraphType is GraphInfo.GraphType.Raised_Dynamic)
|
||||
SaveDefault(animePath, animeTypeModel);
|
||||
else if (animeTypeModel.GraphType.Value is GraphInfo.GraphType.Raised_Static)
|
||||
else if (animeTypeModel.GraphType is GraphInfo.GraphType.Raised_Static)
|
||||
SaveMultiType(animePath, animeTypeModel);
|
||||
}
|
||||
|
||||
@ -554,21 +580,21 @@ public class AnimeTypeModel
|
||||
var countC = 0;
|
||||
foreach (var anime in animes)
|
||||
{
|
||||
if (anime.AnimeType.Value is GraphInfo.AnimatType.A_Start)
|
||||
if (anime.AnimeType is GraphInfo.AnimatType.A_Start)
|
||||
{
|
||||
var animatTypePath = Path.Combine(animePath, "A");
|
||||
Directory.CreateDirectory(animatTypePath);
|
||||
SaveImages(Path.Combine(animatTypePath, countA.ToString()), anime);
|
||||
countA++;
|
||||
}
|
||||
else if (anime.AnimeType.Value is GraphInfo.AnimatType.B_Loop)
|
||||
else if (anime.AnimeType is GraphInfo.AnimatType.B_Loop)
|
||||
{
|
||||
var animatTypePath = Path.Combine(animePath, "B");
|
||||
Directory.CreateDirectory(animatTypePath);
|
||||
SaveImages(Path.Combine(animatTypePath, countB.ToString()), anime);
|
||||
countB++;
|
||||
}
|
||||
else if (anime.AnimeType.Value is GraphInfo.AnimatType.C_End)
|
||||
else if (anime.AnimeType is GraphInfo.AnimatType.C_End)
|
||||
{
|
||||
var animatTypePath = Path.Combine(animePath, "C");
|
||||
Directory.CreateDirectory(animatTypePath);
|
||||
@ -624,11 +650,8 @@ public class AnimeTypeModel
|
||||
Directory.CreateDirectory(imagesPath);
|
||||
foreach (var image in model.Images.EnumerateIndex())
|
||||
{
|
||||
image.Value.Image.Value.SaveToPng(
|
||||
Path.Combine(
|
||||
imagesPath,
|
||||
$"{model.Id.Value}_{image.Index:000}_{image.Value.Duration.Value}.png"
|
||||
)
|
||||
image.Value.Image.SaveToPng(
|
||||
Path.Combine(imagesPath, $"{model.Id}_{image.Index:000}_{image.Value.Duration}.png")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
using HKW.HKWUtils;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Converter;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Converter;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
@ -38,20 +38,38 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
.Cast<VPet_Simulator.Core.Main.WorkingState>()
|
||||
);
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Working
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _working = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 指定工作
|
||||
/// </summary>
|
||||
public ObservableValue<string> Working { get; } = new();
|
||||
public string Working
|
||||
{
|
||||
get => _working;
|
||||
set => SetProperty(ref _working, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 宠物状态
|
||||
/// </summary>
|
||||
public ObservableEnumFlags<ClickText.ModeType> Mode { get; } =
|
||||
public ObservableEnumCommand<ClickText.ModeType> Mode { get; } =
|
||||
new(
|
||||
ClickText.ModeType.Happy
|
||||
| ClickText.ModeType.Nomal
|
||||
@ -59,15 +77,24 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
| ClickText.ModeType.Ill
|
||||
);
|
||||
|
||||
#region WorkingState
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private VPet_Simulator.Core.Main.WorkingState _WorkingState;
|
||||
|
||||
/// <summary>
|
||||
/// 行动状态
|
||||
/// </summary>
|
||||
public ObservableValue<VPet_Simulator.Core.Main.WorkingState> WorkingState { get; } = new();
|
||||
public VPet_Simulator.Core.Main.WorkingState WorkingState
|
||||
{
|
||||
get => _WorkingState;
|
||||
set => SetProperty(ref _WorkingState, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 日期区间
|
||||
/// </summary>
|
||||
public ObservableEnumFlags<ClickText.DayTime> DayTime { get; } =
|
||||
public ObservableEnumCommand<ClickText.DayTime> DayTime { get; } =
|
||||
new(
|
||||
ClickText.DayTime.Morning
|
||||
| ClickText.DayTime.Afternoon
|
||||
@ -120,32 +147,32 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
public ClickTextModel(ClickTextModel clickText)
|
||||
: this()
|
||||
{
|
||||
Id.Value = clickText.Id.Value;
|
||||
Mode.EnumValue.Value = clickText.Mode.EnumValue.Value;
|
||||
Working.Value = clickText.Working.Value;
|
||||
WorkingState.Value = clickText.WorkingState.Value;
|
||||
DayTime.EnumValue.Value = clickText.DayTime.EnumValue.Value;
|
||||
Like = clickText.Like.Copy();
|
||||
Health = clickText.Health.Copy();
|
||||
Level = clickText.Level.Copy();
|
||||
Money = clickText.Money.Copy();
|
||||
Food = clickText.Food.Copy();
|
||||
Drink = clickText.Drink.Copy();
|
||||
Feel = clickText.Feel.Copy();
|
||||
Strength = clickText.Strength.Copy();
|
||||
Id = clickText.Id;
|
||||
Mode.Value = clickText.Mode.Value;
|
||||
Working = clickText.Working;
|
||||
WorkingState = clickText.WorkingState;
|
||||
DayTime.Value = clickText.DayTime.Value;
|
||||
Like = clickText.Like.Clone();
|
||||
Health = clickText.Health.Clone();
|
||||
Level = clickText.Level.Clone();
|
||||
Money = clickText.Money.Clone();
|
||||
Food = clickText.Food.Clone();
|
||||
Drink = clickText.Drink.Clone();
|
||||
Feel = clickText.Feel.Clone();
|
||||
Strength = clickText.Strength.Clone();
|
||||
foreach (var item in clickText.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public ClickTextModel(ClickText clickText)
|
||||
: this()
|
||||
{
|
||||
Id.Value = clickText.Text;
|
||||
Mode.EnumValue.Value = clickText.Mode;
|
||||
Working.Value = clickText.Working;
|
||||
WorkingState.Value = clickText.State;
|
||||
DayTime.EnumValue.Value = clickText.DaiTime;
|
||||
Id = clickText.Text;
|
||||
Mode.Value = clickText.Mode;
|
||||
Working = clickText.Working;
|
||||
WorkingState = clickText.State;
|
||||
DayTime.Value = clickText.DaiTime;
|
||||
Like = new(clickText.LikeMin, clickText.LikeMax);
|
||||
Health = new(clickText.HealthMin, clickText.HealthMax);
|
||||
Level = new(clickText.LevelMin, clickText.LevelMax);
|
||||
@ -160,11 +187,11 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Text = Id.Value,
|
||||
Mode = Mode.EnumValue.Value,
|
||||
Working = Working.Value,
|
||||
State = WorkingState.Value,
|
||||
DaiTime = DayTime.EnumValue.Value,
|
||||
Text = Id,
|
||||
Mode = Mode.Value,
|
||||
Working = Working,
|
||||
State = WorkingState,
|
||||
DaiTime = DayTime.Value,
|
||||
LikeMax = Like.Max,
|
||||
LikeMin = Like.Min,
|
||||
HealthMin = Health.Min,
|
||||
@ -185,14 +212,23 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nClickTextModel
|
||||
public class I18nClickTextModel : ObservableObjectX<I18nClickTextModel>
|
||||
{
|
||||
public ObservableValue<string> Text { get; } = new();
|
||||
#region Text
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _text = string.Empty;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => _text;
|
||||
set => SetProperty(ref _text, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nClickTextModel Copy()
|
||||
{
|
||||
var result = new I18nClickTextModel();
|
||||
result.Text.Value = Text.Value;
|
||||
result.Text = Text;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@ -12,12 +13,18 @@ using static VPet_Simulator.Core.IGameSave;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class FoodAnimeModel
|
||||
public class FoodAnimeModel : ObservableObjectX<FoodAnimeModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _Id;
|
||||
|
||||
public string Id
|
||||
{
|
||||
get => _Id;
|
||||
set => SetProperty(ref _Id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableValue<ModeType> Mode { get; }
|
||||
|
||||
@ -46,7 +53,7 @@ public class FoodAnimeModel
|
||||
//var index = int.Parse(item.Name.Substring(1));
|
||||
var infos = item.Info.Split(',');
|
||||
var foodLocationInfo = new FoodLocationModel();
|
||||
foodLocationInfo.Duration.Value = int.Parse(infos[0]);
|
||||
foodLocationInfo.Duration = int.Parse(infos[0]);
|
||||
if (infos.Length > 1)
|
||||
{
|
||||
foodLocationInfo.Rect = new(
|
||||
@ -57,9 +64,9 @@ public class FoodAnimeModel
|
||||
);
|
||||
}
|
||||
if (infos.Length > 4)
|
||||
foodLocationInfo.Rotate.Value = double.Parse(infos[4]);
|
||||
foodLocationInfo.Rotate = double.Parse(infos[4]);
|
||||
if (infos.Length > 5)
|
||||
foodLocationInfo.Opacity.Value = double.Parse(infos[5]);
|
||||
foodLocationInfo.Opacity = double.Parse(infos[5]);
|
||||
FoodLocations.Add(foodLocationInfo);
|
||||
}
|
||||
}
|
||||
@ -71,7 +78,7 @@ public class FoodAnimeModel
|
||||
public FoodAnimeModel Copy()
|
||||
{
|
||||
var model = new FoodAnimeModel();
|
||||
model.Id.Value = Id.Value;
|
||||
model.Id = Id;
|
||||
foreach (var image in FrontImages)
|
||||
model.FrontImages.Add(image.Copy());
|
||||
foreach (var image in BackImages)
|
||||
@ -92,10 +99,3 @@ public class FoodAnimeModel
|
||||
image.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public class FoodImagesPath
|
||||
{
|
||||
public ObservableValue<ModeType> Mode { get; } = new();
|
||||
|
||||
public ObservableValue<int> Index { get; } = new();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -14,7 +15,7 @@ using static VPet_Simulator.Core.IGameSave;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
public class FoodAnimeTypeModel
|
||||
public class FoodAnimeTypeModel : ObservableObjectX<FoodAnimeModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// 动作类型
|
||||
@ -37,15 +38,30 @@ public class FoodAnimeTypeModel
|
||||
/// </summary>
|
||||
public const string BackLayName = "back_lay";
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public ObservableValue<string> Name { get; } = new();
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 开心动画
|
||||
@ -68,11 +84,11 @@ public class FoodAnimeTypeModel
|
||||
public ObservableCollection<FoodAnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public FoodAnimeTypeModel()
|
||||
{
|
||||
Name.ValueChanged += (_, _) =>
|
||||
{
|
||||
Id.Value = $"{GraphType}_{Name.Value}";
|
||||
};
|
||||
{ //TODO
|
||||
//Name.ValueChanged += (_, _) =>
|
||||
//{
|
||||
// Id.Value = $"{GraphType}_{Name.Value}";
|
||||
//};
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@ -98,7 +114,7 @@ public class FoodAnimeTypeModel
|
||||
public FoodAnimeTypeModel(string path)
|
||||
: this()
|
||||
{
|
||||
Name.Value = Path.GetFileName(path);
|
||||
Name = Path.GetFileName(path);
|
||||
var infoFiles = Directory.EnumerateFiles(
|
||||
path,
|
||||
ModMakerInfo.InfoFile,
|
||||
@ -108,15 +124,15 @@ public class FoodAnimeTypeModel
|
||||
throw new Exception("信息文件不存在".Translate());
|
||||
foreach (var file in infoFiles)
|
||||
{
|
||||
ParseInfoFile(Path.GetDirectoryName(file), file);
|
||||
ParseInfoFile(Path.GetDirectoryName(file)!, file);
|
||||
}
|
||||
}
|
||||
|
||||
public FoodAnimeTypeModel(FoodAnimeTypeModel model)
|
||||
: this()
|
||||
{
|
||||
Id.Value = model.Id.Value;
|
||||
Name.Value = model.Name.Value;
|
||||
Id = model.Id;
|
||||
Name = model.Name;
|
||||
foreach (var anime in model.HappyAnimes)
|
||||
HappyAnimes.Add(anime.Copy());
|
||||
foreach (var anime in model.NomalAnimes)
|
||||
@ -253,7 +269,7 @@ public class FoodAnimeTypeModel
|
||||
/// <param name="path">路径</param>
|
||||
public void Save(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, Name.Value);
|
||||
var animePath = Path.Combine(path, Name);
|
||||
if (
|
||||
Directory.Exists(animePath)
|
||||
&& HappyAnimes.Count == 0
|
||||
@ -293,8 +309,8 @@ public class FoodAnimeTypeModel
|
||||
var indexPath = Path.Combine(modeAnimePath, anime.Index.ToString());
|
||||
Directory.CreateDirectory(indexPath);
|
||||
var infoFile = Path.Combine(indexPath, ModMakerInfo.InfoFile);
|
||||
var frontLayName = $"{Name.Value.ToLower()}_{FrontLayName}_{anime.Index}";
|
||||
var backLayName = $"{Name.Value.ToLower()}_{BackLayName}_{anime.Index}";
|
||||
var frontLayName = $"{Name.ToLower()}_{FrontLayName}_{anime.Index}";
|
||||
var backLayName = $"{Name.ToLower()}_{BackLayName}_{anime.Index}";
|
||||
SaveInfoFile(infoFile, frontLayName, backLayName, anime.Value, mode);
|
||||
SaveImages(anime.Value, indexPath);
|
||||
}
|
||||
@ -315,19 +331,19 @@ public class FoodAnimeTypeModel
|
||||
Directory.CreateDirectory(backLayPath);
|
||||
foreach (var frontImage in anime.FrontImages.EnumerateIndex())
|
||||
{
|
||||
frontImage.Value.Image.Value.SaveToPng(
|
||||
frontImage.Value.Image.SaveToPng(
|
||||
Path.Combine(
|
||||
frontLayPath,
|
||||
$"{anime.Id.Value}_{frontImage.Index:000}_{frontImage.Value.Duration.Value}.png"
|
||||
$"{anime.Id}_{frontImage.Index:000}_{frontImage.Value.Duration}.png"
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach (var backImage in anime.BackImages.EnumerateIndex())
|
||||
{
|
||||
backImage.Value.Image.Value.SaveToPng(
|
||||
backImage.Value.Image.SaveToPng(
|
||||
Path.Combine(
|
||||
backLayPath,
|
||||
$"{anime.Id.Value}_{backImage.Index:000}_{backImage.Value.Duration.Value}.png"
|
||||
$"{anime.Id}_{backImage.Index:000}_{backImage.Value.Duration}.png"
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -356,10 +372,10 @@ public class FoodAnimeTypeModel
|
||||
new Sub("graph", nameof(GraphInfo.GraphType.Common))
|
||||
},
|
||||
};
|
||||
var line = new Line(nameof(FoodAnimation), Name.Value.ToLower())
|
||||
var line = new Line(nameof(FoodAnimation), Name.ToLower())
|
||||
{
|
||||
new Sub("mode", mode.ToString()),
|
||||
new Sub("graph", Name.Value)
|
||||
new Sub("graph", Name)
|
||||
};
|
||||
foreach (var foodLocation in anime.FoodLocations.EnumerateIndex())
|
||||
{
|
||||
|
@ -1,36 +1,64 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
/// <summary>
|
||||
/// 食物图像模型
|
||||
/// </summary>
|
||||
public class FoodLocationModel
|
||||
public class FoodLocationModel : ObservableObjectX<FoodLocationModel>
|
||||
{
|
||||
#region Duration
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _duration;
|
||||
|
||||
/// <summary>
|
||||
/// 持续时间
|
||||
/// </summary>
|
||||
public ObservableValue<int> Duration { get; } = new(100);
|
||||
public int Duration
|
||||
{
|
||||
get => _duration;
|
||||
set => SetProperty(ref _duration, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 范围
|
||||
/// </summary>
|
||||
public ObservableRect<double> Rect { get; set; } = new();
|
||||
public ObservableRectangleLocation<double> Rect { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 旋转角度
|
||||
/// </summary>
|
||||
public ObservableValue<double> Rotate { get; } = new();
|
||||
#region Rotate
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _rotate;
|
||||
|
||||
public double Rotate
|
||||
{
|
||||
get => _rotate;
|
||||
set => SetProperty(ref _rotate, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 透明度
|
||||
/// </summary>
|
||||
public ObservableValue<double> Opacity { get; } = new(100);
|
||||
#region Opacity
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _opacity;
|
||||
|
||||
public double Opacity
|
||||
{
|
||||
get => _opacity;
|
||||
set => SetProperty(ref _opacity, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public FoodLocationModel()
|
||||
{
|
||||
@ -43,15 +71,15 @@ public class FoodLocationModel
|
||||
public FoodLocationModel Copy()
|
||||
{
|
||||
var model = new FoodLocationModel();
|
||||
model.Duration.Value = Duration.Value;
|
||||
model.Duration = Duration;
|
||||
model.Rect = new(Rect.X, Rect.Y, Rect.Width, Rect.Height);
|
||||
model.Rotate.Value = Rotate.Value;
|
||||
model.Opacity.Value = Opacity.Value;
|
||||
model.Rotate = Rotate;
|
||||
model.Opacity = Opacity;
|
||||
return model;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Duration.Value}, {Rect.X}, {Rect.Y}, {Rect.Width}, {Rotate.Value}, {Opacity.Value}";
|
||||
return $"{Duration}, {Rect.X}, {Rect.Y}, {Rect.Width}, {Rotate}, {Opacity}";
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -24,189 +25,334 @@ public class FoodModel : I18nModel<I18nFoodModel>
|
||||
public static ObservableCollection<Food.FoodType> FoodTypes { get; } =
|
||||
new(Enum.GetValues(typeof(Food.FoodType)).Cast<Food.FoodType>());
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DescriptionId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionId = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 详情Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> DescriptionId { get; } = new();
|
||||
public string DescriptionId
|
||||
{
|
||||
get => _descriptionId;
|
||||
set => SetProperty(ref _descriptionId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 指定动画
|
||||
/// </summary>
|
||||
public ObservableValue<string> Graph { get; } = new("eat");
|
||||
public string Graph
|
||||
{
|
||||
get => _graph;
|
||||
set => SetProperty(ref _graph, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Type
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private Food.FoodType _type;
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
public ObservableValue<Food.FoodType> Type { get; } = new();
|
||||
public Food.FoodType Type
|
||||
{
|
||||
get => _type;
|
||||
set => SetProperty(ref _type, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 体力
|
||||
/// </summary>
|
||||
public ObservableValue<double> Strength { get; } = new();
|
||||
#region Strength
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Strength;
|
||||
|
||||
public double Strength
|
||||
{
|
||||
get => _Strength;
|
||||
set => SetProperty(ref _Strength, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 饱食度
|
||||
/// </summary>
|
||||
public ObservableValue<double> StrengthFood { get; } = new();
|
||||
#region StrengthFood
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _StrengthFood;
|
||||
|
||||
public double StrengthFood
|
||||
{
|
||||
get => _StrengthFood;
|
||||
set => SetProperty(ref _StrengthFood, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 口渴度
|
||||
/// </summary>
|
||||
public ObservableValue<double> StrengthDrink { get; } = new();
|
||||
#region StrengthDrink
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _StrengthDrink;
|
||||
|
||||
public double StrengthDrink
|
||||
{
|
||||
get => _StrengthDrink;
|
||||
set => SetProperty(ref _StrengthDrink, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 心情
|
||||
/// </summary>
|
||||
public ObservableValue<double> Feeling { get; } = new();
|
||||
#region Feeling
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Feeling;
|
||||
|
||||
public double Feeling
|
||||
{
|
||||
get => _Feeling;
|
||||
set => SetProperty(ref _Feeling, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 健康度
|
||||
/// </summary>
|
||||
public ObservableValue<double> Health { get; } = new();
|
||||
#region Health
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Health;
|
||||
|
||||
public double Health
|
||||
{
|
||||
get => _Health;
|
||||
set => SetProperty(ref _Health, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 好感度
|
||||
/// </summary>
|
||||
public ObservableValue<double> Likability { get; } = new();
|
||||
#region Likability
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Likability;
|
||||
|
||||
public double Likability
|
||||
{
|
||||
get => _Likability;
|
||||
set => SetProperty(ref _Likability, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 价格
|
||||
/// </summary>
|
||||
public ObservableValue<double> Price { get; } = new();
|
||||
#region Price
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Price;
|
||||
|
||||
public double Price
|
||||
{
|
||||
get => _Price;
|
||||
set => SetProperty(ref _Price, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 经验
|
||||
/// </summary>
|
||||
public ObservableValue<int> Exp { get; } = new();
|
||||
#region Exp
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _Exp;
|
||||
|
||||
public int Exp
|
||||
{
|
||||
get => _Exp;
|
||||
set => SetProperty(ref _Exp, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public ObservableValue<BitmapImage> Image { get; } = new();
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _Image;
|
||||
|
||||
public ObservableValue<double> ReferencePrice { get; } = new();
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _Image;
|
||||
set => SetProperty(ref _Image, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReferencePrice
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _ReferencePrice;
|
||||
|
||||
public double ReferencePrice
|
||||
{
|
||||
get => _ReferencePrice;
|
||||
set => SetProperty(ref _ReferencePrice, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private readonly Food _food = new();
|
||||
|
||||
public FoodModel()
|
||||
{
|
||||
DescriptionId.Value = $"{Id.Value}_{nameof(DescriptionId)}";
|
||||
Id.ValueChanged += (s, e) =>
|
||||
{
|
||||
DescriptionId.Value = $"{e.NewValue}_{nameof(DescriptionId)}";
|
||||
};
|
||||
ReferencePrice.AddNotifySender(
|
||||
Strength,
|
||||
StrengthFood,
|
||||
StrengthDrink,
|
||||
Feeling,
|
||||
Health,
|
||||
Likability,
|
||||
Exp
|
||||
);
|
||||
ReferencePrice.SenderPropertyChanged += (s, _) =>
|
||||
{
|
||||
s.Value = Math.Floor(SetValueToFood(_food).RealPrice);
|
||||
};
|
||||
DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
//TODO
|
||||
//Id.ValueChanged += (s, e) =>
|
||||
//{
|
||||
// DescriptionId.Value = $"{e.NewValue}_{nameof(DescriptionId)}";
|
||||
//};
|
||||
//ReferencePrice.AddNotifySender(
|
||||
// Strength,
|
||||
// StrengthFood,
|
||||
// StrengthDrink,
|
||||
// Feeling,
|
||||
// Health,
|
||||
// Likability,
|
||||
// Exp
|
||||
//);
|
||||
//ReferencePrice.SenderPropertyChanged += (s, _) =>
|
||||
//{
|
||||
// s.Value = Math.Floor(SetValueToFood(_food).RealPrice);
|
||||
//};
|
||||
}
|
||||
|
||||
public FoodModel(FoodModel model)
|
||||
: this()
|
||||
{
|
||||
Id.Value = model.Id.Value;
|
||||
DescriptionId.Value = model.DescriptionId.Value;
|
||||
Graph.Value = model.Graph.Value;
|
||||
Type.Value = model.Type.Value;
|
||||
Strength.Value = model.Strength.Value;
|
||||
StrengthFood.Value = model.StrengthFood.Value;
|
||||
StrengthDrink.Value = model.StrengthDrink.Value;
|
||||
Feeling.Value = model.Feeling.Value;
|
||||
Health.Value = model.Health.Value;
|
||||
Likability.Value = model.Likability.Value;
|
||||
Price.Value = model.Price.Value;
|
||||
Exp.Value = model.Exp.Value;
|
||||
Image.Value = model.Image.Value.Copy();
|
||||
Id = model.Id;
|
||||
DescriptionId = model.DescriptionId;
|
||||
Graph = model.Graph;
|
||||
Type = model.Type;
|
||||
Strength = model.Strength;
|
||||
StrengthFood = model.StrengthFood;
|
||||
StrengthDrink = model.StrengthDrink;
|
||||
Feeling = model.Feeling;
|
||||
Health = model.Health;
|
||||
Likability = model.Likability;
|
||||
Price = model.Price;
|
||||
Exp = model.Exp;
|
||||
Image = model.Image.Copy();
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public FoodModel(Food food)
|
||||
: this()
|
||||
{
|
||||
Id.Value = food.Name;
|
||||
DescriptionId.Value = food.Desc;
|
||||
Graph.Value = food.Graph;
|
||||
Type.Value = food.Type;
|
||||
Strength.Value = food.Strength;
|
||||
StrengthDrink.Value = food.StrengthDrink;
|
||||
StrengthFood.Value = food.StrengthFood;
|
||||
Feeling.Value = food.Feeling;
|
||||
Health.Value = food.Health;
|
||||
Likability.Value = food.Likability;
|
||||
Price.Value = food.Price;
|
||||
Exp.Value = food.Exp;
|
||||
Id = food.Name;
|
||||
DescriptionId = food.Desc;
|
||||
Graph = food.Graph;
|
||||
Type = food.Type;
|
||||
Strength = food.Strength;
|
||||
StrengthDrink = food.StrengthDrink;
|
||||
StrengthFood = food.StrengthFood;
|
||||
Feeling = food.Feeling;
|
||||
Health = food.Health;
|
||||
Likability = food.Likability;
|
||||
Price = food.Price;
|
||||
Exp = food.Exp;
|
||||
if (File.Exists(food.Image))
|
||||
Image.Value = NativeUtils.LoadImageToMemoryStream(food.Image);
|
||||
Image = NativeUtils.LoadImageToMemoryStream(food.Image);
|
||||
}
|
||||
|
||||
public Food ToFood()
|
||||
{
|
||||
return new Food()
|
||||
{
|
||||
Name = Id.Value,
|
||||
Desc = DescriptionId.Value,
|
||||
Graph = Graph.Value,
|
||||
Type = Type.Value,
|
||||
Strength = Strength.Value,
|
||||
StrengthFood = StrengthFood.Value,
|
||||
StrengthDrink = StrengthDrink.Value,
|
||||
Feeling = Feeling.Value,
|
||||
Health = Health.Value,
|
||||
Likability = Likability.Value,
|
||||
Price = Price.Value,
|
||||
Exp = Exp.Value,
|
||||
Name = Id,
|
||||
Desc = DescriptionId,
|
||||
Graph = Graph,
|
||||
Type = Type,
|
||||
Strength = Strength,
|
||||
StrengthFood = StrengthFood,
|
||||
StrengthDrink = StrengthDrink,
|
||||
Feeling = Feeling,
|
||||
Health = Health,
|
||||
Likability = Likability,
|
||||
Price = Price,
|
||||
Exp = Exp,
|
||||
};
|
||||
}
|
||||
|
||||
public Food SetValueToFood(Food food)
|
||||
{
|
||||
food.Strength = Strength.Value;
|
||||
food.StrengthFood = StrengthFood.Value;
|
||||
food.StrengthDrink = StrengthDrink.Value;
|
||||
food.Feeling = Feeling.Value;
|
||||
food.Health = Health.Value;
|
||||
food.Likability = Likability.Value;
|
||||
food.Exp = Exp.Value;
|
||||
food.Strength = Strength;
|
||||
food.StrengthFood = StrengthFood;
|
||||
food.StrengthDrink = StrengthDrink;
|
||||
food.Feeling = Feeling;
|
||||
food.Health = Health;
|
||||
food.Likability = Likability;
|
||||
food.Exp = Exp;
|
||||
return food;
|
||||
}
|
||||
|
||||
public void RefreshId()
|
||||
{
|
||||
DescriptionId.Value = $"{Id.Value}_{nameof(DescriptionId)}";
|
||||
DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image.Value?.StreamSource?.Close();
|
||||
Image.CloseStream();
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nFoodModel
|
||||
public class I18nFoodModel : ObservableObjectX<I18nFoodModel>
|
||||
{
|
||||
public ObservableValue<string> Name { get; } = new();
|
||||
public ObservableValue<string> Description { get; } = new();
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
#region Description
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _description = string.Empty;
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nFoodModel Copy()
|
||||
{
|
||||
var result = new I18nFoodModel();
|
||||
result.Name.Value = Name.Value;
|
||||
result.Description.Value = Description.Value;
|
||||
result.Name = Name;
|
||||
result.Description = Description;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +1,62 @@
|
||||
using HKW.HKWUtils;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media.Imaging;
|
||||
using HKW.HKWUtils;
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace VPet.ModMaker.Models.ModModel;
|
||||
|
||||
/// <summary>
|
||||
/// 图像模型
|
||||
/// </summary>
|
||||
public class ImageModel
|
||||
public class ImageModel : ObservableObjectX<ImageModel>
|
||||
{
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
|
||||
/// <summary>
|
||||
/// 图像
|
||||
/// </summary>
|
||||
public ObservableValue<BitmapImage> Image { get; } = new();
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Duration
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _duration;
|
||||
|
||||
/// <summary>
|
||||
/// 持续时间
|
||||
/// </summary>
|
||||
public ObservableValue<int> Duration { get; } = new(100);
|
||||
public int Duration
|
||||
{
|
||||
get => _duration;
|
||||
set => SetProperty(ref _duration, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ImageModel(BitmapImage image, int duration = 100)
|
||||
{
|
||||
Image.Value = image;
|
||||
Duration.Value = duration;
|
||||
Image = image;
|
||||
Duration = duration;
|
||||
}
|
||||
|
||||
public ImageModel Copy()
|
||||
{
|
||||
var model = new ImageModel(Image.Value.Copy(), Duration.Value);
|
||||
var model = new ImageModel(Image.Copy(), Duration);
|
||||
return model;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image.Value?.CloseStream();
|
||||
Image?.CloseStream();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
@ -33,48 +34,85 @@ public class LowTextModel : I18nModel<I18nLowTextModel>
|
||||
public static ObservableCollection<LowText.StrengthType> StrengthTypes { get; } =
|
||||
new(Enum.GetValues(typeof(LowText.StrengthType)).Cast<LowText.StrengthType>());
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Mode
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private LowText.ModeType _mode;
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public ObservableValue<LowText.ModeType> Mode { get; } = new();
|
||||
public LowText.ModeType Mode
|
||||
{
|
||||
get => _mode;
|
||||
set => SetProperty(ref _mode, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Strength
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private LowText.StrengthType _strength;
|
||||
|
||||
/// <summary>
|
||||
/// 体力
|
||||
/// </summary>
|
||||
public ObservableValue<LowText.StrengthType> Strength { get; } = new();
|
||||
public LowText.StrengthType Strength
|
||||
{
|
||||
get => _strength;
|
||||
set => SetProperty(ref _strength, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Like
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private LowText.LikeType _like;
|
||||
|
||||
/// <summary>
|
||||
/// 好感度
|
||||
/// </summary>
|
||||
public ObservableValue<LowText.LikeType> Like { get; } = new();
|
||||
|
||||
public LowText.LikeType Like
|
||||
{
|
||||
get => _like;
|
||||
set => SetProperty(ref _like, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public LowTextModel() { }
|
||||
|
||||
public LowTextModel(LowTextModel lowText)
|
||||
: this()
|
||||
{
|
||||
Id.Value = lowText.Id.Value;
|
||||
Mode.Value = lowText.Mode.Value;
|
||||
Strength.Value = lowText.Strength.Value;
|
||||
Like.Value = lowText.Like.Value;
|
||||
Id = lowText.Id;
|
||||
Mode = lowText.Mode;
|
||||
Strength = lowText.Strength;
|
||||
Like = lowText.Like;
|
||||
|
||||
foreach (var item in lowText.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public LowTextModel(LowText lowText)
|
||||
: this()
|
||||
{
|
||||
Id.Value = lowText.Text;
|
||||
Mode.Value = lowText.Mode;
|
||||
Strength.Value = lowText.Strength;
|
||||
Like.Value = lowText.Like;
|
||||
Id = lowText.Text;
|
||||
Mode = lowText.Mode;
|
||||
Strength = lowText.Strength;
|
||||
Like = lowText.Like;
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
@ -83,22 +121,31 @@ public class LowTextModel : I18nModel<I18nLowTextModel>
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Text = Id.Value,
|
||||
Mode = Mode.Value,
|
||||
Strength = Strength.Value,
|
||||
Like = Like.Value,
|
||||
Text = Id,
|
||||
Mode = Mode,
|
||||
Strength = Strength,
|
||||
Like = Like,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nLowTextModel
|
||||
public class I18nLowTextModel : ObservableObjectX<I18nLowTextModel>
|
||||
{
|
||||
public ObservableValue<string> Text { get; } = new();
|
||||
#region Text
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _text = string.Empty;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => _text;
|
||||
set => SetProperty(ref _text, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nLowTextModel Copy()
|
||||
{
|
||||
var result = new I18nLowTextModel();
|
||||
result.Text.Value = Text.Value;
|
||||
result.Text = Text;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -25,15 +26,33 @@ namespace VPet.ModMaker.Models;
|
||||
/// </summary>
|
||||
public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
#region AutoSetFoodPrice
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _autoSetFoodPrice;
|
||||
|
||||
/// <summary>
|
||||
/// 自动设置食物推荐价格
|
||||
/// </summary>
|
||||
public ObservableValue<bool> AutoSetFoodPrice { get; } = new();
|
||||
public bool AutoSetFoodPrice
|
||||
{
|
||||
get => _autoSetFoodPrice;
|
||||
set => SetProperty(ref _autoSetFoodPrice, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ShowMainPet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _showMainPet;
|
||||
|
||||
/// <summary>
|
||||
/// 不显示本体宠物
|
||||
/// </summary>
|
||||
public ObservableValue<bool> ShowMainPet { get; } = new(true);
|
||||
public bool ShowMainPet
|
||||
{
|
||||
get => _showMainPet;
|
||||
set => SetProperty(ref _showMainPet, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ModInfo
|
||||
/// <summary>
|
||||
@ -51,40 +70,103 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public static ModInfoModel Current { get; set; } = new();
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DescriptionId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionId = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 描述Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> DescriptionId { get; } = new();
|
||||
public string DescriptionId
|
||||
{
|
||||
get => _descriptionId;
|
||||
set => SetProperty(ref _descriptionId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 作者
|
||||
/// </summary>
|
||||
public ObservableValue<string> Author { get; } = new();
|
||||
#region Author
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _author = string.Empty;
|
||||
|
||||
public string Author
|
||||
{
|
||||
get => _author;
|
||||
set => SetProperty(ref _author, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 支持的游戏版本
|
||||
/// </summary>
|
||||
public ObservableValue<int> GameVersion { get; } = new(ModMakerInfo.GameVersion);
|
||||
#region GameVersion
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _gameVersion;
|
||||
|
||||
public int GameVersion
|
||||
{
|
||||
get => _gameVersion;
|
||||
set => SetProperty(ref _gameVersion, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 模组版本
|
||||
/// </summary>
|
||||
public ObservableValue<int> ModVersion { get; } = new(100);
|
||||
#region ModVersion
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _modVersion;
|
||||
|
||||
public int ModVersion
|
||||
{
|
||||
get => _modVersion;
|
||||
set => SetProperty(ref _modVersion, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 封面
|
||||
/// </summary>
|
||||
public ObservableValue<BitmapImage> Image { get; } = new();
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 源路径
|
||||
/// </summary>
|
||||
public ObservableValue<string> SourcePath { get; } = new();
|
||||
#region SourcePath
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _sourcePath = string.Empty;
|
||||
|
||||
public string SourcePath
|
||||
{
|
||||
get => _sourcePath;
|
||||
set => SetProperty(ref _sourcePath, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
@ -117,7 +199,16 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// <summary>
|
||||
/// 宠物实际数量
|
||||
/// </summary>
|
||||
public ObservableValue<int> PetDisplayedCount { get; } = new();
|
||||
#region PetDisplayedCount
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _petDisplayedCount;
|
||||
|
||||
public int PetDisplayedCount
|
||||
{
|
||||
get => _petDisplayedCount;
|
||||
set => SetProperty(ref _petDisplayedCount, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 其它I18n数据
|
||||
@ -131,13 +222,14 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
#endregion
|
||||
public ModInfoModel()
|
||||
{
|
||||
DescriptionId.Value = $"{Id.Value}_{nameof(DescriptionId)}";
|
||||
Id.ValueChanged += (o, n) =>
|
||||
{
|
||||
DescriptionId.Value = $"{n}_{nameof(DescriptionId)}";
|
||||
};
|
||||
Pets.CollectionChanged += Pets_CollectionChanged;
|
||||
ShowMainPet.ValueChanged += ShowMainPet_ValueChanged;
|
||||
DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
//TODO
|
||||
//Id.ValueChanged += (o, n) =>
|
||||
//{
|
||||
// DescriptionId.Value = $"{n}_{nameof(DescriptionId)}";
|
||||
//};
|
||||
//Pets.CollectionChanged += Pets_CollectionChanged;
|
||||
//ShowMainPet.ValueChanged += ShowMainPet_ValueChanged;
|
||||
}
|
||||
|
||||
private void ShowMainPet_ValueChanged(
|
||||
@ -150,26 +242,26 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
private void Pets_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (ShowMainPet.Value)
|
||||
PetDisplayedCount.Value = Pets.Count;
|
||||
if (ShowMainPet)
|
||||
PetDisplayedCount = Pets.Count;
|
||||
else
|
||||
PetDisplayedCount.Value = Pets.Count - Pets.Count(m => m.FromMain.Value);
|
||||
PetDisplayedCount = Pets.Count - Pets.Count(m => m.FromMain);
|
||||
}
|
||||
|
||||
public ModInfoModel(ModLoader loader)
|
||||
: this()
|
||||
{
|
||||
SourcePath.Value = loader.ModPath.FullName;
|
||||
Id.Value = loader.Name;
|
||||
DescriptionId.Value = loader.Intro;
|
||||
Author.Value = loader.Author;
|
||||
GameVersion.Value = loader.GameVer;
|
||||
ModVersion.Value = loader.Ver;
|
||||
SourcePath = loader.ModPath.FullName;
|
||||
Id = loader.Name;
|
||||
DescriptionId = loader.Intro;
|
||||
Author = loader.Author;
|
||||
GameVersion = loader.GameVer;
|
||||
ModVersion = loader.Ver;
|
||||
ItemID = loader.ItemID;
|
||||
AuthorID = loader.AuthorID;
|
||||
var imagePath = Path.Combine(loader.ModPath.FullName, "icon.png");
|
||||
if (File.Exists(imagePath))
|
||||
Image.Value = NativeUtils.LoadImageToMemoryStream(imagePath);
|
||||
Image = NativeUtils.LoadImageToMemoryStream(imagePath);
|
||||
foreach (var food in loader.Foods)
|
||||
Foods.Add(new(food));
|
||||
foreach (var clickText in loader.ClickTexts)
|
||||
@ -184,29 +276,29 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
var petModel = new PetModel(pet);
|
||||
// 如果检测到本体存在同名宠物
|
||||
if (ModMakerInfo.MainPets.TryGetValue(petModel.Id.Value, out var mainPet))
|
||||
if (ModMakerInfo.MainPets.TryGetValue(petModel.ID, out var mainPet))
|
||||
{
|
||||
// 若宠物的值为默认值并且本体同名宠物不为默认值, 则把本体宠物的值作为模组宠物的默认值
|
||||
if (
|
||||
petModel.TouchHeadRect == PetModel.Default.TouchHeadRect
|
||||
&& petModel.TouchHeadRect != mainPet.TouchHeadRect
|
||||
)
|
||||
petModel.TouchHeadRect.Value = mainPet.TouchHeadRect.Value;
|
||||
petModel.TouchHeadRect = mainPet.TouchHeadRect;
|
||||
if (
|
||||
petModel.TouchBodyRect == PetModel.Default.TouchBodyRect
|
||||
&& petModel.TouchBodyRect != mainPet.TouchBodyRect
|
||||
)
|
||||
petModel.TouchBodyRect.Value = mainPet.TouchBodyRect.Value;
|
||||
petModel.TouchBodyRect = mainPet.TouchBodyRect;
|
||||
if (
|
||||
petModel.TouchRaisedRect == PetModel.Default.TouchRaisedRect
|
||||
&& petModel.TouchRaisedRect != mainPet.TouchRaisedRect
|
||||
)
|
||||
petModel.TouchRaisedRect.Value = mainPet.TouchRaisedRect.Value;
|
||||
petModel.TouchRaisedRect = mainPet.TouchRaisedRect;
|
||||
if (
|
||||
petModel.RaisePoint == PetModel.Default.RaisePoint
|
||||
&& petModel.RaisePoint != mainPet.RaisePoint
|
||||
)
|
||||
petModel.RaisePoint.Value = mainPet.RaisePoint.Value;
|
||||
petModel.RaisePoint = mainPet.RaisePoint;
|
||||
}
|
||||
Pets.Add(petModel);
|
||||
foreach (var p in pet.path)
|
||||
@ -220,7 +312,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
foreach (var pet in ModMakerInfo.MainPets)
|
||||
{
|
||||
// 确保Id不重复
|
||||
if (Pets.All(i => i.Id.Value != pet.Key))
|
||||
if (Pets.All(i => i.ID != pet.Key))
|
||||
Pets.Insert(0, pet.Value);
|
||||
}
|
||||
|
||||
@ -236,7 +328,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
public void RefreshId()
|
||||
{
|
||||
DescriptionId.Value = $"{Id.Value}_{nameof(DescriptionId)}";
|
||||
DescriptionId = $"{Id}_{nameof(DescriptionId)}";
|
||||
}
|
||||
|
||||
#region Load
|
||||
@ -341,7 +433,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
}
|
||||
if (I18nHelper.Current.CultureNames.Count == 0)
|
||||
return;
|
||||
I18nHelper.Current.CultureName.Value = I18nHelper.Current.CultureNames.First();
|
||||
I18nHelper.Current.CultureName = I18nHelper.Current.CultureNames.First();
|
||||
foreach (var i18nData in OtherI18nDatas)
|
||||
{
|
||||
LoadFoodI18nData(i18nData.Key, i18nData.Value);
|
||||
@ -358,10 +450,10 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
if (food.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(food.Id.Value, out var name))
|
||||
data.Name.Value = name;
|
||||
if (i18nData.TryGetValue(food.DescriptionId.Value, out var description))
|
||||
data.Description.Value = description;
|
||||
if (i18nData.TryGetValue(food.Id, out var name))
|
||||
data.Name = name;
|
||||
if (i18nData.TryGetValue(food.DescriptionId, out var description))
|
||||
data.Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,8 +463,8 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
if (lowText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(lowText.Id.Value, out var text))
|
||||
data.Text.Value = text;
|
||||
if (i18nData.TryGetValue(lowText.Id, out var text))
|
||||
data.Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,8 +474,8 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
if (clickText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(clickText.Id.Value, out var text))
|
||||
data.Text.Value = text;
|
||||
if (i18nData.TryGetValue(clickText.Id, out var text))
|
||||
data.Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,10 +485,10 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
if (selectText.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(selectText.Id.Value, out var text))
|
||||
data.Text.Value = text;
|
||||
if (i18nData.TryGetValue(selectText.ChooseId.Value, out var choose))
|
||||
data.Choose.Value = choose;
|
||||
if (i18nData.TryGetValue(selectText.Id, out var text))
|
||||
data.Text = text;
|
||||
if (i18nData.TryGetValue(selectText.ChooseId, out var choose))
|
||||
data.Choose = choose;
|
||||
}
|
||||
}
|
||||
|
||||
@ -406,18 +498,18 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
{
|
||||
if (pet.I18nDatas.TryGetValue(key, out var data) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(pet.Id.Value, out var name))
|
||||
data.Name.Value = name;
|
||||
if (i18nData.TryGetValue(pet.PetNameId.Value, out var petName))
|
||||
data.PetName.Value = petName;
|
||||
if (i18nData.TryGetValue(pet.DescriptionId.Value, out var description))
|
||||
data.Description.Value = description;
|
||||
if (i18nData.TryGetValue(pet.ID, out var name))
|
||||
data.Name = name;
|
||||
if (i18nData.TryGetValue(pet.PetNameId, out var petName))
|
||||
data.PetName = petName;
|
||||
if (i18nData.TryGetValue(pet.DescriptionId, out var description))
|
||||
data.Description = description;
|
||||
foreach (var work in pet.Works)
|
||||
{
|
||||
if (work.I18nDatas.TryGetValue(key, out var workData) is false)
|
||||
continue;
|
||||
if (i18nData.TryGetValue(work.Id.Value, out var workName))
|
||||
workData.Name.Value = workName;
|
||||
if (i18nData.TryGetValue(work.Id, out var workName))
|
||||
workData.Name = workName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -438,7 +530,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
SaveTo(SourcePath.Value);
|
||||
SaveTo(SourcePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -475,13 +567,13 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
|
||||
var lps = new LPS()
|
||||
{
|
||||
new Line("vupmod", Id.Value)
|
||||
new Line("vupmod", Id)
|
||||
{
|
||||
new Sub("author", Author.Value),
|
||||
new Sub("gamever", GameVersion.Value),
|
||||
new Sub("ver", ModVersion.Value)
|
||||
new Sub("author", Author),
|
||||
new Sub("gamever", GameVersion),
|
||||
new Sub("ver", ModVersion)
|
||||
},
|
||||
new Line("intro", DescriptionId.Value),
|
||||
new Line("intro", DescriptionId),
|
||||
new Line("authorid", AuthorID.ToString()),
|
||||
new Line("itemid", ItemID.ToString()),
|
||||
new Line("cachedate", DateTime.Now.Date.ToString("s"))
|
||||
@ -491,12 +583,12 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
lps.Add(
|
||||
new Line("lang", cultureName)
|
||||
{
|
||||
new Sub(Id.Value, I18nDatas[cultureName].Name.Value),
|
||||
new Sub(DescriptionId.Value, I18nDatas[cultureName].Description.Value),
|
||||
new Sub(Id, I18nDatas[cultureName].Name),
|
||||
new Sub(DescriptionId, I18nDatas[cultureName].Description),
|
||||
}
|
||||
);
|
||||
}
|
||||
Image.Value?.SaveToPng(Path.Combine(path, "icon.png"));
|
||||
Image?.SaveToPng(Path.Combine(path, "icon.png"));
|
||||
File.WriteAllText(modInfoFile, lps.ToString());
|
||||
}
|
||||
|
||||
@ -543,13 +635,9 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(food.ToFood(), "food"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName].TryAdd(food.Id, food.I18nDatas[cultureName].Name);
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(food.Id.Value, food.I18nDatas[cultureName].Name.Value);
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(
|
||||
food.DescriptionId.Value,
|
||||
food.I18nDatas[cultureName].Description.Value
|
||||
);
|
||||
.TryAdd(food.DescriptionId, food.I18nDatas[cultureName].Description);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(foodFile, lps.ToString());
|
||||
@ -591,10 +679,9 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(text.ToSelectText(), "SelectText"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName].TryAdd(text.Id, text.I18nDatas[cultureName].Text);
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(text.Id.Value, text.I18nDatas[cultureName].Text.Value);
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(text.ChooseId.Value, text.I18nDatas[cultureName].Choose.Value);
|
||||
.TryAdd(text.ChooseId, text.I18nDatas[cultureName].Choose);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(textFile, lps.ToString());
|
||||
@ -616,8 +703,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(text.ToLowText(), "lowfoodtext"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(text.Id.Value, text.I18nDatas[cultureName].Text.Value);
|
||||
SaveI18nDatas[cultureName].TryAdd(text.Id, text.I18nDatas[cultureName].Text);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(textFile, lps.ToString());
|
||||
@ -639,8 +725,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
lps.Add(LPSConvert.SerializeObjectToLine<Line>(text.ToClickText(), "clicktext"));
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
SaveI18nDatas[cultureName]
|
||||
.TryAdd(text.Id.Value, text.I18nDatas[cultureName].Text.Value);
|
||||
SaveI18nDatas[cultureName].TryAdd(text.Id, text.I18nDatas[cultureName].Text);
|
||||
}
|
||||
}
|
||||
File.WriteAllText(textFile, lps.ToString());
|
||||
@ -683,7 +768,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
Directory.CreateDirectory(foodPath);
|
||||
foreach (var food in Foods)
|
||||
{
|
||||
food.Image.Value.SaveToPng(Path.Combine(foodPath, food.Id.Value));
|
||||
food.Image.SaveToPng(Path.Combine(foodPath, food.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -693,7 +778,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
Image.Value.CloseStream();
|
||||
Image.CloseStream();
|
||||
foreach (var food in Foods)
|
||||
food.Close();
|
||||
foreach (var pet in Pets)
|
||||
@ -715,20 +800,39 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
||||
var cultureFile = Path.Combine(culturePath, $"{cultureName}.lps");
|
||||
File.Create(cultureFile).Close();
|
||||
var lps = new LPS();
|
||||
foreach (var data in I18nEditWindow.Current.ViewModel.AllI18nDatas)
|
||||
lps.Add(
|
||||
new Line(
|
||||
data.Key,
|
||||
data.Value.Datas[I18nHelper.Current.CultureNames.IndexOf(cultureName)].Value
|
||||
)
|
||||
);
|
||||
//TODO
|
||||
//foreach (var data in I18nEditWindow.Current.ViewModel.AllI18nDatas)
|
||||
// lps.Add(
|
||||
// new Line(
|
||||
// data.Key,
|
||||
// data.Value.Datas[I18nHelper.Current.CultureNames.IndexOf(cultureName)].Value
|
||||
// )
|
||||
// );
|
||||
File.WriteAllText(cultureFile, lps.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nModInfoModel
|
||||
public class I18nModInfoModel : ObservableObjectX<I18nModInfoModel>
|
||||
{
|
||||
public ObservableValue<string> Name { get; set; } = new();
|
||||
public ObservableValue<string> Description { get; set; } = new();
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
#region Description
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _description = string.Empty;
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
@ -12,7 +13,7 @@ namespace VPet.ModMaker.Models;
|
||||
/// <summary>
|
||||
/// 移动模型
|
||||
/// </summary>
|
||||
public class MoveModel
|
||||
public class MoveModel : ObservableObjectX<MoveModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// 移动类型
|
||||
@ -29,93 +30,224 @@ public class MoveModel
|
||||
public static ObservableCollection<GraphHelper.Move.ModeType> ModeTypes { get; } =
|
||||
new(Enum.GetValues(typeof(GraphHelper.Move.ModeType)).Cast<GraphHelper.Move.ModeType>());
|
||||
|
||||
//public ObservableValue<string> Id { get; } = new();
|
||||
//#region Id
|
||||
//[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
//private string _Id;
|
||||
|
||||
//public string Id { get => _Id; set => SetProperty(ref _Id, value); }
|
||||
//#endregion
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph;
|
||||
|
||||
/// <summary>
|
||||
/// 指定动画
|
||||
/// </summary>
|
||||
public ObservableValue<string> Graph { get; } = new();
|
||||
public string Graph
|
||||
{
|
||||
get => _graph;
|
||||
set => SetProperty(ref _graph, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Distance
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _distance;
|
||||
|
||||
/// <summary>
|
||||
/// 移动距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> Distance { get; } = new(5);
|
||||
public int Distance
|
||||
{
|
||||
get => _distance;
|
||||
set => SetProperty(ref _distance, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Interval
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _interval;
|
||||
|
||||
/// <summary>
|
||||
/// 间隔
|
||||
/// </summary>
|
||||
public ObservableValue<int> Interval { get; } = new(125);
|
||||
public int Interval
|
||||
{
|
||||
get => _interval;
|
||||
set => SetProperty(ref _interval, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LocateLength
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _locateLength;
|
||||
|
||||
/// <summary>
|
||||
/// 定位长度
|
||||
/// </summary>
|
||||
public ObservableValue<int> LocateLength { get; } = new();
|
||||
public int LocateLength
|
||||
{
|
||||
get => _locateLength;
|
||||
set => SetProperty(ref _locateLength, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SpeedX
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _speedX;
|
||||
|
||||
/// <summary>
|
||||
/// X速度
|
||||
/// </summary>
|
||||
public ObservableValue<int> SpeedX { get; } = new();
|
||||
public int SpeedX
|
||||
{
|
||||
get => _speedX;
|
||||
set => SetProperty(ref _speedX, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SpeedY
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _speedY;
|
||||
|
||||
/// <summary>
|
||||
/// Y速度
|
||||
/// </summary>
|
||||
public ObservableValue<int> SpeedY { get; } = new();
|
||||
public int SpeedY
|
||||
{
|
||||
get => _speedY;
|
||||
set => SetProperty(ref _speedY, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CheckLeft
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _checkLeft;
|
||||
|
||||
/// <summary>
|
||||
/// 左侧检测距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> CheckLeft { get; } = new(100);
|
||||
public int CheckLeft
|
||||
{
|
||||
get => _checkLeft;
|
||||
set => SetProperty(ref _checkLeft, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CheckRight
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _checkRight;
|
||||
|
||||
/// <summary>
|
||||
/// 右侧检测距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> CheckRight { get; } = new(100);
|
||||
public int CheckRight
|
||||
{
|
||||
get => _checkRight;
|
||||
set => SetProperty(ref _checkRight, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CheckTop
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _checkTop;
|
||||
|
||||
/// <summary>
|
||||
/// 上方检测距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> CheckTop { get; } = new(100);
|
||||
public int CheckTop
|
||||
{
|
||||
get => _checkTop;
|
||||
set => SetProperty(ref _checkTop, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CheckBottom
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _checkBottom;
|
||||
|
||||
/// <summary>
|
||||
/// 下方检测距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> CheckBottom { get; } = new(100);
|
||||
public int CheckBottom
|
||||
{
|
||||
get => _checkBottom;
|
||||
set => SetProperty(ref _checkBottom, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TriggerLeft
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _triggerLeft;
|
||||
|
||||
/// <summary>
|
||||
/// 左侧触发距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> TriggerLeft { get; } = new(100);
|
||||
public int TriggerLeft
|
||||
{
|
||||
get => _triggerLeft;
|
||||
set => SetProperty(ref _triggerLeft, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TriggerRight
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _triggerRight;
|
||||
|
||||
/// <summary>
|
||||
/// 右侧触发距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> TriggerRight { get; } = new(100);
|
||||
public int TriggerRight
|
||||
{
|
||||
get => _triggerRight;
|
||||
set => SetProperty(ref _triggerRight, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TriggerTop
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _triggerTop;
|
||||
|
||||
/// <summary>
|
||||
/// 上方触发距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> TriggerTop { get; } = new(100);
|
||||
public int TriggerTop
|
||||
{
|
||||
get => _triggerTop;
|
||||
set => SetProperty(ref _triggerTop, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TriggerBottom
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _triggerBottom;
|
||||
|
||||
/// <summary>
|
||||
/// 下方触发距离
|
||||
/// </summary>
|
||||
public ObservableValue<int> TriggerBottom { get; } = new(100);
|
||||
public int TriggerBottom
|
||||
{
|
||||
get => _triggerBottom;
|
||||
set => SetProperty(ref _triggerBottom, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 定位类型
|
||||
/// </summary>
|
||||
public ObservableEnumFlags<GraphHelper.Move.DirectionType> LocateType { get; } =
|
||||
public ObservableEnumCommand<GraphHelper.Move.DirectionType> LocateType { get; } =
|
||||
new(GraphHelper.Move.DirectionType.None);
|
||||
|
||||
/// <summary>
|
||||
/// 触发类型
|
||||
/// </summary>
|
||||
public ObservableEnumFlags<GraphHelper.Move.DirectionType> TriggerType { get; } =
|
||||
public ObservableEnumCommand<GraphHelper.Move.DirectionType> TriggerType { get; } =
|
||||
new(GraphHelper.Move.DirectionType.None);
|
||||
|
||||
/// <summary>
|
||||
/// 模式
|
||||
/// </summary>
|
||||
public ObservableEnumFlags<GraphHelper.Move.ModeType> ModeType { get; } =
|
||||
public ObservableEnumCommand<GraphHelper.Move.ModeType> ModeType { get; } =
|
||||
new(
|
||||
GraphHelper.Move.ModeType.Happy
|
||||
| GraphHelper.Move.ModeType.Nomal
|
||||
@ -129,69 +261,69 @@ public class MoveModel
|
||||
: this()
|
||||
{
|
||||
//Id.EnumValue = model.Id.EnumValue;
|
||||
Graph.Value = model.Graph.Value;
|
||||
Distance.Value = model.Distance.Value;
|
||||
Interval.Value = model.Interval.Value;
|
||||
CheckLeft.Value = model.CheckLeft.Value;
|
||||
CheckRight.Value = model.CheckRight.Value;
|
||||
CheckTop.Value = model.CheckTop.Value;
|
||||
CheckBottom.Value = model.CheckBottom.Value;
|
||||
SpeedX.Value = model.SpeedX.Value;
|
||||
SpeedY.Value = model.SpeedY.Value;
|
||||
LocateLength.Value = model.LocateLength.Value;
|
||||
TriggerLeft.Value = model.TriggerLeft.Value;
|
||||
TriggerRight.Value = model.TriggerRight.Value;
|
||||
TriggerTop.Value = model.TriggerTop.Value;
|
||||
TriggerBottom.Value = model.TriggerBottom.Value;
|
||||
LocateType.EnumValue.Value = model.LocateType.EnumValue.Value;
|
||||
TriggerType.EnumValue.Value = model.TriggerType.EnumValue.Value;
|
||||
ModeType.EnumValue.Value = model.ModeType.EnumValue.Value;
|
||||
Graph = model.Graph;
|
||||
Distance = model.Distance;
|
||||
Interval = model.Interval;
|
||||
CheckLeft = model.CheckLeft;
|
||||
CheckRight = model.CheckRight;
|
||||
CheckTop = model.CheckTop;
|
||||
CheckBottom = model.CheckBottom;
|
||||
SpeedX = model.SpeedX;
|
||||
SpeedY = model.SpeedY;
|
||||
LocateLength = model.LocateLength;
|
||||
TriggerLeft = model.TriggerLeft;
|
||||
TriggerRight = model.TriggerRight;
|
||||
TriggerTop = model.TriggerTop;
|
||||
TriggerBottom = model.TriggerBottom;
|
||||
LocateType.Value = model.LocateType.Value;
|
||||
TriggerType.Value = model.TriggerType.Value;
|
||||
ModeType.Value = model.ModeType.Value;
|
||||
}
|
||||
|
||||
public MoveModel(GraphHelper.Move move)
|
||||
: this()
|
||||
{
|
||||
//Id.EnumValue = move.Id.EnumValue;
|
||||
Graph.Value = move.Graph;
|
||||
Distance.Value = move.Distance;
|
||||
Interval.Value = move.Interval;
|
||||
CheckLeft.Value = move.CheckLeft;
|
||||
CheckRight.Value = move.CheckRight;
|
||||
CheckTop.Value = move.CheckTop;
|
||||
CheckBottom.Value = move.CheckBottom;
|
||||
SpeedX.Value = move.SpeedX;
|
||||
SpeedY.Value = move.SpeedY;
|
||||
LocateLength.Value = move.LocateLength;
|
||||
TriggerLeft.Value = move.TriggerLeft;
|
||||
TriggerRight.Value = move.TriggerRight;
|
||||
TriggerTop.Value = move.TriggerTop;
|
||||
TriggerBottom.Value = move.TriggerBottom;
|
||||
LocateType.EnumValue.Value = move.LocateType;
|
||||
TriggerType.EnumValue.Value = move.TriggerType;
|
||||
ModeType.EnumValue.Value = move.Mode;
|
||||
Graph = move.Graph;
|
||||
Distance = move.Distance;
|
||||
Interval = move.Interval;
|
||||
CheckLeft = move.CheckLeft;
|
||||
CheckRight = move.CheckRight;
|
||||
CheckTop = move.CheckTop;
|
||||
CheckBottom = move.CheckBottom;
|
||||
SpeedX = move.SpeedX;
|
||||
SpeedY = move.SpeedY;
|
||||
LocateLength = move.LocateLength;
|
||||
TriggerLeft = move.TriggerLeft;
|
||||
TriggerRight = move.TriggerRight;
|
||||
TriggerTop = move.TriggerTop;
|
||||
TriggerBottom = move.TriggerBottom;
|
||||
LocateType.Value = move.LocateType;
|
||||
TriggerType.Value = move.TriggerType;
|
||||
ModeType.Value = move.Mode;
|
||||
}
|
||||
|
||||
public GraphHelper.Move ToMove()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Graph = Graph.Value,
|
||||
Distance = Distance.Value,
|
||||
Interval = Interval.Value,
|
||||
CheckLeft = CheckLeft.Value,
|
||||
CheckRight = CheckRight.Value,
|
||||
CheckTop = CheckTop.Value,
|
||||
CheckBottom = CheckBottom.Value,
|
||||
SpeedX = SpeedX.Value,
|
||||
SpeedY = SpeedY.Value,
|
||||
LocateLength = LocateLength.Value,
|
||||
TriggerLeft = TriggerLeft.Value,
|
||||
TriggerRight = TriggerRight.Value,
|
||||
TriggerTop = TriggerTop.Value,
|
||||
TriggerBottom = TriggerBottom.Value,
|
||||
LocateType = LocateType.EnumValue.Value,
|
||||
TriggerType = TriggerType.EnumValue.Value,
|
||||
Mode = ModeType.EnumValue.Value,
|
||||
Graph = Graph,
|
||||
Distance = Distance,
|
||||
Interval = Interval,
|
||||
CheckLeft = CheckLeft,
|
||||
CheckRight = CheckRight,
|
||||
CheckTop = CheckTop,
|
||||
CheckBottom = CheckBottom,
|
||||
SpeedX = SpeedX,
|
||||
SpeedY = SpeedY,
|
||||
LocateLength = LocateLength,
|
||||
TriggerLeft = TriggerLeft,
|
||||
TriggerRight = TriggerRight,
|
||||
TriggerTop = TriggerTop,
|
||||
TriggerBottom = TriggerBottom,
|
||||
LocateType = LocateType.Value,
|
||||
TriggerType = TriggerType.Value,
|
||||
Mode = ModeType.Value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -24,56 +25,123 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
public static PetModel Default { get; } = new();
|
||||
|
||||
#region FromMain
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _fromMain;
|
||||
|
||||
/// <summary>
|
||||
/// 来自本体
|
||||
/// </summary>
|
||||
public ObservableValue<bool> FromMain { get; } = new(false);
|
||||
public bool FromMain
|
||||
{
|
||||
get => _fromMain;
|
||||
set => SetProperty(ref _fromMain, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
#region PetNameId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _petNameId;
|
||||
|
||||
/// <summary>
|
||||
/// 名称Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> PetNameId { get; } = new();
|
||||
public string PetNameId
|
||||
{
|
||||
get => _petNameId;
|
||||
set => SetProperty(ref _petNameId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DescriptionId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _descriptionId;
|
||||
|
||||
/// <summary>
|
||||
/// 描述Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> DescriptionId { get; } = new();
|
||||
public string DescriptionId
|
||||
{
|
||||
get => _descriptionId;
|
||||
set => SetProperty(ref _descriptionId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TouchHeadRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _touchHeadRect = new(159, 16, 189, 178);
|
||||
|
||||
/// <summary>
|
||||
/// 头部点击区域
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableRect<double>> TouchHeadRect { get; } =
|
||||
new(new(159, 16, 189, 178));
|
||||
public ObservableRectangleLocation<double> TouchHeadRect
|
||||
{
|
||||
get => _touchHeadRect;
|
||||
set => SetProperty(ref _touchHeadRect, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TouchBodyRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _touchBodyRect = new(166, 206, 163, 136);
|
||||
|
||||
/// <summary>
|
||||
/// 身体区域
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableRect<double>> TouchBodyRect { get; } =
|
||||
new(new(166, 206, 163, 136));
|
||||
public ObservableRectangleLocation<double> TouchBodyRect
|
||||
{
|
||||
get => _touchBodyRect;
|
||||
set => SetProperty(ref _touchBodyRect, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 提起区域
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableMultiStateRect> TouchRaisedRect { get; } =
|
||||
#region TouchRaisedRect
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableMultiStateRect _touchRaisedRect =
|
||||
new(
|
||||
new(
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 200, 500, 300)
|
||||
)
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 50, 500, 200),
|
||||
new(0, 200, 500, 300)
|
||||
);
|
||||
|
||||
public ObservableMultiStateRect TouchRaisedRect
|
||||
{
|
||||
get => _touchRaisedRect;
|
||||
set => SetProperty(ref _touchRaisedRect, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RaisePoint
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableMultiStatePoint _raisePoint =
|
||||
new(new(290, 128), new(290, 128), new(290, 128), new(225, 115));
|
||||
|
||||
/// <summary>
|
||||
/// 提起定位
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableMultiStatePoint> RaisePoint { get; } =
|
||||
new(new(new(290, 128), new(290, 128), new(290, 128), new(225, 115)));
|
||||
public ObservableMultiStatePoint RaisePoint
|
||||
{
|
||||
get => _raisePoint;
|
||||
set => SetProperty(ref _raisePoint, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 工作
|
||||
@ -95,97 +163,107 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
/// </summary>
|
||||
public ObservableCollection<FoodAnimeTypeModel> FoodAnimes { get; } = new();
|
||||
|
||||
public ObservableValue<int> AnimeCount { get; } = new();
|
||||
#region AnimeCount
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _AnimeCount;
|
||||
|
||||
public int AnimeCount
|
||||
{
|
||||
get => _AnimeCount;
|
||||
set => SetProperty(ref _AnimeCount, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public PetModel()
|
||||
{
|
||||
PetNameId.Value = $"{Id.Value}_{nameof(PetNameId)}";
|
||||
DescriptionId.Value = $"{Id.Value}_{nameof(DescriptionId)}";
|
||||
Id.ValueChanged += (s, e) =>
|
||||
{
|
||||
PetNameId.Value = $"{e.NewValue}_{nameof(PetNameId)}";
|
||||
DescriptionId.Value = $"{e.NewValue}_{nameof(DescriptionId)}";
|
||||
};
|
||||
AnimeCount.AddNotifySender(Animes);
|
||||
AnimeCount.AddNotifySender(FoodAnimes);
|
||||
AnimeCount.SenderPropertyChanged += (s, _) =>
|
||||
{
|
||||
s.Value = Animes.Count + FoodAnimes.Count;
|
||||
};
|
||||
PetNameId = $"{ID}_{nameof(PetNameId)}";
|
||||
DescriptionId = $"{ID}_{nameof(DescriptionId)}";
|
||||
//TODO
|
||||
//ID.ValueChanged += (s, e) =>
|
||||
//{
|
||||
// PetNameId = $"{e.NewValue}_{nameof(PetNameId)}";
|
||||
// DescriptionId = $"{e.NewValue}_{nameof(DescriptionId)}";
|
||||
//};
|
||||
//AnimeCount.AddNotifySender(Animes);
|
||||
//AnimeCount.AddNotifySender(FoodAnimes);
|
||||
//AnimeCount.SenderPropertyChanged += (s, _) =>
|
||||
//{
|
||||
// s.Value = Animes.Count + FoodAnimes.Count;
|
||||
//};
|
||||
}
|
||||
|
||||
public PetModel(PetModel model)
|
||||
: this()
|
||||
{
|
||||
Id.Value = model.Id.Value;
|
||||
PetNameId.Value = model.PetNameId.Value;
|
||||
TouchHeadRect.Value = model.TouchHeadRect.Value.Copy();
|
||||
TouchBodyRect.Value = model.TouchBodyRect.Value.Copy();
|
||||
TouchRaisedRect.Value = model.TouchRaisedRect.Value.Copy();
|
||||
RaisePoint.Value = model.RaisePoint.Value.Copy();
|
||||
ID = model.ID;
|
||||
PetNameId = model.PetNameId;
|
||||
TouchHeadRect = model.TouchHeadRect.Clone();
|
||||
TouchBodyRect = model.TouchBodyRect.Clone();
|
||||
TouchRaisedRect = model.TouchRaisedRect.Copy();
|
||||
RaisePoint = model.RaisePoint.Copy();
|
||||
foreach (var work in model.Works)
|
||||
Works.Add(work);
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public PetModel(PetLoader loader, bool fromMain = false)
|
||||
: this()
|
||||
{
|
||||
Id.Value = loader.Name;
|
||||
PetNameId.Value = loader.PetName;
|
||||
DescriptionId.Value = loader.Intor;
|
||||
ID = loader.Name;
|
||||
PetNameId = loader.PetName;
|
||||
DescriptionId = loader.Intor;
|
||||
|
||||
TouchHeadRect.Value = new(
|
||||
TouchHeadRect = new(
|
||||
loader.Config.TouchHeadLocate.X,
|
||||
loader.Config.TouchHeadLocate.Y,
|
||||
loader.Config.TouchHeadSize.Width,
|
||||
loader.Config.TouchHeadSize.Height
|
||||
);
|
||||
|
||||
TouchBodyRect.Value = new(
|
||||
TouchBodyRect = new(
|
||||
loader.Config.TouchBodyLocate.X,
|
||||
loader.Config.TouchBodyLocate.Y,
|
||||
loader.Config.TouchBodySize.Width,
|
||||
loader.Config.TouchBodySize.Height
|
||||
);
|
||||
|
||||
TouchRaisedRect.Value.Happy = new(
|
||||
TouchRaisedRect.Happy = new(
|
||||
loader.Config.TouchRaisedLocate[0].X,
|
||||
loader.Config.TouchRaisedLocate[0].Y,
|
||||
loader.Config.TouchRaisedSize[0].Width,
|
||||
loader.Config.TouchRaisedSize[0].Height
|
||||
);
|
||||
TouchRaisedRect.Value.Nomal = new(
|
||||
TouchRaisedRect.Nomal = new(
|
||||
loader.Config.TouchRaisedLocate[1].X,
|
||||
loader.Config.TouchRaisedLocate[1].Y,
|
||||
loader.Config.TouchRaisedSize[1].Width,
|
||||
loader.Config.TouchRaisedSize[1].Height
|
||||
);
|
||||
TouchRaisedRect.Value.PoorCondition = new(
|
||||
TouchRaisedRect.PoorCondition = new(
|
||||
loader.Config.TouchRaisedLocate[2].X,
|
||||
loader.Config.TouchRaisedLocate[2].Y,
|
||||
loader.Config.TouchRaisedSize[2].Width,
|
||||
loader.Config.TouchRaisedSize[2].Height
|
||||
);
|
||||
TouchRaisedRect.Value.Ill = new(
|
||||
TouchRaisedRect.Ill = new(
|
||||
loader.Config.TouchRaisedLocate[3].X,
|
||||
loader.Config.TouchRaisedLocate[3].Y,
|
||||
loader.Config.TouchRaisedSize[3].Width,
|
||||
loader.Config.TouchRaisedSize[3].Height
|
||||
);
|
||||
|
||||
RaisePoint.Value.Happy = new(loader.Config.RaisePoint[0].X, loader.Config.RaisePoint[0].Y);
|
||||
RaisePoint.Value.Nomal = new(loader.Config.RaisePoint[1].X, loader.Config.RaisePoint[1].Y);
|
||||
RaisePoint.Value.PoorCondition = new(
|
||||
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.Value.Ill = new(loader.Config.RaisePoint[3].X, loader.Config.RaisePoint[3].Y);
|
||||
RaisePoint.Ill = new(loader.Config.RaisePoint[3].X, loader.Config.RaisePoint[3].Y);
|
||||
// 如果这个宠物数据来自本体, 则不载入 Work 和 Move
|
||||
if (FromMain.Value = fromMain)
|
||||
if (FromMain = fromMain)
|
||||
return;
|
||||
|
||||
foreach (var work in loader.Config.Works)
|
||||
@ -196,8 +274,8 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
|
||||
public void RefreshId()
|
||||
{
|
||||
PetNameId.Value = $"{Id.Value}_{nameof(PetNameId)}";
|
||||
DescriptionId.Value = $"{Id.Value}_{nameof(DescriptionId)}";
|
||||
PetNameId = $"{ID}_{nameof(PetNameId)}";
|
||||
DescriptionId = $"{ID}_{nameof(DescriptionId)}";
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@ -217,7 +295,7 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
public bool CanSave()
|
||||
{
|
||||
if (
|
||||
FromMain.Value
|
||||
FromMain
|
||||
&& Works.Count == 0
|
||||
&& Moves.Count == 0
|
||||
&& Animes.Count == 0
|
||||
@ -235,22 +313,20 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
foreach (var cultureName in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
ModInfoModel.SaveI18nDatas[cultureName].TryAdd(ID, I18nDatas[cultureName].Name);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(Id.Value, I18nDatas[cultureName].Name.Value);
|
||||
.TryAdd(PetNameId, I18nDatas[cultureName].PetName);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(PetNameId.Value, I18nDatas[cultureName].PetName.Value);
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(DescriptionId.Value, I18nDatas[cultureName].Description.Value);
|
||||
.TryAdd(DescriptionId, I18nDatas[cultureName].Description);
|
||||
}
|
||||
var petFile = Path.Combine(path, $"{Id.Value}.lps");
|
||||
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.Value, out var mainPet))
|
||||
if (ModMakerInfo.MainPets.TryGetValue(ID, out var mainPet))
|
||||
SaveDifferentPetInfo(lps, mainPet);
|
||||
else
|
||||
SavePetInfo(lps);
|
||||
@ -264,7 +340,7 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
|
||||
private void SaveAnime(string path)
|
||||
{
|
||||
var petAnimePath = Path.Combine(path, Id.Value);
|
||||
var petAnimePath = Path.Combine(path, ID);
|
||||
foreach (var anime in Animes)
|
||||
anime.Save(petAnimePath);
|
||||
foreach (var anime in FoodAnimes)
|
||||
@ -298,7 +374,7 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
{
|
||||
ModInfoModel
|
||||
.SaveI18nDatas[cultureName]
|
||||
.TryAdd(work.Id.Value, work.I18nDatas[cultureName].Name.Value);
|
||||
.TryAdd(work.Id, work.I18nDatas[cultureName].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -345,11 +421,11 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
private void SavePetBasicInfo(LPS lps)
|
||||
{
|
||||
lps.Add(
|
||||
new Line("pet", Id.Value)
|
||||
new Line("pet", ID)
|
||||
{
|
||||
new Sub("intor", DescriptionId.Value),
|
||||
new Sub("path", Id.Value),
|
||||
new Sub("petname", PetNameId.Value)
|
||||
new Sub("intor", DescriptionId),
|
||||
new Sub("path", ID),
|
||||
new Sub("petname", PetNameId)
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -359,10 +435,10 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("touchhead")
|
||||
{
|
||||
new Sub("px", TouchHeadRect.Value.X),
|
||||
new Sub("py", TouchHeadRect.Value.Y),
|
||||
new Sub("sw", TouchHeadRect.Value.Width),
|
||||
new Sub("sh", TouchHeadRect.Value.Height),
|
||||
new Sub("px", TouchHeadRect.X),
|
||||
new Sub("py", TouchHeadRect.Y),
|
||||
new Sub("sw", TouchHeadRect.Width),
|
||||
new Sub("sh", TouchHeadRect.Height),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -372,10 +448,10 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("touchbody")
|
||||
{
|
||||
new Sub("px", TouchBodyRect.Value.X),
|
||||
new Sub("py", TouchBodyRect.Value.Y),
|
||||
new Sub("sw", TouchBodyRect.Value.Width),
|
||||
new Sub("sh", TouchBodyRect.Value.Height),
|
||||
new Sub("px", TouchBodyRect.X),
|
||||
new Sub("py", TouchBodyRect.Y),
|
||||
new Sub("sw", TouchBodyRect.Width),
|
||||
new Sub("sh", TouchBodyRect.Height),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -385,25 +461,25 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("touchraised")
|
||||
{
|
||||
new Sub("happy_px", TouchRaisedRect.Value.Happy.X),
|
||||
new Sub("happy_py", TouchRaisedRect.Value.Happy.Y),
|
||||
new Sub("happy_sw", TouchRaisedRect.Value.Happy.Width),
|
||||
new Sub("happy_sh", TouchRaisedRect.Value.Happy.Height),
|
||||
new Sub("happy_px", TouchRaisedRect.Happy.X),
|
||||
new Sub("happy_py", TouchRaisedRect.Happy.Y),
|
||||
new Sub("happy_sw", TouchRaisedRect.Happy.Width),
|
||||
new Sub("happy_sh", TouchRaisedRect.Happy.Height),
|
||||
//
|
||||
new Sub("nomal_px", TouchRaisedRect.Value.Nomal.X),
|
||||
new Sub("nomal_py", TouchRaisedRect.Value.Nomal.Y),
|
||||
new Sub("nomal_sw", TouchRaisedRect.Value.Nomal.Width),
|
||||
new Sub("nomal_sh", TouchRaisedRect.Value.Nomal.Height),
|
||||
new Sub("nomal_px", TouchRaisedRect.Nomal.X),
|
||||
new Sub("nomal_py", TouchRaisedRect.Nomal.Y),
|
||||
new Sub("nomal_sw", TouchRaisedRect.Nomal.Width),
|
||||
new Sub("nomal_sh", TouchRaisedRect.Nomal.Height),
|
||||
//
|
||||
new Sub("poorcondition_px", TouchRaisedRect.Value.PoorCondition.X),
|
||||
new Sub("poorcondition_py", TouchRaisedRect.Value.PoorCondition.Y),
|
||||
new Sub("poorcondition_sw", TouchRaisedRect.Value.PoorCondition.Width),
|
||||
new Sub("poorcondition_sh", TouchRaisedRect.Value.PoorCondition.Height),
|
||||
new Sub("poorcondition_px", TouchRaisedRect.PoorCondition.X),
|
||||
new Sub("poorcondition_py", TouchRaisedRect.PoorCondition.Y),
|
||||
new Sub("poorcondition_sw", TouchRaisedRect.PoorCondition.Width),
|
||||
new Sub("poorcondition_sh", TouchRaisedRect.PoorCondition.Height),
|
||||
//
|
||||
new Sub("ill_px", TouchRaisedRect.Value.Ill.X),
|
||||
new Sub("ill_py", TouchRaisedRect.Value.Ill.Y),
|
||||
new Sub("ill_sw", TouchRaisedRect.Value.Ill.Width),
|
||||
new Sub("ill_sh", TouchRaisedRect.Value.Ill.Height),
|
||||
new Sub("ill_px", TouchRaisedRect.Ill.X),
|
||||
new Sub("ill_py", TouchRaisedRect.Ill.Y),
|
||||
new Sub("ill_sw", TouchRaisedRect.Ill.Width),
|
||||
new Sub("ill_sh", TouchRaisedRect.Ill.Height),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -413,17 +489,17 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
lps.Add(
|
||||
new Line("raisepoint")
|
||||
{
|
||||
new Sub("happy_x", RaisePoint.Value.Happy.X),
|
||||
new Sub("happy_y", RaisePoint.Value.Happy.Y),
|
||||
new Sub("happy_x", RaisePoint.Happy.X),
|
||||
new Sub("happy_y", RaisePoint.Happy.Y),
|
||||
//
|
||||
new Sub("nomal_x", RaisePoint.Value.Nomal.X),
|
||||
new Sub("nomal_y", RaisePoint.Value.Nomal.Y),
|
||||
new Sub("nomal_x", RaisePoint.Nomal.X),
|
||||
new Sub("nomal_y", RaisePoint.Nomal.Y),
|
||||
//
|
||||
new Sub("poorcondition_x", RaisePoint.Value.PoorCondition.X),
|
||||
new Sub("poorcondition_y", RaisePoint.Value.PoorCondition.Y),
|
||||
new Sub("poorcondition_x", RaisePoint.PoorCondition.X),
|
||||
new Sub("poorcondition_y", RaisePoint.PoorCondition.Y),
|
||||
//
|
||||
new Sub("ill_x", RaisePoint.Value.Ill.X),
|
||||
new Sub("ill_y", RaisePoint.Value.Ill.Y),
|
||||
new Sub("ill_x", RaisePoint.Ill.X),
|
||||
new Sub("ill_y", RaisePoint.Ill.Y),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -431,50 +507,93 @@ public class PetModel : I18nModel<I18nPetInfoModel>
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class I18nPetInfoModel
|
||||
public class I18nPetInfoModel : ObservableObjectX<I18nPetInfoModel>
|
||||
{
|
||||
public ObservableValue<string> Name { get; } = new();
|
||||
public ObservableValue<string> PetName { get; } = new();
|
||||
public ObservableValue<string> Description { get; } = new();
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name = string.Empty;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
#region PetName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _petName = string.Empty;
|
||||
|
||||
public string PetName
|
||||
{
|
||||
get => _petName;
|
||||
set => SetProperty(ref _petName, value);
|
||||
}
|
||||
#endregion
|
||||
#region Description
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _description = string.Empty;
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nPetInfoModel Copy()
|
||||
{
|
||||
var result = new I18nPetInfoModel();
|
||||
result.Name.Value = Name.Value;
|
||||
result.PetName.Value = PetName.Value;
|
||||
result.Description.Value = Description.Value;
|
||||
result.Name = Name;
|
||||
result.PetName = PetName;
|
||||
result.Description = Description;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class ObservableMultiStateRect
|
||||
: ObservableClass<ObservableMultiStateRect>,
|
||||
: ObservableObjectX<ObservableMultiStateRect>,
|
||||
IEquatable<ObservableMultiStateRect>
|
||||
{
|
||||
private ObservableRect<double> _happy;
|
||||
public ObservableRect<double> Happy
|
||||
#region Happy
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _happy;
|
||||
public ObservableRectangleLocation<double> Happy
|
||||
{
|
||||
get => _happy;
|
||||
set => SetProperty(ref _happy, value);
|
||||
}
|
||||
private ObservableRect<double> _nomal;
|
||||
public ObservableRect<double> Nomal
|
||||
#endregion
|
||||
|
||||
#region Nomal
|
||||
private ObservableRectangleLocation<double> _nomal;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
public ObservableRectangleLocation<double> Nomal
|
||||
{
|
||||
get => _nomal;
|
||||
set => SetProperty(ref _nomal, value);
|
||||
}
|
||||
private ObservableRect<double> _poorCondition;
|
||||
public ObservableRect<double> PoorCondition
|
||||
#endregion
|
||||
|
||||
#region PoorCondition
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _poorCondition;
|
||||
public ObservableRectangleLocation<double> PoorCondition
|
||||
{
|
||||
get => _poorCondition;
|
||||
set => SetProperty(ref _poorCondition, value);
|
||||
}
|
||||
private ObservableRect<double> _ill;
|
||||
public ObservableRect<double> Ill
|
||||
#endregion
|
||||
|
||||
#region Ill
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableRectangleLocation<double> _ill;
|
||||
public ObservableRectangleLocation<double> Ill
|
||||
{
|
||||
get => _ill;
|
||||
set => SetProperty(ref _ill, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableMultiStateRect()
|
||||
{
|
||||
@ -485,10 +604,10 @@ public class ObservableMultiStateRect
|
||||
}
|
||||
|
||||
public ObservableMultiStateRect(
|
||||
ObservableRect<double> happy,
|
||||
ObservableRect<double> nomal,
|
||||
ObservableRect<double> poorCondition,
|
||||
ObservableRect<double> ill
|
||||
ObservableRectangleLocation<double> happy,
|
||||
ObservableRectangleLocation<double> nomal,
|
||||
ObservableRectangleLocation<double> poorCondition,
|
||||
ObservableRectangleLocation<double> ill
|
||||
)
|
||||
{
|
||||
Happy = happy;
|
||||
@ -501,10 +620,10 @@ public class ObservableMultiStateRect
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Happy = Happy.Copy(),
|
||||
Nomal = Nomal.Copy(),
|
||||
PoorCondition = PoorCondition.Copy(),
|
||||
Ill = Ill.Copy(),
|
||||
Happy = Happy.Clone(),
|
||||
Nomal = Nomal.Clone(),
|
||||
PoorCondition = PoorCondition.Clone(),
|
||||
Ill = Ill.Clone(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -520,13 +639,19 @@ public class ObservableMultiStateRect
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservableMultiStateRect temp
|
||||
&& EqualityComparer<ObservableRect<double>>.Default.Equals(Happy, temp.Happy)
|
||||
&& EqualityComparer<ObservableRect<double>>.Default.Equals(Nomal, temp.Nomal)
|
||||
&& EqualityComparer<ObservableRect<double>>.Default.Equals(
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(
|
||||
Happy,
|
||||
temp.Happy
|
||||
)
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(
|
||||
Nomal,
|
||||
temp.Nomal
|
||||
)
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(
|
||||
PoorCondition,
|
||||
temp.PoorCondition
|
||||
)
|
||||
&& EqualityComparer<ObservableRect<double>>.Default.Equals(Ill, temp.Ill);
|
||||
&& EqualityComparer<ObservableRectangleLocation<double>>.Default.Equals(Ill, temp.Ill);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@ -551,34 +676,48 @@ public class ObservableMultiStateRect
|
||||
}
|
||||
|
||||
public class ObservableMultiStatePoint
|
||||
: ObservableClass<ObservableMultiStatePoint>,
|
||||
: ObservableObjectX<ObservableMultiStatePoint>,
|
||||
IEquatable<ObservableMultiStatePoint>
|
||||
{
|
||||
#region Happy
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _happy;
|
||||
public ObservablePoint<double> Happy
|
||||
{
|
||||
get => _happy;
|
||||
set => SetProperty(ref _happy, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Nomal
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _nomal;
|
||||
public ObservablePoint<double> Nomal
|
||||
{
|
||||
get => _nomal;
|
||||
set => SetProperty(ref _nomal, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PoorCondition
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _poorCondition;
|
||||
public ObservablePoint<double> PoorCondition
|
||||
{
|
||||
get => _poorCondition;
|
||||
set => SetProperty(ref _poorCondition, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Ill
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservablePoint<double> _ill;
|
||||
public ObservablePoint<double> Ill
|
||||
{
|
||||
get => _ill;
|
||||
set => SetProperty(ref _ill, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
public ObservableMultiStatePoint()
|
||||
{
|
||||
Happy = new();
|
||||
@ -604,10 +743,10 @@ public class ObservableMultiStatePoint
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Happy = Happy.Copy(),
|
||||
Nomal = Nomal.Copy(),
|
||||
PoorCondition = PoorCondition.Copy(),
|
||||
Ill = Ill.Copy(),
|
||||
Happy = Happy.Clone(),
|
||||
Nomal = Nomal.Clone(),
|
||||
PoorCondition = PoorCondition.Clone(),
|
||||
Ill = Ill.Clone(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
@ -21,30 +21,67 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
/// </summary>
|
||||
public static ObservableCollection<ClickText.ModeType> ModeTypes => ClickTextModel.ModeTypes;
|
||||
|
||||
#region Tags
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _tags = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
public ObservableValue<string> Tags { get; } = new();
|
||||
public string Tags
|
||||
{
|
||||
get => _tags;
|
||||
set => SetProperty(ref _tags, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToTags
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _toTags = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 跳转标签
|
||||
/// </summary>
|
||||
public ObservableValue<string> ToTags { get; } = new();
|
||||
public string ToTags
|
||||
{
|
||||
get => _toTags;
|
||||
set => SetProperty(ref _toTags, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ChooseId
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _chooseId = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 选择Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> ChooseId { get; } = new();
|
||||
|
||||
public string ChooseId
|
||||
{
|
||||
get => _chooseId;
|
||||
set => SetProperty(ref _chooseId, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 宠物状态
|
||||
/// </summary>
|
||||
public ObservableEnumFlags<ClickText.ModeType> Mode { get; } =
|
||||
public ObservableEnumCommand<ClickText.ModeType> Mode { get; } =
|
||||
new(
|
||||
ClickText.ModeType.Happy
|
||||
| ClickText.ModeType.Nomal
|
||||
@ -94,42 +131,43 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
|
||||
public SelectTextModel()
|
||||
{
|
||||
ChooseId.Value = $"{Id.Value}_{nameof(ChooseId)}";
|
||||
Id.ValueChanged += (s, e) =>
|
||||
{
|
||||
ChooseId.Value = $"{e.NewValue}_{nameof(ChooseId)}";
|
||||
};
|
||||
ChooseId = $"{Id}_{nameof(ChooseId)}";
|
||||
//TODO
|
||||
//Id.ValueChanged += (s, e) =>
|
||||
//{
|
||||
// ChooseId.Value = $"{e.NewValue}_{nameof(ChooseId)}";
|
||||
//};
|
||||
}
|
||||
|
||||
public SelectTextModel(SelectTextModel model)
|
||||
: this()
|
||||
{
|
||||
Id.Value = model.Id.Value;
|
||||
Mode.EnumValue.Value = model.Mode.EnumValue.Value;
|
||||
Tags.Value = model.Tags.Value;
|
||||
ToTags.Value = model.ToTags.Value;
|
||||
Like = model.Like.Copy();
|
||||
Health = model.Health.Copy();
|
||||
Level = model.Level.Copy();
|
||||
Money = model.Money.Copy();
|
||||
Food = model.Food.Copy();
|
||||
Drink = model.Drink.Copy();
|
||||
Feel = model.Feel.Copy();
|
||||
Strength = model.Strength.Copy();
|
||||
Id = model.Id;
|
||||
Mode.Value = model.Mode.Value;
|
||||
Tags = model.Tags;
|
||||
ToTags = model.ToTags;
|
||||
Like = model.Like.Clone();
|
||||
Health = model.Health.Clone();
|
||||
Level = model.Level.Clone();
|
||||
Money = model.Money.Clone();
|
||||
Food = model.Food.Clone();
|
||||
Drink = model.Drink.Clone();
|
||||
Feel = model.Feel.Clone();
|
||||
Strength = model.Strength.Clone();
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public SelectTextModel(SelectText text)
|
||||
: this()
|
||||
{
|
||||
Id.Value = text.Text;
|
||||
ChooseId.Value = text.Choose ?? string.Empty;
|
||||
Mode.EnumValue.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);
|
||||
Id = text.Text;
|
||||
ChooseId = text.Choose ?? string.Empty;
|
||||
Mode.Value = text.Mode;
|
||||
Tags = text.Tags is null ? string.Empty : string.Join(", ", text.Tags);
|
||||
ToTags = text.ToTags is null ? string.Empty : string.Join(", ", text.ToTags);
|
||||
Like = new(text.LikeMin, text.LikeMax);
|
||||
Health = new(text.HealthMin, text.HealthMax);
|
||||
Level = new(text.LevelMin, text.LevelMax);
|
||||
@ -142,20 +180,20 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
|
||||
public void RefreshId()
|
||||
{
|
||||
ChooseId.Value = $"{Id.Value}_{nameof(ChooseId)}";
|
||||
ChooseId = $"{Id}_{nameof(ChooseId)}";
|
||||
}
|
||||
|
||||
private readonly static char[] rs_splitChar = { ',', ' ' };
|
||||
private static readonly char[] rs_splitChar = { ',', ' ' };
|
||||
|
||||
public SelectText ToSelectText()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Text = Id.Value,
|
||||
Choose = ChooseId.Value,
|
||||
Mode = Mode.EnumValue.Value,
|
||||
Tags = new(Tags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
||||
ToTags = new(ToTags.Value.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
||||
Text = Id,
|
||||
Choose = ChooseId,
|
||||
Mode = Mode.Value,
|
||||
Tags = new(Tags.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
||||
ToTags = new(ToTags.Split(rs_splitChar, StringSplitOptions.RemoveEmptyEntries)),
|
||||
LikeMax = Like.Max,
|
||||
LikeMin = Like.Min,
|
||||
HealthMin = Health.Min,
|
||||
@ -176,16 +214,34 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nSelectTextModel
|
||||
public class I18nSelectTextModel : ObservableObjectX<I18nSelectTextModel>
|
||||
{
|
||||
public ObservableValue<string> Choose { get; } = new();
|
||||
public ObservableValue<string> Text { get; } = new();
|
||||
#region Choose
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _choose = string.Empty;
|
||||
|
||||
public string Choose
|
||||
{
|
||||
get => _choose;
|
||||
set => SetProperty(ref _choose, value);
|
||||
}
|
||||
#endregion
|
||||
#region Text
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _text = string.Empty;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => _text;
|
||||
set => SetProperty(ref _text, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nSelectTextModel Copy()
|
||||
{
|
||||
var result = new I18nSelectTextModel();
|
||||
result.Text.Value = Text.Value;
|
||||
result.Choose.Value = Choose.Value;
|
||||
result.Text = Text;
|
||||
result.Choose = Choose;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -24,237 +25,430 @@ public class WorkModel : I18nModel<I18nWorkModel>
|
||||
.Cast<VPet_Simulator.Core.GraphHelper.Work.WorkType>()
|
||||
);
|
||||
|
||||
#region Id
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Graph
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _graph;
|
||||
|
||||
/// <summary>
|
||||
/// 指定动画
|
||||
/// </summary>
|
||||
public ObservableValue<string> Graph { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 收获倍率
|
||||
/// </summary>
|
||||
//public ObservableValue<double> MoneyLevel { get; } = new();
|
||||
public string Graph
|
||||
{
|
||||
get => _graph;
|
||||
set => SetProperty(ref _graph, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
//#region MoneyLevel
|
||||
//[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
//private double _moneyLevel;
|
||||
|
||||
///// <summary>
|
||||
///// 收获倍率
|
||||
///// </summary>
|
||||
//public double MoneyLevel
|
||||
//{
|
||||
// get => _moneyLevel;
|
||||
// set => SetProperty(ref _moneyLevel, value);
|
||||
//}
|
||||
//#endregion
|
||||
|
||||
#region MoneyBase
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _moneyBase;
|
||||
|
||||
/// <summary>
|
||||
/// 收获基础
|
||||
/// </summary>
|
||||
public ObservableValue<double> MoneyBase { get; } = new();
|
||||
public double MoneyBase
|
||||
{
|
||||
get => _moneyBase;
|
||||
set => SetProperty(ref _moneyBase, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region StrengthFood
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _strengthFood;
|
||||
|
||||
/// <summary>
|
||||
/// 饱食度消耗
|
||||
/// </summary>
|
||||
public ObservableValue<double> StrengthFood { get; } = new();
|
||||
public double StrengthFood
|
||||
{
|
||||
get => _strengthFood;
|
||||
set => SetProperty(ref _strengthFood, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region StrengthDrink
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _strengthDrink;
|
||||
|
||||
/// <summary>
|
||||
/// 口渴度消耗
|
||||
/// </summary>
|
||||
public ObservableValue<double> StrengthDrink { get; } = new();
|
||||
public double StrengthDrink
|
||||
{
|
||||
get => _strengthDrink;
|
||||
set => SetProperty(ref _strengthDrink, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Feeling
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _feeling;
|
||||
|
||||
/// <summary>
|
||||
/// 心情消耗
|
||||
/// </summary>
|
||||
public ObservableValue<double> Feeling { get; } = new();
|
||||
public double Feeling
|
||||
{
|
||||
get => _feeling;
|
||||
set => SetProperty(ref _feeling, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LevelLimit
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _levelLimit;
|
||||
|
||||
/// <summary>
|
||||
/// 等级倍率
|
||||
/// </summary>
|
||||
public ObservableValue<int> LevelLimit { get; } = new();
|
||||
public int LevelLimit
|
||||
{
|
||||
get => _levelLimit;
|
||||
set => SetProperty(ref _levelLimit, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Time
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private int _time;
|
||||
|
||||
/// <summary>
|
||||
/// 时间
|
||||
/// </summary>
|
||||
public ObservableValue<int> Time { get; } = new();
|
||||
public int Time
|
||||
{
|
||||
get => _time;
|
||||
set => SetProperty(ref _time, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region FinishBonus
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _finishBonus;
|
||||
|
||||
/// <summary>
|
||||
/// 完成奖励倍率
|
||||
/// </summary>
|
||||
public ObservableValue<double> FinishBonus { get; } = new();
|
||||
public double FinishBonus
|
||||
{
|
||||
get => _finishBonus;
|
||||
set => SetProperty(ref _finishBonus, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IsOverLoad
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _isOverLoad;
|
||||
|
||||
/// <summary>
|
||||
/// 是否超模
|
||||
/// </summary>
|
||||
public ObservableValue<bool> IsOverLoad { get; } = new();
|
||||
public bool IsOverLoad
|
||||
{
|
||||
get => _isOverLoad;
|
||||
set => SetProperty(ref _isOverLoad, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public ObservableValue<BitmapImage> Image { get; } = new();
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WorkType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private VPet_Simulator.Core.GraphHelper.Work.WorkType _workType;
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// 工作类型
|
||||
/// </summary>
|
||||
public ObservableValue<VPet_Simulator.Core.GraphHelper.Work.WorkType> WorkType { get; } =
|
||||
new(VPet_Simulator.Core.GraphHelper.Work.WorkType.Work);
|
||||
public VPet_Simulator.Core.GraphHelper.Work.WorkType WorkType
|
||||
{
|
||||
get => _workType;
|
||||
set => SetProperty(ref _workType, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BorderBrush
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _borderBrush =
|
||||
new((Color)ColorConverter.ConvertFromString("#FF0290D5"));
|
||||
|
||||
/// <summary>
|
||||
/// 边框颜色
|
||||
/// </summary>
|
||||
public ObservableValue<SolidColorBrush> BorderBrush { get; } =
|
||||
new(new((Color)ColorConverter.ConvertFromString("#FF0290D5")));
|
||||
|
||||
public SolidColorBrush BorderBrush
|
||||
{
|
||||
get => _borderBrush;
|
||||
set => SetProperty(ref _borderBrush, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 背景色
|
||||
/// </summary>
|
||||
public ObservableValue<SolidColorBrush> Background { get; } =
|
||||
new(new((Color)ColorConverter.ConvertFromString("#FF81D4FA")));
|
||||
#region Background
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _background = new((Color)ColorConverter.ConvertFromString("#FF81D4FA"));
|
||||
|
||||
public SolidColorBrush Background
|
||||
{
|
||||
get => _background;
|
||||
set => SetProperty(ref _background, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 前景色
|
||||
/// </summary>
|
||||
public ObservableValue<SolidColorBrush> Foreground { get; } =
|
||||
new(new((Color)ColorConverter.ConvertFromString("#FF0286C6")));
|
||||
#region Foreground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _foreground = new((Color)ColorConverter.ConvertFromString("#FF0286C6"));
|
||||
|
||||
public SolidColorBrush Foreground
|
||||
{
|
||||
get => _foreground;
|
||||
set => SetProperty(ref _foreground, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 按钮背景色
|
||||
/// </summary>
|
||||
public ObservableValue<SolidColorBrush> ButtonBackground { get; } =
|
||||
new(new((Color)ColorConverter.ConvertFromString("#AA0286C6")));
|
||||
#region ButtonBackground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _buttonBackground =
|
||||
new((Color)ColorConverter.ConvertFromString("#AA0286C6"));
|
||||
|
||||
public SolidColorBrush ButtonBackground
|
||||
{
|
||||
get => _buttonBackground;
|
||||
set => SetProperty(ref _buttonBackground, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 按钮前景色
|
||||
/// </summary>
|
||||
public ObservableValue<SolidColorBrush> ButtonForeground { get; } =
|
||||
new(new((Color)ColorConverter.ConvertFromString("#FFFFFFFF")));
|
||||
#region ButtonForeground
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SolidColorBrush _buttonForeground;
|
||||
|
||||
public SolidColorBrush ButtonForeground
|
||||
{
|
||||
get => _buttonForeground;
|
||||
set => SetProperty(ref _buttonForeground, value);
|
||||
}
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// X位置
|
||||
/// </summary>
|
||||
public ObservableValue<double> Left { get; } = new(100);
|
||||
#region Left
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Left;
|
||||
|
||||
public double Left
|
||||
{
|
||||
get => _Left;
|
||||
set => SetProperty(ref _Left, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Y位置
|
||||
/// </summary>
|
||||
public ObservableValue<double> Top { get; } = new(160);
|
||||
#region Top
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Top;
|
||||
|
||||
public double Top
|
||||
{
|
||||
get => _Top;
|
||||
set => SetProperty(ref _Top, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 宽度
|
||||
/// </summary>
|
||||
public ObservableValue<double> Width { get; } = new(300);
|
||||
#region Width
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _Width;
|
||||
|
||||
public double Width
|
||||
{
|
||||
get => _Width;
|
||||
set => SetProperty(ref _Width, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public WorkModel()
|
||||
{
|
||||
IsOverLoad.AddNotifySender(
|
||||
WorkType,
|
||||
MoneyBase,
|
||||
//MoneyLevel,
|
||||
StrengthFood,
|
||||
StrengthDrink,
|
||||
Feeling,
|
||||
LevelLimit,
|
||||
FinishBonus
|
||||
);
|
||||
IsOverLoad.SenderPropertyChanged += (s, _) =>
|
||||
{
|
||||
s.Value = VPet_Simulator.Windows.Interface.ExtensionFunction.IsOverLoad(ToWork());
|
||||
};
|
||||
{ //TODO
|
||||
//IsOverLoad.AddNotifySender(
|
||||
// WorkType,
|
||||
// MoneyBase,
|
||||
// //MoneyLevel,
|
||||
// StrengthFood,
|
||||
// StrengthDrink,
|
||||
// Feeling,
|
||||
// LevelLimit,
|
||||
// FinishBonus
|
||||
//);
|
||||
//IsOverLoad.SenderPropertyChanged += (s, _) =>
|
||||
//{
|
||||
// s.Value = VPet_Simulator.Windows.Interface.ExtensionFunction.IsOverLoad(ToWork());
|
||||
//};
|
||||
}
|
||||
|
||||
public WorkModel(WorkModel model)
|
||||
: this()
|
||||
{
|
||||
WorkType.Value = model.WorkType.Value;
|
||||
Id.Value = model.Id.Value;
|
||||
Graph.Value = model.Graph.Value;
|
||||
//MoneyLevel.Value = model.MoneyLevel.Value;
|
||||
MoneyBase.Value = model.MoneyBase.Value;
|
||||
StrengthFood.Value = model.StrengthFood.Value;
|
||||
StrengthDrink.Value = model.StrengthDrink.Value;
|
||||
Feeling.Value = model.Feeling.Value;
|
||||
LevelLimit.Value = model.LevelLimit.Value;
|
||||
Time.Value = model.Time.Value;
|
||||
FinishBonus.Value = model.FinishBonus.Value;
|
||||
WorkType = model.WorkType;
|
||||
Id = model.Id;
|
||||
Graph = model.Graph;
|
||||
//MoneyLevel = model.MoneyLevel;
|
||||
MoneyBase = model.MoneyBase;
|
||||
StrengthFood = model.StrengthFood;
|
||||
StrengthDrink = model.StrengthDrink;
|
||||
Feeling = model.Feeling;
|
||||
LevelLimit = model.LevelLimit;
|
||||
Time = model.Time;
|
||||
FinishBonus = model.FinishBonus;
|
||||
|
||||
BorderBrush.Value = model.BorderBrush.Value;
|
||||
Background.Value = model.Background.Value;
|
||||
ButtonBackground.Value = model.ButtonBackground.Value;
|
||||
ButtonForeground.Value = model.ButtonForeground.Value;
|
||||
Foreground.Value = model.Foreground.Value;
|
||||
|
||||
Left.Value = model.Left.Value;
|
||||
Top.Value = model.Top.Value;
|
||||
Width.Value = model.Width.Value;
|
||||
BorderBrush = model.BorderBrush;
|
||||
Background = model.Background;
|
||||
ButtonBackground = model.ButtonBackground;
|
||||
ButtonForeground = model.ButtonForeground;
|
||||
Foreground = model.Foreground;
|
||||
Left = model.Left;
|
||||
Top = model.Top;
|
||||
Width = model.Width;
|
||||
|
||||
foreach (var item in model.I18nDatas)
|
||||
I18nDatas[item.Key] = item.Value.Copy();
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
CurrentI18nData = I18nDatas[I18nHelper.Current.CultureName];
|
||||
}
|
||||
|
||||
public WorkModel(VPet_Simulator.Core.GraphHelper.Work work)
|
||||
: this()
|
||||
{
|
||||
WorkType.Value = work.Type;
|
||||
Id.Value = work.Name;
|
||||
Graph.Value = work.Graph;
|
||||
//MoneyLevel.Value = work.MoneyLevel;
|
||||
MoneyBase.Value = work.MoneyBase;
|
||||
StrengthFood.Value = work.StrengthFood;
|
||||
StrengthDrink.Value = work.StrengthDrink;
|
||||
Feeling.Value = work.Feeling;
|
||||
LevelLimit.Value = work.LevelLimit;
|
||||
Time.Value = work.Time;
|
||||
FinishBonus.Value = work.FinishBonus;
|
||||
WorkType = work.Type;
|
||||
Id = work.Name;
|
||||
Graph = work.Graph;
|
||||
//MoneyLevel = work.MoneyLevel;
|
||||
MoneyBase = work.MoneyBase;
|
||||
StrengthFood = work.StrengthFood;
|
||||
StrengthDrink = work.StrengthDrink;
|
||||
Feeling = work.Feeling;
|
||||
LevelLimit = work.LevelLimit;
|
||||
Time = work.Time;
|
||||
FinishBonus = work.FinishBonus;
|
||||
|
||||
BorderBrush.Value = new((Color)ColorConverter.ConvertFromString("#FF" + work.BorderBrush));
|
||||
Background.Value = new((Color)ColorConverter.ConvertFromString("#FF" + work.Background));
|
||||
Foreground.Value = new((Color)ColorConverter.ConvertFromString("#FF" + work.Foreground));
|
||||
ButtonBackground.Value = new(
|
||||
BorderBrush = new((Color)ColorConverter.ConvertFromString("#FF" + work.BorderBrush));
|
||||
Background = new((Color)ColorConverter.ConvertFromString("#FF" + work.Background));
|
||||
Foreground = new((Color)ColorConverter.ConvertFromString("#FF" + work.Foreground));
|
||||
ButtonBackground = new(
|
||||
(Color)ColorConverter.ConvertFromString("#AA" + work.ButtonBackground)
|
||||
);
|
||||
ButtonForeground.Value = new(
|
||||
ButtonForeground = new(
|
||||
(Color)ColorConverter.ConvertFromString("#FF" + work.ButtonForeground)
|
||||
);
|
||||
|
||||
Left.Value = work.Left;
|
||||
Top.Value = work.Top;
|
||||
Width.Value = work.Width;
|
||||
Left = work.Left;
|
||||
Top = work.Top;
|
||||
Width = work.Width;
|
||||
}
|
||||
|
||||
public VPet_Simulator.Core.GraphHelper.Work ToWork()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Type = WorkType.Value,
|
||||
Name = Id.Value,
|
||||
Graph = Graph.Value,
|
||||
//MoneyLevel = MoneyLevel.Value,
|
||||
MoneyBase = MoneyBase.Value,
|
||||
StrengthFood = StrengthFood.Value,
|
||||
StrengthDrink = StrengthDrink.Value,
|
||||
Feeling = Feeling.Value,
|
||||
LevelLimit = LevelLimit.Value,
|
||||
Time = Time.Value,
|
||||
FinishBonus = FinishBonus.Value,
|
||||
Type = WorkType,
|
||||
Name = Id,
|
||||
Graph = Graph,
|
||||
//MoneyLevel = MoneyLevel,
|
||||
MoneyBase = MoneyBase,
|
||||
StrengthFood = StrengthFood,
|
||||
StrengthDrink = StrengthDrink,
|
||||
Feeling = Feeling,
|
||||
LevelLimit = LevelLimit,
|
||||
Time = Time,
|
||||
FinishBonus = FinishBonus,
|
||||
//
|
||||
BorderBrush = BorderBrush.Value.ToString()[3..],
|
||||
Background = Background.Value.ToString()[3..],
|
||||
ButtonBackground = ButtonBackground.Value.ToString()[3..],
|
||||
ButtonForeground = ButtonForeground.Value.ToString()[3..],
|
||||
Foreground = Foreground.Value.ToString()[3..],
|
||||
BorderBrush = BorderBrush.ToString()[3..],
|
||||
Background = Background.ToString()[3..],
|
||||
ButtonBackground = ButtonBackground.ToString()[3..],
|
||||
ButtonForeground = ButtonForeground.ToString()[3..],
|
||||
Foreground = Foreground.ToString()[3..],
|
||||
//
|
||||
Left = Left.Value,
|
||||
Top = Top.Value,
|
||||
Width = Width.Value,
|
||||
Left = Left,
|
||||
Top = Top,
|
||||
Width = Width,
|
||||
};
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image.Value.CloseStream();
|
||||
Image.CloseStream();
|
||||
}
|
||||
}
|
||||
|
||||
public class I18nWorkModel
|
||||
public class I18nWorkModel : ObservableObjectX<I18nWorkModel>
|
||||
{
|
||||
public ObservableValue<string> Name { get; } = new();
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public I18nWorkModel Copy()
|
||||
{
|
||||
var result = new I18nWorkModel();
|
||||
result.Name.Value = Name.Value;
|
||||
result.Name = Name;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
//using HKW.HKWUtils.Observable;
|
||||
|
||||
//namespace VPet.ModMaker.Models;
|
||||
|
||||
//public class ObservablePoint<T>
|
||||
//{
|
||||
// public ObservableValue<T> X { get; } = new();
|
||||
// public ObservableValue<T> Y { get; } = new();
|
||||
|
||||
// public ObservablePoint() { }
|
||||
|
||||
// public ObservablePoint(T x, T y)
|
||||
// {
|
||||
// X.Value = x;
|
||||
// Y.Value = y;
|
||||
// }
|
||||
|
||||
// public void SetValue(T x, T y)
|
||||
// {
|
||||
// X.Value = x;
|
||||
// Y.Value = y;
|
||||
// }
|
||||
|
||||
// public ObservablePoint<T> Copy()
|
||||
// {
|
||||
// var result = new ObservablePoint<T>();
|
||||
// result.X.Value = X.Value;
|
||||
// result.Y.Value = Y.Value;
|
||||
// return result;
|
||||
// }
|
||||
//}
|
@ -1,62 +0,0 @@
|
||||
//using HKW.HKWUtils.Observable;
|
||||
|
||||
//namespace HKW.Models;
|
||||
|
||||
///// <summary>
|
||||
///// 可观察的范围
|
||||
///// </summary>
|
||||
///// <typeparam name="T">类型</typeparam>
|
||||
//public class ObservableRange<T>
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 最小值
|
||||
// /// </summary>
|
||||
// public ObservableValue<T> Min { get; } = new();
|
||||
|
||||
// /// <summary>
|
||||
// /// 最大值
|
||||
// /// </summary>
|
||||
// public ObservableValue<T> Max { get; } = new();
|
||||
|
||||
// /// <summary>
|
||||
// /// 信息
|
||||
// /// </summary>
|
||||
// public ObservableValue<string> Info { get; } = new();
|
||||
|
||||
// public ObservableRange()
|
||||
// {
|
||||
// Min.ValueChanged += ValueChanged;
|
||||
// Max.ValueChanged += ValueChanged;
|
||||
// }
|
||||
|
||||
// public ObservableRange(T min, T max)
|
||||
// : this()
|
||||
// {
|
||||
// SetValue(min, max);
|
||||
// }
|
||||
|
||||
// private void ValueChanged(ObservableValue<T> sender, ValueChangedEventArgs<T> e)
|
||||
// {
|
||||
// Info.Value = $"({Min.Value}, {Max.Value})";
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 设置值
|
||||
// /// </summary>
|
||||
// /// <param name="min">最小值</param>
|
||||
// /// <param name="max">最大值</param>
|
||||
// public void SetValue(T min, T max)
|
||||
// {
|
||||
// Min.Value = min;
|
||||
// Max.Value = max;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 复制
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public ObservableRange<T> Copy()
|
||||
// {
|
||||
// return new(Min.Value, Max.Value);
|
||||
// }
|
||||
//}
|
@ -1,41 +0,0 @@
|
||||
//using HKW.HKWUtils.Observable;
|
||||
|
||||
//namespace VPet.ModMaker.Models;
|
||||
|
||||
//public class ObservableRect<T>
|
||||
//{
|
||||
// public ObservableValue<T> X { get; } = new();
|
||||
// public ObservableValue<T> Y { get; } = new();
|
||||
// public ObservableValue<T> Width { get; } = new();
|
||||
// public ObservableValue<T> Height { get; } = new();
|
||||
|
||||
// public bool Changed { get; set; } = true;
|
||||
|
||||
// public ObservableRect() { }
|
||||
|
||||
// public ObservableRect(T x, T y, T width, T hetght)
|
||||
// {
|
||||
// X.Value = x;
|
||||
// Y.Value = y;
|
||||
// Width.Value = width;
|
||||
// Height.Value = hetght;
|
||||
// }
|
||||
|
||||
// public void SetValue(T x, T y, T width, T hetght)
|
||||
// {
|
||||
// X.Value = x;
|
||||
// Y.Value = y;
|
||||
// Width.Value = width;
|
||||
// Height.Value = hetght;
|
||||
// }
|
||||
|
||||
// public ObservableRect<T> Copy()
|
||||
// {
|
||||
// var result = new ObservableRect<T>();
|
||||
// result.X.Value = X.Value;
|
||||
// result.Y.Value = Y.Value;
|
||||
// result.Width.Value = Width.Value;
|
||||
// result.Height.Value = Height.Value;
|
||||
// return result;
|
||||
// }
|
||||
//}
|
@ -1,12 +0,0 @@
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 通知属性改变后接口
|
||||
/// </summary>
|
||||
public interface INotifyPropertyChangedX<TSender>
|
||||
{
|
||||
/// <summary>
|
||||
/// 通知属性改变后事件
|
||||
/// </summary>
|
||||
public event PropertyChangedXEventHandler<TSender>? PropertyChangedX;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 通知属性改变前接口
|
||||
/// </summary>
|
||||
public interface INotifyPropertyChangingX<TSender>
|
||||
{
|
||||
/// <summary>
|
||||
/// 属性改变前事件
|
||||
/// </summary>
|
||||
public event PropertyChangingXEventHandler<TSender>? PropertyChangingX;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察对象
|
||||
/// <para>示例:<code><![CDATA[
|
||||
/// public class ObservableClassExample : ObservableClass<ObservableClassExample>
|
||||
/// {
|
||||
/// int _value = 0;
|
||||
/// public int Value
|
||||
/// {
|
||||
/// get => _value;
|
||||
/// set => SetProperty(ref _value, value);
|
||||
/// }
|
||||
/// }]]></code></para>
|
||||
/// </summary>
|
||||
public abstract class ObservableClass<TObject>
|
||||
: INotifyPropertyChanging,
|
||||
INotifyPropertyChanged,
|
||||
INotifyPropertyChangingX<TObject>,
|
||||
INotifyPropertyChangedX<TObject>
|
||||
where TObject : ObservableClass<TObject>
|
||||
{
|
||||
#region OnPropertyChange
|
||||
/// <summary>
|
||||
/// 设置属性值
|
||||
/// </summary>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <param name="propertyName">属性名称</param>
|
||||
/// <returns>成功为 <see langword="true"/> 失败为 <see langword="false"/></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected virtual bool SetProperty<TValue>(
|
||||
ref TValue value,
|
||||
TValue newValue,
|
||||
[CallerMemberName] string propertyName = null!
|
||||
)
|
||||
{
|
||||
if (EqualityComparer<TValue>.Default.Equals(value, newValue) is true)
|
||||
return false;
|
||||
var oldValue = value;
|
||||
if (OnPropertyChanging(oldValue, newValue, propertyName))
|
||||
return false;
|
||||
value = newValue;
|
||||
OnPropertyChanged(oldValue, newValue, propertyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变前
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <param name="propertyName">属性名称</param>
|
||||
/// <returns>取消为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected virtual bool OnPropertyChanging(
|
||||
object? oldValue,
|
||||
object? newValue,
|
||||
[CallerMemberName] string propertyName = null!
|
||||
)
|
||||
{
|
||||
PropertyChanging?.Invoke(this, new(propertyName));
|
||||
if (PropertyChangingX is null)
|
||||
return false;
|
||||
var e = new PropertyChangingXEventArgs(propertyName, oldValue, newValue);
|
||||
PropertyChangingX?.Invoke((TObject)this, e);
|
||||
if (e.Cancel)
|
||||
PropertyChanged?.Invoke(this, new(propertyName));
|
||||
return e.Cancel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变后
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <param name="propertyName">属性名称</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected virtual void OnPropertyChanged(
|
||||
object? oldValue,
|
||||
object? newValue,
|
||||
[CallerMemberName] string propertyName = null!
|
||||
)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new(propertyName));
|
||||
PropertyChangedX?.Invoke((TObject)this, new(propertyName, oldValue, newValue));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
/// <inheritdoc/>
|
||||
public event PropertyChangingEventHandler? PropertyChanging;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event PropertyChangingXEventHandler<TObject>? PropertyChangingX;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event PropertyChangedXEventHandler<TObject>? PropertyChangedX;
|
||||
#endregion
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变后事件参数
|
||||
/// </summary>
|
||||
public class PropertyChangedXEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 属性名
|
||||
/// </summary>
|
||||
public string PropertyName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 旧值
|
||||
/// </summary>
|
||||
public object? OldValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 新值
|
||||
/// </summary>
|
||||
public object? NewValue { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public PropertyChangedXEventArgs(string propertyName, object? oldValue, object? newValue)
|
||||
{
|
||||
PropertyName = propertyName;
|
||||
OldValue = oldValue;
|
||||
NewValue = newValue;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// 获取值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <returns>(旧值, 新值)</returns>
|
||||
public (T oldValue, T newValye) GetValue<T>()
|
||||
{
|
||||
return ((T)OldValue!, (T)NewValue!)!;
|
||||
}
|
||||
#else
|
||||
/// <summary>
|
||||
/// 获取值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <returns>(旧值, 新值)</returns>
|
||||
public ValueInfo<T> GetValue<T>()
|
||||
{
|
||||
return new((T)OldValue!, (T)NewValue!)!;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !NETCOREAPP2_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// 值信息
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
public struct ValueInfo<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 旧值
|
||||
/// </summary>
|
||||
public T OldValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 新值
|
||||
/// </summary>
|
||||
public T NewValue { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public ValueInfo(T oldValue, T newValue)
|
||||
{
|
||||
OldValue = oldValue;
|
||||
NewValue = newValue;
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变后事件
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="e">参数</param>
|
||||
public delegate void PropertyChangedXEventHandler<TSender>(
|
||||
TSender sender,
|
||||
PropertyChangedXEventArgs e
|
||||
);
|
@ -1,57 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变前事件参数
|
||||
/// </summary>
|
||||
public class PropertyChangingXEventArgs : CancelEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 属性名
|
||||
/// </summary>
|
||||
public string PropertyName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 旧值
|
||||
/// </summary>
|
||||
public object? OldValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 新值
|
||||
/// </summary>
|
||||
public object? NewValue { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public PropertyChangingXEventArgs(string propertyName, object? oldValue, object? newValue)
|
||||
{
|
||||
PropertyName = propertyName;
|
||||
OldValue = oldValue;
|
||||
NewValue = newValue;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// 获取值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <returns>(旧值, 新值)</returns>
|
||||
public (T oldValue, T newValye) GetValue<T>()
|
||||
{
|
||||
return ((T)OldValue!, (T)NewValue!)!;
|
||||
}
|
||||
#else
|
||||
/// <summary>
|
||||
/// 获取值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <returns>(旧值, 新值)</returns>
|
||||
public ValueInfo<T> GetValue<T>()
|
||||
{
|
||||
return new((T)OldValue!, (T)NewValue!)!;
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变前事件
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="e">参数</param>
|
||||
public delegate void PropertyChangingXEventHandler<TSender>(
|
||||
TSender sender,
|
||||
PropertyChangingXEventArgs e
|
||||
);
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行命令事件
|
||||
/// </summary>
|
||||
public delegate Task ExecuteAsyncEventHandler();
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行命令事件
|
||||
/// </summary>
|
||||
/// <param name="parameter">值</param>
|
||||
public delegate Task ExecuteAsyncEventHandler<T>(T parameter);
|
@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 执行事件
|
||||
/// </summary>
|
||||
public delegate void ExecuteEventHandler();
|
||||
|
||||
/// <summary>
|
||||
/// 执行事件
|
||||
/// </summary>
|
||||
/// <param name="parameter">参数</param>
|
||||
public delegate void ExecuteEventHandler<T>(T parameter);
|
@ -1,11 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 通知接收器
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="e">参数</param>
|
||||
public delegate void NotifyReceivedEventHandler(ICommand sender, CancelEventArgs e);
|
@ -1,118 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察命令
|
||||
/// </summary>
|
||||
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {IsCanExecute.Value}\\}")]
|
||||
public class ObservableCommand : ObservableClass<ObservableCommand>, ICommand
|
||||
{
|
||||
bool _isCanExecute = true;
|
||||
|
||||
/// <summary>
|
||||
/// 能执行的属性
|
||||
/// </summary>
|
||||
public bool IsCanExecute
|
||||
{
|
||||
get => _isCanExecute;
|
||||
set => SetProperty(ref _isCanExecute, value);
|
||||
}
|
||||
|
||||
bool _currentCanExecute = true;
|
||||
|
||||
/// <summary>
|
||||
/// 当前可执行状态
|
||||
/// <para>
|
||||
/// 在执行异步事件时会强制为 <see langword="false"/>, 但异步结束后会恢复为 <see cref="IsCanExecute"/> 的值
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool CurrentCanExecute
|
||||
{
|
||||
get => _currentCanExecute;
|
||||
private set => SetProperty(ref _currentCanExecute, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ObservableCommand()
|
||||
{
|
||||
PropertyChanged += OnCanExecuteChanged;
|
||||
}
|
||||
|
||||
private void OnCanExecuteChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
CanExecuteChanged?.Invoke(this, new());
|
||||
}
|
||||
|
||||
#region ICommand
|
||||
/// <summary>
|
||||
/// 能否被执行
|
||||
/// </summary>
|
||||
/// <param name="parameter">参数</param>
|
||||
/// <returns>能被执行为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
||||
public bool CanExecute(object? parameter)
|
||||
{
|
||||
return CurrentCanExecute && IsCanExecute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行方法
|
||||
/// </summary>
|
||||
/// <param name="parameter">参数</param>
|
||||
public async void Execute(object? parameter)
|
||||
{
|
||||
if (IsCanExecute is not true)
|
||||
return;
|
||||
ExecuteCommand?.Invoke();
|
||||
await ExecuteAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行异步方法, 会在等待中修改 <see cref="CurrentCanExecute"/>, 完成后恢复
|
||||
/// <para>
|
||||
/// 若要在执行此方法时触发 <see cref="ExecuteCommand"/> 事件, 请将 <paramref name="runAlone"/> 设置为 <see langword="true"/>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="runAlone">设置为 <see langword="true"/> 时触发 <see cref="ExecuteCommand"/> 事件</param>
|
||||
/// <returns>任务</returns>
|
||||
public async Task ExecuteAsync(bool runAlone = false)
|
||||
{
|
||||
if (IsCanExecute is not true)
|
||||
return;
|
||||
if (runAlone)
|
||||
ExecuteCommand?.Invoke();
|
||||
if (ExecuteAsyncCommand is null)
|
||||
return;
|
||||
CurrentCanExecute = false;
|
||||
foreach (
|
||||
var asyncEvent in ExecuteAsyncCommand
|
||||
.GetInvocationList()
|
||||
.Cast<ExecuteAsyncEventHandler>()
|
||||
)
|
||||
await asyncEvent.Invoke();
|
||||
CurrentCanExecute = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
/// <summary>
|
||||
/// 能否执行属性改变后事件
|
||||
/// </summary>
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 执行事件
|
||||
/// </summary>
|
||||
public event ExecuteEventHandler? ExecuteCommand;
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行事件
|
||||
/// </summary>
|
||||
public event ExecuteAsyncEventHandler? ExecuteAsyncCommand;
|
||||
#endregion
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 具有参数的可观察命令
|
||||
/// </summary>
|
||||
[DebuggerDisplay("\\{ObservableCommand, CanExecute = {IsCanExecute.Value}\\}")]
|
||||
public class ObservableCommand<T> : ObservableClass<ObservableCommand>, ICommand
|
||||
{
|
||||
bool _isCanExecute = true;
|
||||
|
||||
/// <summary>
|
||||
/// 能执行的属性
|
||||
/// </summary>
|
||||
public bool IsCanExecute
|
||||
{
|
||||
get => _isCanExecute;
|
||||
set => SetProperty(ref _isCanExecute, value);
|
||||
}
|
||||
|
||||
bool _currentCanExecute = true;
|
||||
|
||||
/// <summary>
|
||||
/// 当前可执行状态
|
||||
/// <para>
|
||||
/// 在执行异步事件时会强制为 <see langword="false"/>, 但异步结束后会恢复为 <see cref="IsCanExecute"/> 的值
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool CurrentCanExecute
|
||||
{
|
||||
get => _currentCanExecute;
|
||||
private set => SetProperty(ref _currentCanExecute, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ObservableCommand()
|
||||
{
|
||||
PropertyChanged += OnCanExecuteChanged;
|
||||
}
|
||||
|
||||
private void OnCanExecuteChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
CanExecuteChanged?.Invoke(this, new());
|
||||
}
|
||||
|
||||
#region ICommand
|
||||
/// <summary>
|
||||
/// 能否被执行
|
||||
/// </summary>
|
||||
/// <param name="parameter">参数</param>
|
||||
/// <returns>能被执行为 <see langword="true"/> 否则为 <see langword="false"/></returns>
|
||||
public bool CanExecute(object? parameter)
|
||||
{
|
||||
return CurrentCanExecute && IsCanExecute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行方法
|
||||
/// </summary>
|
||||
/// <param name="parameter">参数</param>
|
||||
public async void Execute(object? parameter)
|
||||
{
|
||||
if (IsCanExecute is not true)
|
||||
return;
|
||||
ExecuteCommand?.Invoke((T)parameter!);
|
||||
await ExecuteAsync((T)parameter!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行异步方法, 会在等待中修改 <see cref="CurrentCanExecute"/>, 完成后恢复
|
||||
/// <para>
|
||||
/// 若要在执行此方法时触发 <see cref="ExecuteCommand"/> 事件, 请将 <paramref name="runAlone"/> 设置为 <see langword="true"/>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="parameter">参数</param>
|
||||
/// <param name="runAlone">设置为 <see langword="true"/> 时触发 <see cref="ExecuteCommand"/> 事件</param>
|
||||
/// <returns>任务</returns>
|
||||
public async Task ExecuteAsync(T parameter, bool runAlone = false)
|
||||
{
|
||||
if (IsCanExecute is not true)
|
||||
return;
|
||||
if (runAlone)
|
||||
ExecuteCommand?.Invoke(parameter);
|
||||
if (ExecuteAsyncCommand is null)
|
||||
return;
|
||||
CurrentCanExecute = false;
|
||||
foreach (
|
||||
var asyncEvent in ExecuteAsyncCommand
|
||||
.GetInvocationList()
|
||||
.Cast<ExecuteAsyncEventHandler<T>>()
|
||||
)
|
||||
await asyncEvent.Invoke(parameter);
|
||||
CurrentCanExecute = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
/// <summary>
|
||||
/// 能否执行属性改变后事件
|
||||
/// </summary>
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 执行事件
|
||||
/// </summary>
|
||||
public event ExecuteEventHandler<T>? ExecuteCommand;
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行事件
|
||||
/// </summary>
|
||||
public event ExecuteAsyncEventHandler<T>? ExecuteAsyncCommand;
|
||||
#endregion
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 通知发送者属性改变接收器
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="eventSender">属性改变事件发送者</param>
|
||||
public delegate void NotifySenderPropertyChangedHandler<T>(
|
||||
ObservableValue<T> sender,
|
||||
INotifyPropertyChanged? eventSender
|
||||
);
|
@ -1,231 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DebuggerDisplay("\\{ObservableValue, Value = {Value}\\}")]
|
||||
public class ObservableValue<T>
|
||||
: INotifyPropertyChanging,
|
||||
INotifyPropertyChanged,
|
||||
IEquatable<ObservableValue<T>>
|
||||
{
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private T _value = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public T Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
if (_value?.Equals(value) is true)
|
||||
return;
|
||||
var oldValue = _value;
|
||||
if (NotifyPropertyChanging(oldValue, value))
|
||||
return;
|
||||
_value = value;
|
||||
NotifyPropertyChanged(oldValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 包含值
|
||||
/// </summary>
|
||||
public bool HasValue => Value != null;
|
||||
|
||||
/// <summary>
|
||||
/// 分组
|
||||
/// </summary>
|
||||
public ObservableValueGroup<T>? Group { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 唯一标识符
|
||||
/// </summary>
|
||||
public Guid Guid { get; } = Guid.NewGuid();
|
||||
|
||||
#region Ctor
|
||||
/// <inheritdoc/>
|
||||
public ObservableValue() { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="value">初始值</param>
|
||||
public ObservableValue(T value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NotifyProperty
|
||||
/// <summary>
|
||||
/// 通知属性改变前
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
/// <returns>取消改变</returns>
|
||||
private bool NotifyPropertyChanging(T oldValue, T newValue)
|
||||
{
|
||||
PropertyChanging?.Invoke(this, new(nameof(Value)));
|
||||
var args = new ValueChangingEventArgs<T>(oldValue, newValue);
|
||||
ValueChanging?.Invoke(this, args);
|
||||
// 取消改变后通知UI更改
|
||||
if (args.Cancel)
|
||||
PropertyChanged?.Invoke(this, new(nameof(Value)));
|
||||
return args.Cancel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知属性改变后
|
||||
/// </summary>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
private void NotifyPropertyChanged(T oldValue, T newValue)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new(nameof(Value)));
|
||||
ValueChanged?.Invoke(this, new(oldValue, newValue));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NotifySender
|
||||
/// <summary>
|
||||
/// 通知发送者
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<INotifyPropertyChanged> NotifySenders => _notifySenders;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private readonly HashSet<INotifyPropertyChanged> _notifySenders = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加通知发送者
|
||||
/// <para>
|
||||
/// 添加的发送者改变后会执行 <see cref="SenderPropertyChanged"/>
|
||||
/// </para>
|
||||
/// <para>示例:
|
||||
/// <code><![CDATA[
|
||||
/// ObservableValue<string> value1 = new();
|
||||
/// ObservableValue<string> value2 = new();
|
||||
/// value2.AddNotifySender(value1);
|
||||
/// value2.SenderPropertyChanged += (source, sender) =>
|
||||
/// {
|
||||
/// source.Value = sender.Value;
|
||||
/// };
|
||||
/// value1.Value = "A";
|
||||
/// // value1.Value == "A", value2.Value == "A"
|
||||
/// ]]>
|
||||
/// </code></para>
|
||||
/// </summary>
|
||||
/// <param name="items">发送者</param>
|
||||
public void AddNotifySender(params INotifyPropertyChanged[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.PropertyChanged -= NotifySenderPropertyChanged;
|
||||
item.PropertyChanged += NotifySenderPropertyChanged;
|
||||
_notifySenders.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除通知发送者
|
||||
/// </summary>
|
||||
/// <param name="items">发送者</param>
|
||||
public void RemoveNotifySender(params INotifyPropertyChanged[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.PropertyChanged -= NotifySenderPropertyChanged;
|
||||
_notifySenders.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空通知发送者
|
||||
/// </summary>
|
||||
public void ClearNotifySender()
|
||||
{
|
||||
foreach (var sender in _notifySenders)
|
||||
sender.PropertyChanged -= NotifySenderPropertyChanged;
|
||||
_notifySenders.Clear();
|
||||
}
|
||||
|
||||
private void NotifySenderPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
SenderPropertyChanged?.Invoke(this, (INotifyPropertyChanged)sender!);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return Value?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value?.GetHashCode() ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservableValue<T> value
|
||||
&& EqualityComparer<T>.Default.Equals(Value, value.Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableValue<T>? other)
|
||||
{
|
||||
return Equals(obj: other);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator ==(ObservableValue<T> a, ObservableValue<T> b)
|
||||
{
|
||||
return a.Equals(obj: b);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator !=(ObservableValue<T> a, ObservableValue<T> b)
|
||||
{
|
||||
return a.Equals(obj: b) is not true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变前事件
|
||||
/// </summary>
|
||||
public event PropertyChangingEventHandler? PropertyChanging;
|
||||
|
||||
/// <summary>
|
||||
/// 属性改变后事件
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变前事件
|
||||
/// </summary>
|
||||
public event ValueChangingEventHandler<T>? ValueChanging;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件
|
||||
/// </summary>
|
||||
public event ValueChangedEventHandler<T>? ValueChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 通知接收事件
|
||||
/// </summary>
|
||||
public event NotifySenderPropertyChangedHandler<T>? SenderPropertyChanged;
|
||||
#endregion
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察值组合
|
||||
/// <para>示例:<code><![CDATA[
|
||||
/// var value1 = new ObservableValue<string>();
|
||||
/// var value2 = new ObservableValue<string>();
|
||||
/// var group = new ObservableValueGroup<string>() { value1, value2 };
|
||||
/// value1.Value = "A";
|
||||
/// // value1 == "A", value2 == "A"
|
||||
/// group.Remove(value1);
|
||||
/// value1.Value = "C";
|
||||
/// // value1 == "C", value2 == "A"]]></code></para>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
[DebuggerDisplay("\\{ObservableValueGroup, Count = {Count}\\}")]
|
||||
public class ObservableValueGroup<T> : IEnumerable<ObservableValue<T>?>
|
||||
{
|
||||
/// <summary>
|
||||
/// 数量
|
||||
/// </summary>
|
||||
public int Count => _bindingValues.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 在添加的时候改变值 (如果分组中存在值)
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool ChangeOnAdd { get; set; } = false;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private readonly Dictionary<Guid, WeakReference<ObservableValue<T>>> _bindingValues = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加项
|
||||
/// </summary>
|
||||
/// <param name="items">项</param>
|
||||
public void Add(params ObservableValue<T>[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
AddToGroup(item);
|
||||
}
|
||||
|
||||
private void AddToGroup(ObservableValue<T> item)
|
||||
{
|
||||
if (item.Group is not null)
|
||||
throw new ArgumentException("item Group must be null", nameof(item));
|
||||
_bindingValues.Add(item.Guid, new(item));
|
||||
item.ValueChanged -= Item_ValueChanged;
|
||||
if (ChangeOnAdd)
|
||||
{
|
||||
foreach (var bindingValue in _bindingValues)
|
||||
{
|
||||
if (bindingValue.Value.TryGetTarget(out var target))
|
||||
{
|
||||
item.Value = target.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
item.ValueChanged += Item_ValueChanged;
|
||||
item.Group = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除项
|
||||
/// </summary>
|
||||
/// <param name="items">项</param>
|
||||
public void Remove(params ObservableValue<T>[] items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
RemoveFromGroup(item);
|
||||
}
|
||||
|
||||
private void RemoveFromGroup(ObservableValue<T> item)
|
||||
{
|
||||
var result = _bindingValues.Remove(item.Guid);
|
||||
if (result)
|
||||
{
|
||||
item.ValueChanged -= Item_ValueChanged;
|
||||
item.Group = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空分组
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var bindingValue in _bindingValues)
|
||||
{
|
||||
if (bindingValue.Value.TryGetTarget(out var target))
|
||||
{
|
||||
target.ValueChanged -= Item_ValueChanged;
|
||||
target.Group = null;
|
||||
}
|
||||
}
|
||||
_bindingValues.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找项
|
||||
/// </summary>
|
||||
/// <param name="item">项</param>
|
||||
/// <returns>包含为 <see langword="true"/> 不包含为 <see langword="false"/></returns>
|
||||
public bool Contains(ObservableValue<T> item)
|
||||
{
|
||||
return _bindingValues.ContainsKey(item.Guid);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerator<ObservableValue<T>?> GetEnumerator()
|
||||
{
|
||||
return _bindingValues
|
||||
.Values.Select(v => v.TryGetTarget(out var t) ? t : null)
|
||||
.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _onChange = false;
|
||||
|
||||
private void Item_ValueChanged(ObservableValue<T> sender, ValueChangedEventArgs<T> e)
|
||||
{
|
||||
if (_onChange)
|
||||
return;
|
||||
_onChange = true;
|
||||
foreach (var bindingValue in _bindingValues.AsEnumerable())
|
||||
{
|
||||
if (bindingValue.Value.TryGetTarget(out var target))
|
||||
target.Value = e.NewValue!;
|
||||
else
|
||||
_bindingValues.Remove(bindingValue.Key);
|
||||
}
|
||||
_onChange = false;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件参数
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
public class ValueChangedEventArgs<T> : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 旧值
|
||||
/// </summary>
|
||||
public T? OldValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 新值
|
||||
/// </summary>
|
||||
public T? NewValue { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public ValueChangedEventArgs(T oldValue, T newValue)
|
||||
{
|
||||
OldValue = oldValue;
|
||||
NewValue = newValue;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变后事件
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="e">参数</param>
|
||||
public delegate void ValueChangedEventHandler<T>(
|
||||
ObservableValue<T> sender,
|
||||
ValueChangedEventArgs<T> e
|
||||
);
|
@ -1,29 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变前事件参数
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值类型</typeparam>
|
||||
public class ValueChangingEventArgs<T> : CancelEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 旧值
|
||||
/// </summary>
|
||||
public T? OldValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 新值
|
||||
/// </summary>
|
||||
public T? NewValue { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <param name="oldValue">旧值</param>
|
||||
/// <param name="newValue">新值</param>
|
||||
public ValueChangingEventArgs(T? oldValue, T? newValue)
|
||||
{
|
||||
OldValue = oldValue;
|
||||
NewValue = newValue;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
namespace HKW.HKWUtils.Observable;
|
||||
|
||||
/// <summary>
|
||||
/// 值改变前事件
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="e">参数</param>
|
||||
public delegate void ValueChangingEventHandler<T>(
|
||||
ObservableValue<T> sender,
|
||||
ValueChangingEventArgs<T> e
|
||||
);
|
@ -21,17 +21,17 @@ namespace HKW.HKWUtils;
|
||||
/// </summary>
|
||||
public static class NativeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="comparisonType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Contains(this string source, string value, StringComparison comparisonType)
|
||||
{
|
||||
return source.IndexOf(value, comparisonType) >= 0;
|
||||
}
|
||||
///// <summary>
|
||||
/////
|
||||
///// </summary>
|
||||
///// <param name="source"></param>
|
||||
///// <param name="value"></param>
|
||||
///// <param name="comparisonType"></param>
|
||||
///// <returns></returns>
|
||||
//public static bool Contains(this string source, string value, StringComparison comparisonType)
|
||||
//{
|
||||
// return source.IndexOf(value, comparisonType) >= 0;
|
||||
//}
|
||||
|
||||
//public static string GetSourceFile(this BitmapImage image)
|
||||
//{
|
@ -1,81 +0,0 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HKW.HKWUtils;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察的枚举标签模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
public class ObservableEnumFlags<T> : ObservableClass<ObservableEnumFlags<T>>
|
||||
where T : Enum
|
||||
{
|
||||
private T _EnumValue;
|
||||
public T EnumValue
|
||||
{
|
||||
get => _EnumValue;
|
||||
set => SetProperty(ref _EnumValue, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加枚举命令
|
||||
/// </summary>
|
||||
public ObservableCommand<T> AddCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除枚举命令
|
||||
/// </summary>
|
||||
public ObservableCommand<T> RemoveCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 枚举类型
|
||||
/// </summary>
|
||||
public Type EnumType = typeof(T);
|
||||
|
||||
/// <summary>
|
||||
/// 枚举基类
|
||||
/// </summary>
|
||||
public Type UnderlyingType { get; } = Enum.GetUnderlyingType(typeof(T));
|
||||
|
||||
public ObservableEnumFlags()
|
||||
{
|
||||
if (Attribute.IsDefined(EnumType, typeof(FlagsAttribute)) is false)
|
||||
throw new Exception($"此枚举类型未使用特性 [{nameof(FlagsAttribute)}]");
|
||||
AddCommand.ExecuteCommand += AddCommand_Execute;
|
||||
RemoveCommand.ExecuteCommand += RemoveCommand_Execute;
|
||||
}
|
||||
|
||||
public ObservableEnumFlags(T value)
|
||||
: this()
|
||||
{
|
||||
EnumValue = value;
|
||||
}
|
||||
|
||||
private void AddCommand_Execute(T v)
|
||||
{
|
||||
if (UnderlyingType == typeof(int))
|
||||
{
|
||||
EnumValue = (T)
|
||||
Enum.Parse(EnumType, (Convert.ToInt32(EnumValue) | Convert.ToInt32(v)).ToString());
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException($"Value type: {UnderlyingType}");
|
||||
}
|
||||
|
||||
private void RemoveCommand_Execute(T v)
|
||||
{
|
||||
if (UnderlyingType == typeof(int))
|
||||
{
|
||||
EnumValue = (T)
|
||||
Enum.Parse(EnumType, (Convert.ToInt32(EnumValue) & ~Convert.ToInt32(v)).ToString());
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException($"Value type: {UnderlyingType}");
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace HKW.HKWUtils;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察地点
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class ObservablePoint<T>
|
||||
: ObservableClass<ObservablePoint<T>>,
|
||||
IEquatable<ObservablePoint<T>>
|
||||
{
|
||||
private T _x;
|
||||
public T X
|
||||
{
|
||||
get => _x;
|
||||
set => SetProperty(ref _x, value);
|
||||
}
|
||||
|
||||
private T _y;
|
||||
public T Y
|
||||
{
|
||||
get => _y;
|
||||
set => SetProperty(ref _y, value);
|
||||
}
|
||||
|
||||
public ObservablePoint() { }
|
||||
|
||||
public ObservablePoint(T x, T y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制一个新的对象
|
||||
/// </summary>
|
||||
/// <returns>新对象</returns>
|
||||
public ObservablePoint<T> Copy()
|
||||
{
|
||||
return new(X, Y);
|
||||
}
|
||||
|
||||
#region Other
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(X, Y);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservablePoint<T> temp
|
||||
&& EqualityComparer<T>.Default.Equals(X, temp.X)
|
||||
&& EqualityComparer<T>.Default.Equals(Y, temp.Y);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservablePoint<T>? other)
|
||||
{
|
||||
return Equals(obj: other);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator ==(ObservablePoint<T> a, ObservablePoint<T> b)
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator !=(ObservablePoint<T> a, ObservablePoint<T> b)
|
||||
{
|
||||
return a.Equals(b) is not true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
using HKW.HKWUtils;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace HKW.HKWUtils;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察的范围
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class ObservableRange<T>
|
||||
: ObservableClass<ObservableRange<T>>,
|
||||
IEquatable<ObservableRange<T>>
|
||||
{
|
||||
private T _min;
|
||||
public T Min
|
||||
{
|
||||
get => _min;
|
||||
set => SetProperty(ref _min, value);
|
||||
}
|
||||
|
||||
private T _max;
|
||||
public T Max
|
||||
{
|
||||
get => _max;
|
||||
set => SetProperty(ref _max, value);
|
||||
}
|
||||
|
||||
public ObservableRange() { }
|
||||
|
||||
public ObservableRange(T min, T max)
|
||||
{
|
||||
_min = min;
|
||||
_max = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制一个新的对象
|
||||
/// </summary>
|
||||
/// <returns>新对象</returns>
|
||||
public ObservableRange<T> Copy()
|
||||
{
|
||||
return new(Min, Max);
|
||||
}
|
||||
|
||||
#region Other
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Min, Max);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservableRange<T> temp
|
||||
&& EqualityComparer<T>.Default.Equals(Min, temp.Min)
|
||||
&& EqualityComparer<T>.Default.Equals(Max, temp.Max);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableRange<T>? other)
|
||||
{
|
||||
return Equals(obj: other);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator ==(ObservableRange<T> a, ObservableRange<T> b)
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator !=(ObservableRange<T> a, ObservableRange<T> b)
|
||||
{
|
||||
return a.Equals(b) is not true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
namespace HKW.HKWUtils;
|
||||
|
||||
public class ObservableRect<T> : ObservableClass<ObservableRect<T>>, IEquatable<ObservableRect<T>>
|
||||
{
|
||||
private T _x;
|
||||
public T X
|
||||
{
|
||||
get => _x;
|
||||
set => SetProperty(ref _x, value);
|
||||
}
|
||||
|
||||
private T _y;
|
||||
public T Y
|
||||
{
|
||||
get => _y;
|
||||
set => SetProperty(ref _y, value);
|
||||
}
|
||||
|
||||
private T _width;
|
||||
public T Width
|
||||
{
|
||||
get => _width;
|
||||
set => SetProperty(ref _width, value);
|
||||
}
|
||||
|
||||
private T _heigth;
|
||||
public T Height
|
||||
{
|
||||
get => _heigth;
|
||||
set => SetProperty(ref _heigth, value);
|
||||
}
|
||||
|
||||
public ObservableRect() { }
|
||||
|
||||
public ObservableRect(T x, T y, T width, T hetght)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = hetght;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制一个新的对象
|
||||
/// </summary>
|
||||
/// <returns>新对象</returns>
|
||||
public ObservableRect<T> Copy()
|
||||
{
|
||||
return new(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
#region Other
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ObservableRect<T> temp
|
||||
&& EqualityComparer<T>.Default.Equals(X, temp.X)
|
||||
&& EqualityComparer<T>.Default.Equals(Y, temp.Y)
|
||||
&& EqualityComparer<T>.Default.Equals(Width, temp.Width)
|
||||
&& EqualityComparer<T>.Default.Equals(Height, temp.Height);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ObservableRect<T>? other)
|
||||
{
|
||||
return Equals(obj: other);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator ==(ObservableRect<T> a, ObservableRect<T> b)
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static bool operator !=(ObservableRect<T> a, ObservableRect<T> b)
|
||||
{
|
||||
return a.Equals(b) is not true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -25,4 +25,10 @@
|
||||
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="HKW.Utils" Version="1.2.2" />
|
||||
<PackageReference Include="HKW.WPF" Version="1.0.3" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,23 +1,32 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit;
|
||||
|
||||
public class AddCultureWindowVM
|
||||
public class AddCultureWindowVM : ObservableObjectX<AddCultureWindowVM>
|
||||
{
|
||||
/// <summary>
|
||||
/// 显示的文化
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<string>> ShowCultures { get; } = new();
|
||||
#region ShowCultures
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<string> _showCultures;
|
||||
|
||||
public ObservableCollection<string> ShowCultures
|
||||
{
|
||||
get => _showCultures;
|
||||
set => SetProperty(ref _showCultures, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 全部文化
|
||||
@ -28,25 +37,53 @@ public class AddCultureWindowVM
|
||||
/// <summary>
|
||||
/// 当前文化
|
||||
/// </summary>
|
||||
public ObservableValue<string> Culture { get; } = new();
|
||||
#region Culture
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _culture;
|
||||
|
||||
public string Culture
|
||||
{
|
||||
get => _culture;
|
||||
set => SetProperty(ref _culture, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 当前文化全名
|
||||
/// </summary>
|
||||
public ObservableValue<string> CultureFullName { get; } = new(UnknownCulture);
|
||||
#region CultureFullName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _cultureFullName;
|
||||
|
||||
public string CultureFullName
|
||||
{
|
||||
get => _cultureFullName;
|
||||
set => SetProperty(ref _cultureFullName, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 搜索文化
|
||||
/// </summary>
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _Search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _Search;
|
||||
set => SetProperty(ref _Search, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static string UnknownCulture = "未知文化".Translate();
|
||||
|
||||
public AddCultureWindowVM()
|
||||
{
|
||||
ShowCultures.Value = AllCultures;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
Culture.ValueChanged += Culture_ValueChanged;
|
||||
//TODO
|
||||
//ShowCultures = AllCultures;
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
//Culture.ValueChanged += Culture_ValueChanged;
|
||||
}
|
||||
|
||||
private void Culture_ValueChanged(
|
||||
@ -56,7 +93,7 @@ public class AddCultureWindowVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
CultureFullName.Value = UnknownCulture;
|
||||
CultureFullName = UnknownCulture;
|
||||
return;
|
||||
}
|
||||
CultureInfo info = null!;
|
||||
@ -66,11 +103,11 @@ public class AddCultureWindowVM
|
||||
}
|
||||
catch
|
||||
{
|
||||
CultureFullName.Value = UnknownCulture;
|
||||
CultureFullName = UnknownCulture;
|
||||
}
|
||||
if (info is not null)
|
||||
{
|
||||
CultureFullName.Value = info.GetFullInfo();
|
||||
CultureFullName = info.GetFullInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,11 +118,11 @@ public class AddCultureWindowVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowCultures.Value = AllCultures;
|
||||
ShowCultures = AllCultures;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCultures.Value = new(
|
||||
ShowCultures = new(
|
||||
AllCultures.Where(s => s.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -18,7 +19,7 @@ using static VPet_Simulator.Core.IGameSave;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimeEditWindowVM
|
||||
public class AnimeEditWindowVM : ObservableObjectX<AnimeEditWindowVM>
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
@ -35,35 +36,81 @@ public class AnimeEditWindowVM
|
||||
/// </summary>
|
||||
public ObservableValue<AnimeTypeModel> Anime { get; } = new(new());
|
||||
|
||||
#region CurrentImageModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ImageModel _currentImageModel;
|
||||
|
||||
/// <summary>
|
||||
/// 当前图像模型
|
||||
/// </summary>
|
||||
public ObservableValue<ImageModel> CurrentImageModel { get; } = new();
|
||||
public ImageModel CurrentImageModel
|
||||
{
|
||||
get => _currentImageModel;
|
||||
set => SetProperty(ref _currentImageModel, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CurrentAnimeModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private AnimeModel _currentAnimeModel;
|
||||
|
||||
/// <summary>
|
||||
/// 当前动画模型
|
||||
/// </summary>
|
||||
public ObservableValue<AnimeModel> CurrentAnimeModel { get; } = new();
|
||||
|
||||
public AnimeModel CurrentAnimeModel
|
||||
{
|
||||
get => _currentAnimeModel;
|
||||
set => SetProperty(ref _currentAnimeModel, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 当前模式
|
||||
/// </summary>
|
||||
public ModeType CurrentMode { get; set; }
|
||||
|
||||
#region Loop
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _loop;
|
||||
|
||||
/// <summary>
|
||||
/// 循环
|
||||
/// </summary>
|
||||
public ObservableValue<bool> Loop { get; } = new();
|
||||
public bool Loop
|
||||
{
|
||||
get => _loop;
|
||||
set => SetProperty(ref _loop, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HasMultiType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _hasMultiType;
|
||||
|
||||
/// <summary>
|
||||
/// 含有多个状态 参见 <see cref="AnimeTypeModel.HasMultiTypeAnimes"/>
|
||||
/// </summary>
|
||||
public ObservableValue<bool> HasMultiType { get; } = new(false);
|
||||
public bool HasMultiType
|
||||
{
|
||||
get => _hasMultiType;
|
||||
set => SetProperty(ref _hasMultiType, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HasAnimeName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _hasAnimeName;
|
||||
|
||||
/// <summary>
|
||||
/// 含有动画名称 参见 <see cref="AnimeTypeModel.HasNameAnimes"/>
|
||||
/// </summary>
|
||||
public ObservableValue<bool> HasAnimeName { get; } = new(false);
|
||||
public bool HasAnimeName
|
||||
{
|
||||
get => _hasAnimeName;
|
||||
set => SetProperty(ref _hasAnimeName, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
/// <summary>
|
||||
@ -120,8 +167,8 @@ public class AnimeEditWindowVM
|
||||
public AnimeEditWindowVM()
|
||||
{
|
||||
_playerTask = new(Play);
|
||||
|
||||
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||
//TODO
|
||||
//CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||
|
||||
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||
@ -146,11 +193,11 @@ public class AnimeEditWindowVM
|
||||
|
||||
private void CheckGraphType(AnimeTypeModel model)
|
||||
{
|
||||
if (AnimeTypeModel.HasMultiTypeAnimes.Contains(model.GraphType.Value))
|
||||
HasMultiType.Value = true;
|
||||
if (AnimeTypeModel.HasMultiTypeAnimes.Contains(model.GraphType))
|
||||
HasMultiType = true;
|
||||
|
||||
if (AnimeTypeModel.HasNameAnimes.Contains(model.GraphType.Value))
|
||||
HasAnimeName.Value = true;
|
||||
if (AnimeTypeModel.HasNameAnimes.Contains(model.GraphType))
|
||||
HasAnimeName = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -221,8 +268,8 @@ public class AnimeEditWindowVM
|
||||
/// <param name="value">动画模型</param>
|
||||
private void RemoveImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
CurrentImageModel.Value.Close();
|
||||
value.Images.Remove(CurrentImageModel.Value);
|
||||
CurrentImageModel.Close();
|
||||
value.Images.Remove(CurrentImageModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -248,8 +295,8 @@ public class AnimeEditWindowVM
|
||||
}
|
||||
if (newImage is null)
|
||||
return;
|
||||
CurrentImageModel.Value.Close();
|
||||
CurrentImageModel.Value.Image.Value = newImage;
|
||||
CurrentImageModel.Close();
|
||||
CurrentImageModel.Image = newImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -331,7 +378,7 @@ public class AnimeEditWindowVM
|
||||
/// </summary>
|
||||
private async Task PlayCommand_AsyncExecuteEvent()
|
||||
{
|
||||
if (CurrentAnimeModel.Value is null)
|
||||
if (CurrentAnimeModel is null)
|
||||
{
|
||||
MessageBox.Show("未选中动画".Translate());
|
||||
return;
|
||||
@ -349,14 +396,14 @@ public class AnimeEditWindowVM
|
||||
{
|
||||
do
|
||||
{
|
||||
foreach (var model in CurrentAnimeModel.Value.Images)
|
||||
foreach (var model in CurrentAnimeModel.Images)
|
||||
{
|
||||
CurrentImageModel.Value = model;
|
||||
Task.Delay(model.Duration.Value).Wait();
|
||||
CurrentImageModel = model;
|
||||
Task.Delay(model.Duration).Wait();
|
||||
if (_playing is false)
|
||||
return;
|
||||
}
|
||||
} while (Loop.Value);
|
||||
} while (Loop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,22 +1,22 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Panuon.WPF.UI;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Panuon.WPF.UI;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet.ModMaker.Views.ModEdit.AnimeEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimePageVM
|
||||
public class AnimePageVM : ObservableObjectX<AnimePageVM>
|
||||
{
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
@ -24,7 +24,16 @@ public class AnimePageVM
|
||||
/// <summary>
|
||||
/// 显示的动画
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<object>> ShowAnimes { get; } = new();
|
||||
#region ShowAnimes
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<object> _showAnimes;
|
||||
|
||||
public ObservableCollection<object> ShowAnimes
|
||||
{
|
||||
get => _showAnimes;
|
||||
set => SetProperty(ref _showAnimes, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 所有动画
|
||||
@ -51,10 +60,19 @@ public class AnimePageVM
|
||||
/// </summary>
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
/// <summary>
|
||||
/// 搜索
|
||||
/// </summary>
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
/// <summary>
|
||||
@ -74,9 +92,10 @@ public class AnimePageVM
|
||||
#endregion
|
||||
public AnimePageVM()
|
||||
{
|
||||
ShowAnimes.Value = AllAnimes;
|
||||
ShowAnimes = AllAnimes;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
@ -110,7 +129,7 @@ public class AnimePageVM
|
||||
)
|
||||
{
|
||||
InitializeAllAnimes();
|
||||
ShowAnimes.Value = AllAnimes;
|
||||
ShowAnimes = AllAnimes;
|
||||
}
|
||||
|
||||
private void Search_ValueChanged(
|
||||
@ -120,20 +139,20 @@ public class AnimePageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowAnimes.Value = AllAnimes;
|
||||
ShowAnimes = AllAnimes;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowAnimes.Value = new(
|
||||
ShowAnimes = new(
|
||||
AllAnimes.Where(m =>
|
||||
{
|
||||
if (m is AnimeTypeModel animeTypeModel)
|
||||
return animeTypeModel.Id.Value.Contains(
|
||||
return animeTypeModel.Id.Contains(
|
||||
e.NewValue,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
else if (m is FoodAnimeTypeModel foodAnimeTypeModel)
|
||||
return foodAnimeTypeModel.Id.Value.Contains(
|
||||
return foodAnimeTypeModel.Id.Contains(
|
||||
e.NewValue,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
@ -164,7 +183,7 @@ public class AnimePageVM
|
||||
var window = new FoodAnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.Anime.Value.Name.Value = animeName;
|
||||
vm.Anime.Value.Name = animeName;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
@ -175,8 +194,8 @@ public class AnimePageVM
|
||||
var window = new AnimeEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.Anime.Value.GraphType.Value = graphType;
|
||||
vm.Anime.Value.Name.Value = animeName;
|
||||
vm.Anime.Value.GraphType = graphType;
|
||||
vm.Anime.Value.Name = animeName;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
@ -203,8 +222,8 @@ public class AnimePageVM
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Animes[Animes.IndexOf(animeTypeModel)] = newAnime;
|
||||
if (ShowAnimes.Value.Count != Animes.Count)
|
||||
ShowAnimes.Value[ShowAnimes.Value.IndexOf(animeTypeModel)] = newAnime;
|
||||
if (ShowAnimes.Count != Animes.Count)
|
||||
ShowAnimes[ShowAnimes.IndexOf(animeTypeModel)] = newAnime;
|
||||
}
|
||||
else if (model is FoodAnimeTypeModel foodAnimeTypeModel)
|
||||
{
|
||||
@ -218,8 +237,8 @@ public class AnimePageVM
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
FoodAnimes[FoodAnimes.IndexOf(foodAnimeTypeModel)] = newAnime;
|
||||
if (ShowAnimes.Value.Count != FoodAnimes.Count)
|
||||
ShowAnimes.Value[ShowAnimes.Value.IndexOf(foodAnimeTypeModel)] = newAnime;
|
||||
if (ShowAnimes.Count != FoodAnimes.Count)
|
||||
ShowAnimes[ShowAnimes.IndexOf(foodAnimeTypeModel)] = newAnime;
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +250,7 @@ public class AnimePageVM
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
ShowAnimes.Value.Remove(model);
|
||||
ShowAnimes.Remove(model);
|
||||
if (model is AnimeTypeModel animeTypeModel)
|
||||
{
|
||||
Animes.Remove(animeTypeModel);
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@ -17,7 +18,7 @@ using static VPet_Simulator.Core.IGameSave;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class FoodAnimeEditWindowVM
|
||||
public class FoodAnimeEditWindowVM : ObservableObjectX<FoodAnimeEditWindowVM>
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
@ -30,15 +31,33 @@ public class FoodAnimeEditWindowVM
|
||||
public static BitmapImage DefaultFoodImage { get; } =
|
||||
NativeUtils.LoadImageToMemoryStream(NativeResources.GetStream(NativeResources.FoodImage));
|
||||
|
||||
#region FoodImage
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _foodImage;
|
||||
|
||||
/// <summary>
|
||||
/// 食物图片
|
||||
/// </summary>
|
||||
public ObservableValue<BitmapImage> FoodImage { get; } = new(DefaultFoodImage);
|
||||
public BitmapImage FoodImage
|
||||
{
|
||||
get => _foodImage;
|
||||
set => SetProperty(ref _foodImage, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LengthRatio
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _lengthRatio;
|
||||
|
||||
/// <summary>
|
||||
/// 比例
|
||||
/// </summary>
|
||||
public ObservableValue<double> LengthRatio { get; } = new(250.0 / 500.0);
|
||||
public double LengthRatio
|
||||
{
|
||||
get => _lengthRatio;
|
||||
set => SetProperty(ref _lengthRatio, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 旧动画
|
||||
@ -50,45 +69,108 @@ public class FoodAnimeEditWindowVM
|
||||
/// </summary>
|
||||
public ObservableValue<FoodAnimeTypeModel> Anime { get; } = new(new());
|
||||
|
||||
#region CurrentFrontImageModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ImageModel _currentFrontImageModel;
|
||||
|
||||
/// <summary>
|
||||
/// 当前顶层图像模型
|
||||
/// </summary>
|
||||
public ObservableValue<ImageModel> CurrentFrontImageModel { get; } = new();
|
||||
public ImageModel CurrentFrontImageModel
|
||||
{
|
||||
get => _currentFrontImageModel;
|
||||
set => SetProperty(ref _currentFrontImageModel, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CurrentBackImageModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ImageModel _currentBackImageModel;
|
||||
|
||||
/// <summary>
|
||||
/// 当前底层图像模型
|
||||
/// </summary>
|
||||
public ObservableValue<ImageModel> CurrentBackImageModel { get; } = new();
|
||||
public ImageModel CurrentBackImageModel
|
||||
{
|
||||
get => _currentBackImageModel;
|
||||
set => SetProperty(ref _currentBackImageModel, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CurrentFoodLocationModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private FoodLocationModel _currentFoodLocationModel;
|
||||
|
||||
/// <summary>
|
||||
/// 当前食物定位模型
|
||||
/// </summary>
|
||||
public ObservableValue<FoodLocationModel> CurrentFoodLocationModel { get; } = new();
|
||||
public FoodLocationModel CurrentFoodLocationModel
|
||||
{
|
||||
get => _currentFoodLocationModel;
|
||||
set => SetProperty(ref _currentFoodLocationModel, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CurrentAnimeModel
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private FoodAnimeModel _currentAnimeModel;
|
||||
|
||||
/// <summary>
|
||||
/// 当前动画模型
|
||||
/// </summary>
|
||||
public ObservableValue<FoodAnimeModel> CurrentAnimeModel { get; } = new();
|
||||
public FoodAnimeModel CurrentAnimeModel
|
||||
{
|
||||
get => _currentAnimeModel;
|
||||
set => SetProperty(ref _currentAnimeModel, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 当前模式
|
||||
/// </summary>
|
||||
public ModeType CurrentMode { get; set; }
|
||||
|
||||
#region Loop
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _loop;
|
||||
|
||||
/// <summary>
|
||||
/// 循环
|
||||
/// </summary>
|
||||
public ObservableValue<bool> Loop { get; } = new();
|
||||
public bool Loop
|
||||
{
|
||||
get => _loop;
|
||||
set => SetProperty(ref _loop, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HasMultiType
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _hasMultiType;
|
||||
|
||||
/// <summary>
|
||||
/// 含有多个状态 参见 <see cref="AnimeTypeModel.HasMultiTypeAnimes"/>
|
||||
/// </summary>
|
||||
public ObservableValue<bool> HasMultiType { get; } = new(false);
|
||||
public bool HasMultiType
|
||||
{
|
||||
get => _hasMultiType;
|
||||
set => SetProperty(ref _hasMultiType, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HasAnimeName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _hasAnimeName;
|
||||
|
||||
/// <summary>
|
||||
/// 含有动画名称 参见 <see cref="AnimeTypeModel.HasNameAnimes"/>
|
||||
/// </summary>
|
||||
public ObservableValue<bool> HasAnimeName { get; } = new(false);
|
||||
public bool HasAnimeName
|
||||
{
|
||||
get => _hasAnimeName;
|
||||
set => SetProperty(ref _hasAnimeName, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
/// <summary>
|
||||
@ -207,8 +289,8 @@ public class FoodAnimeEditWindowVM
|
||||
_frontPlayerTask = new(FrontPlay);
|
||||
_backPlayerTask = new(BackPlay);
|
||||
_foodPlayerTask = new(FoodPlay);
|
||||
|
||||
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||
//TODO
|
||||
//CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
|
||||
|
||||
PlayCommand.ExecuteAsyncCommand += PlayCommand_AsyncExecuteEvent;
|
||||
StopCommand.ExecuteCommand += StopCommand_ExecuteEvent;
|
||||
@ -235,9 +317,9 @@ public class FoodAnimeEditWindowVM
|
||||
|
||||
private void ResetFoodImageCommand_ExecuteEvent()
|
||||
{
|
||||
if (FoodImage.Value != DefaultFoodImage)
|
||||
FoodImage.Value.CloseStream();
|
||||
FoodImage.Value = DefaultFoodImage;
|
||||
if (FoodImage != DefaultFoodImage)
|
||||
FoodImage.CloseStream();
|
||||
FoodImage = DefaultFoodImage;
|
||||
}
|
||||
|
||||
private void ChangeFoodImageCommand_ExecuteEvent()
|
||||
@ -246,9 +328,9 @@ public class FoodAnimeEditWindowVM
|
||||
new() { Title = "选择食物图片".Translate(), Filter = $"图片|*.png".Translate() };
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
if (FoodImage.Value != DefaultFoodImage)
|
||||
FoodImage.Value.CloseStream();
|
||||
FoodImage.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
if (FoodImage != DefaultFoodImage)
|
||||
FoodImage.CloseStream();
|
||||
FoodImage = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,8 +413,8 @@ public class FoodAnimeEditWindowVM
|
||||
/// <param name="value">动画模型</param>
|
||||
private void RemoveFrontImageCommand_ExecuteEvent(FoodAnimeModel value)
|
||||
{
|
||||
CurrentFrontImageModel.Value.Close();
|
||||
value.FrontImages.Remove(CurrentFrontImageModel.Value);
|
||||
CurrentFrontImageModel.Close();
|
||||
value.FrontImages.Remove(CurrentFrontImageModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -374,8 +456,8 @@ public class FoodAnimeEditWindowVM
|
||||
}
|
||||
if (newImage is null)
|
||||
return;
|
||||
CurrentFrontImageModel.Value.Close();
|
||||
CurrentFrontImageModel.Value.Image.Value = newImage;
|
||||
CurrentFrontImageModel.Close();
|
||||
CurrentFrontImageModel.Image = newImage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -405,8 +487,8 @@ public class FoodAnimeEditWindowVM
|
||||
/// <param name="value">动画模型</param>
|
||||
private void RemoveBackImageCommand_ExecuteEvent(FoodAnimeModel value)
|
||||
{
|
||||
CurrentBackImageModel.Value.Close();
|
||||
value.BackImages.Remove(CurrentBackImageModel.Value);
|
||||
CurrentBackImageModel.Close();
|
||||
value.BackImages.Remove(CurrentBackImageModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -448,8 +530,8 @@ public class FoodAnimeEditWindowVM
|
||||
}
|
||||
if (newImage is null)
|
||||
return;
|
||||
CurrentBackImageModel.Value.Close();
|
||||
CurrentBackImageModel.Value.Image.Value = newImage;
|
||||
CurrentBackImageModel.Close();
|
||||
CurrentBackImageModel.Image = newImage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -494,8 +576,8 @@ public class FoodAnimeEditWindowVM
|
||||
|
||||
private void RemoveFoodLocationCommand_ExecuteEvent(FoodAnimeModel value)
|
||||
{
|
||||
value.FoodLocations.Remove(CurrentFoodLocationModel.Value);
|
||||
CurrentFoodLocationModel.Value = null;
|
||||
value.FoodLocations.Remove(CurrentFoodLocationModel);
|
||||
CurrentFoodLocationModel = null;
|
||||
}
|
||||
|
||||
private void ClearFoodLocationCommand_ExecuteEvent(FoodAnimeModel value)
|
||||
@ -547,7 +629,7 @@ public class FoodAnimeEditWindowVM
|
||||
/// </summary>
|
||||
private async Task PlayCommand_AsyncExecuteEvent()
|
||||
{
|
||||
if (CurrentAnimeModel.Value is null)
|
||||
if (CurrentAnimeModel is null)
|
||||
{
|
||||
MessageBox.Show("未选中动画".Translate());
|
||||
return;
|
||||
@ -562,7 +644,7 @@ public class FoodAnimeEditWindowVM
|
||||
_frontPlayerTask = new(FrontPlay);
|
||||
_backPlayerTask = new(BackPlay);
|
||||
_foodPlayerTask = new(FoodPlay);
|
||||
} while (Loop.Value && _playing);
|
||||
} while (Loop && _playing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -570,10 +652,10 @@ public class FoodAnimeEditWindowVM
|
||||
/// </summary>
|
||||
private void FrontPlay()
|
||||
{
|
||||
foreach (var model in CurrentAnimeModel.Value.FrontImages)
|
||||
foreach (var model in CurrentAnimeModel.FrontImages)
|
||||
{
|
||||
CurrentFrontImageModel.Value = model;
|
||||
Task.Delay(model.Duration.Value).Wait();
|
||||
CurrentFrontImageModel = model;
|
||||
Task.Delay(model.Duration).Wait();
|
||||
if (_playing is false)
|
||||
return;
|
||||
}
|
||||
@ -584,10 +666,10 @@ public class FoodAnimeEditWindowVM
|
||||
/// </summary>
|
||||
private void BackPlay()
|
||||
{
|
||||
foreach (var model in CurrentAnimeModel.Value.BackImages)
|
||||
foreach (var model in CurrentAnimeModel.BackImages)
|
||||
{
|
||||
CurrentBackImageModel.Value = model;
|
||||
Task.Delay(model.Duration.Value).Wait();
|
||||
CurrentBackImageModel = model;
|
||||
Task.Delay(model.Duration).Wait();
|
||||
if (_playing is false)
|
||||
return;
|
||||
}
|
||||
@ -598,10 +680,10 @@ public class FoodAnimeEditWindowVM
|
||||
/// </summary>
|
||||
private void FoodPlay()
|
||||
{
|
||||
foreach (var model in CurrentAnimeModel.Value.FoodLocations)
|
||||
foreach (var model in CurrentAnimeModel.FoodLocations)
|
||||
{
|
||||
CurrentFoodLocationModel.Value = model;
|
||||
Task.Delay(model.Duration.Value).Wait();
|
||||
CurrentFoodLocationModel = model;
|
||||
Task.Delay(model.Duration).Wait();
|
||||
if (_playing is false)
|
||||
return;
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.ClickTextEdit;
|
||||
|
||||
public class ClickTextEditWindowVM
|
||||
public class ClickTextEditWindowVM : ObservableObjectX<ClickTextEditWindowVM>
|
||||
{
|
||||
public I18nHelper I18nData => I18nHelper.Current;
|
||||
|
||||
@ -20,10 +21,19 @@ public class ClickTextEditWindowVM
|
||||
/// </summary>
|
||||
public ClickTextModel OldClickText { get; set; }
|
||||
|
||||
#region ClickText
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ClickTextModel _clickText = new();
|
||||
|
||||
/// <summary>
|
||||
/// 点击文本
|
||||
/// </summary>
|
||||
public ObservableValue<ClickTextModel> ClickText { get; } = new(new());
|
||||
public ClickTextModel ClickText
|
||||
{
|
||||
get => _clickText;
|
||||
set => SetProperty(ref _clickText, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
public ClickTextEditWindowVM() { }
|
||||
}
|
||||
|
@ -1,35 +1,53 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Views.ModEdit.ClickTextEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.ClickTextEdit;
|
||||
|
||||
public class ClickTextPageVM
|
||||
public class ClickTextPageVM : ObservableObjectX<ClickTextPageVM>
|
||||
{
|
||||
#region Value
|
||||
#region ShowClickTexts
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<ClickTextModel> _showClickTexts;
|
||||
|
||||
/// <summary>
|
||||
/// 显示的点击文本
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<ClickTextModel>> ShowClickTexts { get; } = new();
|
||||
public ObservableCollection<ClickTextModel> ShowClickTexts
|
||||
{
|
||||
get => _showClickTexts;
|
||||
set => SetProperty(ref _showClickTexts, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 点击文本
|
||||
/// </summary>
|
||||
public ObservableCollection<ClickTextModel> ClickTexts => ModInfoModel.Current.ClickTexts;
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
/// <summary>
|
||||
/// 搜索
|
||||
/// </summary>
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
/// <summary>
|
||||
@ -50,8 +68,9 @@ public class ClickTextPageVM
|
||||
|
||||
public ClickTextPageVM()
|
||||
{
|
||||
ShowClickTexts.Value = ClickTexts;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
ShowClickTexts = ClickTexts;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
@ -64,14 +83,12 @@ public class ClickTextPageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowClickTexts.Value = ClickTexts;
|
||||
ShowClickTexts = ClickTexts;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowClickTexts.Value = new(
|
||||
ClickTexts.Where(
|
||||
m => m.Id.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
ShowClickTexts = new(
|
||||
ClickTexts.Where(m => m.Id.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -86,7 +103,7 @@ public class ClickTextPageVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
ClickTexts.Add(vm.ClickText.Value);
|
||||
ClickTexts.Add(vm.ClickText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -98,13 +115,13 @@ public class ClickTextPageVM
|
||||
var window = new ClickTextEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.OldClickText = model;
|
||||
var newLowTest = vm.ClickText.Value = new(model);
|
||||
var newLowTest = vm.ClickText = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
ClickTexts[ClickTexts.IndexOf(model)] = newLowTest;
|
||||
if (ShowClickTexts.Value.Count != ClickTexts.Count)
|
||||
ShowClickTexts.Value[ShowClickTexts.Value.IndexOf(model)] = newLowTest;
|
||||
if (ShowClickTexts.Count != ClickTexts.Count)
|
||||
ShowClickTexts[ShowClickTexts.IndexOf(model)] = newLowTest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -115,13 +132,13 @@ public class ClickTextPageVM
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowClickTexts.Value.Count == ClickTexts.Count)
|
||||
if (ShowClickTexts.Count == ClickTexts.Count)
|
||||
{
|
||||
ClickTexts.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowClickTexts.Value.Remove(model);
|
||||
ShowClickTexts.Remove(model);
|
||||
ClickTexts.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@ -14,13 +15,23 @@ using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.FoodEdit;
|
||||
|
||||
public class FoodEditWindowVM
|
||||
public class FoodEditWindowVM : ObservableObjectX<FoodEditWindowVM>
|
||||
{
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
#region Value
|
||||
public FoodModel OldFood { get; set; }
|
||||
public ObservableValue<FoodModel> Food { get; } = new(new());
|
||||
|
||||
#region Food
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private FoodModel _food;
|
||||
|
||||
public FoodModel Food
|
||||
{
|
||||
get => _food;
|
||||
set => SetProperty(ref _food, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
@ -34,7 +45,8 @@ public class FoodEditWindowVM
|
||||
AddImageCommand.ExecuteCommand += AddImage;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImage;
|
||||
SetReferencePriceCommand.ExecuteCommand += SetReferencePriceToPrice;
|
||||
Food.Value.ReferencePrice.ValueChanged += ReferencePrice_ValueChanged;
|
||||
//TODO
|
||||
//Food.Value.ReferencePrice.ValueChanged += ReferencePrice_ValueChanged;
|
||||
}
|
||||
|
||||
private void ReferencePrice_ValueChanged(
|
||||
@ -42,7 +54,7 @@ public class FoodEditWindowVM
|
||||
ValueChangedEventArgs<double> e
|
||||
)
|
||||
{
|
||||
if (ModInfo.AutoSetFoodPrice.Value)
|
||||
if (ModInfo.AutoSetFoodPrice)
|
||||
{
|
||||
SetReferencePriceToPrice(e.NewValue);
|
||||
}
|
||||
@ -50,12 +62,12 @@ public class FoodEditWindowVM
|
||||
|
||||
private void SetReferencePriceToPrice(double value)
|
||||
{
|
||||
Food.Value.Price.Value = value;
|
||||
Food.Price = value;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Food.Value.Close();
|
||||
Food.Close();
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
@ -68,7 +80,7 @@ public class FoodEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Food.Value.Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Food.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,8 +94,8 @@ public class FoodEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Food.Value.Image.Value?.StreamSource?.Close();
|
||||
Food.Value.Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Food.Image?.StreamSource?.Close();
|
||||
Food.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,45 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Views.ModEdit.FoodEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.FoodEdit;
|
||||
|
||||
public class FoodPageVM
|
||||
public class FoodPageVM : ObservableObjectX<FoodPageVM>
|
||||
{
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<FoodModel>> ShowFoods { get; } = new();
|
||||
#region ShowFoods
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<FoodModel> _showFoods;
|
||||
|
||||
public ObservableCollection<FoodModel> ShowFoods
|
||||
{
|
||||
get => _showFoods;
|
||||
set => SetProperty(ref _showFoods, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<FoodModel> Foods => ModInfoModel.Current.Foods;
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
@ -29,8 +48,9 @@ public class FoodPageVM
|
||||
#endregion
|
||||
public FoodPageVM()
|
||||
{
|
||||
ShowFoods.Value = Foods;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
ShowFoods = Foods;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
@ -44,14 +64,12 @@ public class FoodPageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowFoods.Value = Foods;
|
||||
ShowFoods = Foods;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowFoods.Value = new(
|
||||
Foods.Where(
|
||||
m => m.Id.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
ShowFoods = new(
|
||||
Foods.Where(m => m.Id.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -65,7 +83,7 @@ public class FoodPageVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Foods.Add(vm.Food.Value);
|
||||
Foods.Add(vm.Food);
|
||||
}
|
||||
|
||||
public void Edit(FoodModel food)
|
||||
@ -73,13 +91,13 @@ public class FoodPageVM
|
||||
var window = new FoodEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.OldFood = food;
|
||||
var newFood = vm.Food.Value = new(food);
|
||||
var newFood = vm.Food = new(food);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Foods[Foods.IndexOf(food)] = newFood;
|
||||
if (ShowFoods.Value.Count != Foods.Count)
|
||||
ShowFoods.Value[ShowFoods.Value.IndexOf(food)] = newFood;
|
||||
if (ShowFoods.Count != Foods.Count)
|
||||
ShowFoods[ShowFoods.IndexOf(food)] = newFood;
|
||||
food.Close();
|
||||
}
|
||||
|
||||
@ -87,13 +105,13 @@ public class FoodPageVM
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowFoods.Value.Count == Foods.Count)
|
||||
if (ShowFoods.Count == Foods.Count)
|
||||
{
|
||||
Foods.Remove(food);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowFoods.Value.Remove(food);
|
||||
ShowFoods.Remove(food);
|
||||
Foods.Remove(food);
|
||||
}
|
||||
}
|
||||
|
@ -1,500 +1,523 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.I18nEdit;
|
||||
|
||||
public class I18nEditWindowVM
|
||||
{
|
||||
/// <summary>
|
||||
/// 搜索
|
||||
/// </summary>
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
public class I18nEditWindowVM : ObservableObjectX<I18nEditWindowVM> { }
|
||||
//{
|
||||
// #region Search
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
// private string _search;
|
||||
|
||||
/// <summary>
|
||||
/// 全部I18n数据 (Id, I18nData)
|
||||
/// </summary>
|
||||
public Dictionary<string, I18nData> AllI18nDatas { get; } = new();
|
||||
// /// <summary>
|
||||
// /// 搜索
|
||||
// /// </summary>
|
||||
// public string Search
|
||||
// {
|
||||
// get => _search;
|
||||
// set => SetProperty(ref _search, value);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
/// <summary>
|
||||
/// 全部I18n数据
|
||||
/// </summary>
|
||||
public ObservableCollection<I18nData> I18nDatas { get; } = new();
|
||||
// /// <summary>
|
||||
// /// 全部I18n数据 (Id, I18nData)
|
||||
// /// </summary>
|
||||
// public Dictionary<string, I18nData> AllI18nDatas { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 显示的I18n数据
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<I18nData>> ShowI18nDatas { get; } = new();
|
||||
// /// <summary>
|
||||
// /// 全部I18n数据
|
||||
// /// </summary>
|
||||
// public ObservableCollection<I18nData> I18nDatas { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 搜索目标列表
|
||||
/// </summary>
|
||||
public ObservableCollection<string> SearchTargets { get; } = new() { nameof(ModInfoModel.Id) };
|
||||
// /// <summary>
|
||||
// /// 显示的I18n数据
|
||||
// /// </summary>
|
||||
// #region ShowI18nDatas
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
// private ObservableCollection<I18nData> _showI18nDatas;
|
||||
|
||||
/// <summary>
|
||||
/// 搜索目标
|
||||
/// </summary>
|
||||
public ObservableValue<string> SearchTarget { get; } = new();
|
||||
// public ObservableCollection<I18nData> ShowI18nDatas
|
||||
// {
|
||||
// get => _showI18nDatas;
|
||||
// set => SetProperty(ref _showI18nDatas, value);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
public I18nEditWindowVM()
|
||||
{
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
ShowI18nDatas.Value = I18nDatas;
|
||||
SearchTarget.Value = nameof(ModInfoModel.Id);
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 搜索目标列表
|
||||
// /// </summary>
|
||||
// public ObservableCollection<string> SearchTargets { get; } = new() { nameof(ModInfoModel.Id) };
|
||||
|
||||
/// <summary>
|
||||
/// 搜索改变事件
|
||||
/// </summary>
|
||||
/// <param name="oldValue"></param>
|
||||
/// <param name="newValue"></param>
|
||||
private void Search_ValueChanged(
|
||||
ObservableValue<string> sender,
|
||||
ValueChangedEventArgs<string> e
|
||||
)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowI18nDatas.Value = I18nDatas;
|
||||
}
|
||||
else if (SearchTarget.Value == nameof(ModInfoModel.Id))
|
||||
{
|
||||
ShowI18nDatas.Value = new(
|
||||
I18nDatas.Where(
|
||||
m =>
|
||||
m.Id.Value?.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase) is true
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cultureIndex = I18nHelper.Current.CultureNames.IndexOf(SearchTarget.Value);
|
||||
ShowI18nDatas.Value = new(
|
||||
I18nDatas.Where(
|
||||
m =>
|
||||
m.Datas[cultureIndex].Value?.Contains(
|
||||
e.NewValue,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
is true
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 搜索目标
|
||||
// /// </summary>
|
||||
// #region SearchTarget
|
||||
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
// private string _searchTarget;
|
||||
|
||||
/// <summary>
|
||||
/// 文化列表改变事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void CultureNames_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
var newCulture = (string)e.NewItems[0];
|
||||
AddCulture(newCulture);
|
||||
SearchTargets.Add(newCulture);
|
||||
foreach (var data in AllI18nDatas)
|
||||
data.Value.Datas.Add(new());
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
var oldCulture = (string)e.OldItems[0];
|
||||
RemoveCulture(oldCulture);
|
||||
SearchTargets.Remove(oldCulture);
|
||||
foreach (var data in AllI18nDatas)
|
||||
{
|
||||
var value = data.Value.Datas[e.OldStartingIndex];
|
||||
value.Group?.Remove(value);
|
||||
data.Value.Datas.RemoveAt(e.OldStartingIndex);
|
||||
}
|
||||
if (SearchTarget.Value is null)
|
||||
SearchTarget.Value = nameof(ModInfoModel.Id);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
{
|
||||
var oldCulture = (string)e.OldItems[0];
|
||||
var newCulture = (string)e.NewItems[0];
|
||||
ReplaceCulture(oldCulture, newCulture);
|
||||
SearchTargets[SearchTargets.IndexOf(oldCulture)] = newCulture;
|
||||
}
|
||||
}
|
||||
// public string SearchTarget
|
||||
// {
|
||||
// get => _searchTarget;
|
||||
// set => SetProperty(ref _searchTarget, value);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region LoadData
|
||||
/// <summary>
|
||||
/// 初始化I18n数据
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void InitializeI18nData(ModInfoModel model)
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
AddCulture(culture);
|
||||
SearchTargets.Add(culture);
|
||||
}
|
||||
try
|
||||
{
|
||||
LoadFood(model);
|
||||
LoadClickText(model);
|
||||
LoadLowText(model);
|
||||
LoadSelectText(model);
|
||||
LoadPets(model);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Close();
|
||||
throw;
|
||||
}
|
||||
I18nHelper.Current.CultureNames.CollectionChanged -= CultureNames_CollectionChanged;
|
||||
I18nHelper.Current.CultureNames.CollectionChanged += CultureNames_CollectionChanged;
|
||||
}
|
||||
// public I18nEditWindowVM()
|
||||
// {
|
||||
// //Search.ValueChanged += Search_ValueChanged;// TODO
|
||||
// ShowI18nDatas = I18nDatas;
|
||||
// SearchTarget = nameof(ModInfoModel.Id);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 载入食物
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
private void LoadFood(ModInfoModel model)
|
||||
{
|
||||
foreach (var food in model.Foods)
|
||||
{
|
||||
AddData(food.Id, food, (m) => m.Name);
|
||||
AddData(food.DescriptionId, food, (m) => m.Description);
|
||||
}
|
||||
model.Foods.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
var newModel = (FoodModel)e.NewItems[0];
|
||||
AddData(newModel.Id, newModel, (m) => m.Name);
|
||||
AddData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
var oldModel = (FoodModel)e.OldItems[0];
|
||||
RemoveData(oldModel.Id, oldModel, (m) => m.Name);
|
||||
RemoveData(oldModel.DescriptionId, oldModel, (m) => m.Description);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
{
|
||||
var newModel = (FoodModel)e.NewItems[0];
|
||||
var oldModel = (FoodModel)e.OldItems[0];
|
||||
ReplaceData(newModel.Id, newModel, (m) => m.Name);
|
||||
ReplaceData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
}
|
||||
};
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 搜索改变事件
|
||||
// /// </summary>
|
||||
// /// <param name="oldValue"></param>
|
||||
// /// <param name="newValue"></param>
|
||||
// private void Search_ValueChanged(
|
||||
// ObservableValue<string> sender,
|
||||
// ValueChangedEventArgs<string> e
|
||||
// )
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
// {
|
||||
// ShowI18nDatas = I18nDatas;
|
||||
// }
|
||||
// else if (SearchTarget == nameof(ModInfoModel.Id))
|
||||
// {
|
||||
// ShowI18nDatas = new(
|
||||
// I18nDatas.Where(m =>
|
||||
// m.Id?.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase) is true
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var cultureIndex = I18nHelper.Current.CultureNames.IndexOf(SearchTarget);
|
||||
// ShowI18nDatas = new(
|
||||
// I18nDatas.Where(m =>
|
||||
// m.Datas[cultureIndex]
|
||||
// .Value?.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
// is true
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 载入点击文本
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
private void LoadClickText(ModInfoModel model)
|
||||
{
|
||||
foreach (var text in model.ClickTexts)
|
||||
{
|
||||
AddData(text.Id, text, (m) => m.Text);
|
||||
}
|
||||
model.ClickTexts.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
var newModel = (ClickTextModel)e.NewItems[0];
|
||||
AddData(newModel.Id, newModel, (m) => m.Text);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
var oldModel = (ClickTextModel)e.OldItems[0];
|
||||
RemoveData(oldModel.Id, oldModel, (m) => m.Text);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
{
|
||||
var newModel = (ClickTextModel)e.NewItems[0];
|
||||
var oldModel = (ClickTextModel)e.OldItems[0];
|
||||
ReplaceData(newModel.Id, newModel, (m) => m.Text);
|
||||
}
|
||||
};
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 文化列表改变事件
|
||||
// /// </summary>
|
||||
// /// <param name="sender"></param>
|
||||
// /// <param name="e"></param>
|
||||
// private void CultureNames_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// var newCulture = (string)e.NewItems[0];
|
||||
// AddCulture(newCulture);
|
||||
// SearchTargets.Add(newCulture);
|
||||
// foreach (var data in AllI18nDatas)
|
||||
// data.Value.Datas.Add(new());
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// var oldCulture = (string)e.OldItems[0];
|
||||
// RemoveCulture(oldCulture);
|
||||
// SearchTargets.Remove(oldCulture);
|
||||
// foreach (var data in AllI18nDatas)
|
||||
// {
|
||||
// var value = data.Value.Datas[e.OldStartingIndex];
|
||||
// value.Group?.Remove(value);
|
||||
// data.Value.Datas.RemoveAt(e.OldStartingIndex);
|
||||
// }
|
||||
// if (SearchTarget is null)
|
||||
// SearchTarget = nameof(ModInfoModel.Id);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
// {
|
||||
// var oldCulture = (string)e.OldItems[0];
|
||||
// var newCulture = (string)e.NewItems[0];
|
||||
// ReplaceCulture(oldCulture, newCulture);
|
||||
// SearchTargets[SearchTargets.IndexOf(oldCulture)] = newCulture;
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 载入低状态为文本
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
private void LoadLowText(ModInfoModel model)
|
||||
{
|
||||
foreach (var text in model.LowTexts)
|
||||
{
|
||||
AddData(text.Id, text, (m) => m.Text);
|
||||
}
|
||||
model.LowTexts.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
var newModel = (LowTextModel)e.NewItems[0];
|
||||
AddData(newModel.Id, newModel, (m) => m.Text);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
var oldModel = (LowTextModel)e.OldItems[0];
|
||||
RemoveData(oldModel.Id, oldModel, (m) => m.Text);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
{
|
||||
var newModel = (LowTextModel)e.NewItems[0];
|
||||
var oldModel = (LowTextModel)e.OldItems[0];
|
||||
ReplaceData(newModel.Id, newModel, (m) => m.Text);
|
||||
}
|
||||
};
|
||||
}
|
||||
// #region LoadData
|
||||
// /// <summary>
|
||||
// /// 初始化I18n数据
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// public void InitializeI18nData(ModInfoModel model)
|
||||
// {
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
// {
|
||||
// AddCulture(culture);
|
||||
// SearchTargets.Add(culture);
|
||||
// }
|
||||
// try
|
||||
// {
|
||||
// LoadFood(model);
|
||||
// LoadClickText(model);
|
||||
// LoadLowText(model);
|
||||
// LoadSelectText(model);
|
||||
// LoadPets(model);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// Close();
|
||||
// throw;
|
||||
// }
|
||||
// I18nHelper.Current.CultureNames.CollectionChanged -= CultureNames_CollectionChanged;
|
||||
// I18nHelper.Current.CultureNames.CollectionChanged += CultureNames_CollectionChanged;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 载入选择文本
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
private void LoadSelectText(ModInfoModel model)
|
||||
{
|
||||
foreach (var text in model.SelectTexts)
|
||||
{
|
||||
AddData(text.Id, text, (m) => m.Text);
|
||||
AddData(text.ChooseId, text, (m) => m.Choose);
|
||||
}
|
||||
model.SelectTexts.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
var newModel = (SelectTextModel)e.NewItems[0];
|
||||
AddData(newModel.Id, newModel, (m) => m.Text);
|
||||
AddData(newModel.ChooseId, newModel, (m) => m.Choose);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
var oldModel = (SelectTextModel)e.OldItems[0];
|
||||
RemoveData(oldModel.Id, oldModel, (m) => m.Text);
|
||||
RemoveData(oldModel.ChooseId, oldModel, (m) => m.Choose);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
{
|
||||
var newModel = (SelectTextModel)e.NewItems[0];
|
||||
var oldModel = (SelectTextModel)e.OldItems[0];
|
||||
ReplaceData(newModel.Id, newModel, (m) => m.Text);
|
||||
ReplaceData(newModel.ChooseId, newModel, (m) => m.Choose);
|
||||
}
|
||||
};
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 载入食物
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// private void LoadFood(ModInfoModel model)
|
||||
// {
|
||||
// foreach (var food in model.Foods)
|
||||
// {
|
||||
// AddData(food.Id, food, (m) => m.Name);
|
||||
// AddData(food.DescriptionId, food, (m) => m.Description);
|
||||
// }
|
||||
// model.Foods.CollectionChanged += (s, e) =>
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// var newModel = (FoodModel)e.NewItems[0];
|
||||
// AddData(newModel.Id, newModel, (m) => m.Name);
|
||||
// AddData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// var oldModel = (FoodModel)e.OldItems[0];
|
||||
// RemoveData(oldModel.Id, oldModel, (m) => m.Name);
|
||||
// RemoveData(oldModel.DescriptionId, oldModel, (m) => m.Description);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
// {
|
||||
// var newModel = (FoodModel)e.NewItems[0];
|
||||
// var oldModel = (FoodModel)e.OldItems[0];
|
||||
// ReplaceData(newModel.Id, newModel, (m) => m.Name);
|
||||
// ReplaceData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 载入宠物
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void LoadPets(ModInfoModel model)
|
||||
{
|
||||
foreach (var pet in model.Pets)
|
||||
{
|
||||
if (pet.FromMain.Value)
|
||||
continue;
|
||||
AddData(pet.Id, pet, (m) => m.Name);
|
||||
AddData(pet.PetNameId, pet, (m) => m.PetName);
|
||||
AddData(pet.DescriptionId, pet, (m) => m.Description);
|
||||
foreach (var work in pet.Works)
|
||||
AddData(work.Id, work, (m) => m.Name);
|
||||
}
|
||||
model.Pets.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
var newModel = (PetModel)e.NewItems[0];
|
||||
AddData(newModel.Id, newModel, (m) => m.Name);
|
||||
AddData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
foreach (var work in newModel.Works)
|
||||
AddData(work.Id, work, (m) => m.Name);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
var oldModel = (PetModel)e.OldItems[0];
|
||||
if (oldModel.FromMain.Value)
|
||||
return;
|
||||
RemoveData(oldModel.Id, oldModel, (m) => m.Name);
|
||||
RemoveData(oldModel.DescriptionId, oldModel, (m) => m.Description);
|
||||
foreach (var work in oldModel.Works)
|
||||
RemoveData(work.Id, work, (m) => m.Name);
|
||||
}
|
||||
else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
{
|
||||
var newModel = (PetModel)e.NewItems[0];
|
||||
var oldModel = (PetModel)e.OldItems[0];
|
||||
ReplaceData(newModel.Id, newModel, (m) => m.Name);
|
||||
ReplaceData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
foreach (var work in newModel.Works)
|
||||
ReplaceData(work.Id, work, (m) => m.Name);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
// /// <summary>
|
||||
// /// 载入点击文本
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// private void LoadClickText(ModInfoModel model)
|
||||
// {
|
||||
// foreach (var text in model.ClickTexts)
|
||||
// {
|
||||
// AddData(text.Id, text, (m) => m.Text);
|
||||
// }
|
||||
// model.ClickTexts.CollectionChanged += (s, e) =>
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// var newModel = (ClickTextModel)e.NewItems[0];
|
||||
// AddData(newModel.Id, newModel, (m) => m.Text);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// var oldModel = (ClickTextModel)e.OldItems[0];
|
||||
// RemoveData(oldModel.Id, oldModel, (m) => m.Text);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
// {
|
||||
// var newModel = (ClickTextModel)e.NewItems[0];
|
||||
// var oldModel = (ClickTextModel)e.OldItems[0];
|
||||
// ReplaceData(newModel.Id, newModel, (m) => m.Text);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
#region DatEdit
|
||||
/// <summary>
|
||||
/// 添加数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="i18nModel"></param>
|
||||
/// <param name="i18nValue"></param>
|
||||
private void AddData<T>(
|
||||
ObservableValue<string> id,
|
||||
I18nModel<T> i18nModel,
|
||||
Func<T, ObservableValue<string>> i18nValue
|
||||
)
|
||||
where T : class, new()
|
||||
{
|
||||
if (AllI18nDatas.TryGetValue(id.Value, out var outData))
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>() { outData.Datas[culture.Index] };
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(
|
||||
i18nValue(i18nModel.I18nDatas[culture.Value])
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new I18nData();
|
||||
data.Id.Value = id.Value;
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
data.Datas.Add(i18nValue(i18nModel.I18nDatas[culture]));
|
||||
I18nDatas.Add(data);
|
||||
AllI18nDatas.Add(id.Value, data);
|
||||
//id.ValueChanged += IdChange;
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 载入低状态为文本
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// private void LoadLowText(ModInfoModel model)
|
||||
// {
|
||||
// foreach (var text in model.LowTexts)
|
||||
// {
|
||||
// AddData(text.Id, text, (m) => m.Text);
|
||||
// }
|
||||
// model.LowTexts.CollectionChanged += (s, e) =>
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// var newModel = (LowTextModel)e.NewItems[0];
|
||||
// AddData(newModel.Id, newModel, (m) => m.Text);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// var oldModel = (LowTextModel)e.OldItems[0];
|
||||
// RemoveData(oldModel.Id, oldModel, (m) => m.Text);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
// {
|
||||
// var newModel = (LowTextModel)e.NewItems[0];
|
||||
// var oldModel = (LowTextModel)e.OldItems[0];
|
||||
// ReplaceData(newModel.Id, newModel, (m) => m.Text);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Id改变
|
||||
/// </summary>
|
||||
/// <param name="oldValue"></param>
|
||||
/// <param name="newValue"></param>
|
||||
private void IdChange(ObservableValue<string> sender, ValueChangedEventArgs<string> e)
|
||||
{
|
||||
var sourceData = AllI18nDatas[e.OldValue];
|
||||
sourceData.Id.Group?.Remove(sourceData.Id);
|
||||
if (AllI18nDatas.TryGetValue(e.OldValue, out var outData))
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
{
|
||||
if (outData.Datas[culture.Index].Group is null)
|
||||
{
|
||||
var group = new ObservableValueGroup<string>() { outData.Datas[culture.Index] };
|
||||
}
|
||||
outData.Datas[culture.Index].Group!.Add(sourceData.Datas[culture.Index]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceData.Id.Value = e.NewValue;
|
||||
AllI18nDatas.Remove(e.OldValue);
|
||||
AllI18nDatas.Add(e.NewValue, sourceData);
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 载入选择文本
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// private void LoadSelectText(ModInfoModel model)
|
||||
// {
|
||||
// foreach (var text in model.SelectTexts)
|
||||
// {
|
||||
// AddData(text.Id, text, (m) => m.Text);
|
||||
// AddData(text.ChooseId, text, (m) => m.Choose);
|
||||
// }
|
||||
// model.SelectTexts.CollectionChanged += (s, e) =>
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// var newModel = (SelectTextModel)e.NewItems[0];
|
||||
// AddData(newModel.Id, newModel, (m) => m.Text);
|
||||
// AddData(newModel.ChooseId, newModel, (m) => m.Choose);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// var oldModel = (SelectTextModel)e.OldItems[0];
|
||||
// RemoveData(oldModel.Id, oldModel, (m) => m.Text);
|
||||
// RemoveData(oldModel.ChooseId, oldModel, (m) => m.Choose);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
// {
|
||||
// var newModel = (SelectTextModel)e.NewItems[0];
|
||||
// var oldModel = (SelectTextModel)e.OldItems[0];
|
||||
// ReplaceData(newModel.Id, newModel, (m) => m.Text);
|
||||
// ReplaceData(newModel.ChooseId, newModel, (m) => m.Choose);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 删除I18n数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="i18nModel"></param>
|
||||
/// <param name="i18nValue"></param>
|
||||
private void RemoveData<T>(
|
||||
ObservableValue<string> id,
|
||||
I18nModel<T> i18nModel,
|
||||
Func<T, ObservableValue<string>> i18nValue
|
||||
)
|
||||
where T : class, new()
|
||||
{
|
||||
var data = AllI18nDatas[id.Value];
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
{
|
||||
if (data.Datas[culture.Index].Group is ObservableValueGroup<string> group)
|
||||
{
|
||||
group.Remove(i18nValue(i18nModel.I18nDatas[culture.Value]));
|
||||
if (group.Count == 1)
|
||||
{
|
||||
group.Clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
I18nDatas.Remove(data);
|
||||
AllI18nDatas.Remove(id.Value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 载入宠物
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// public void LoadPets(ModInfoModel model)
|
||||
// {
|
||||
// foreach (var pet in model.Pets)
|
||||
// {
|
||||
// if (pet.FromMain.Value)
|
||||
// continue;
|
||||
// AddData(pet.ID, pet, (m) => m.Name);
|
||||
// AddData(pet.PetNameId, pet, (m) => m.PetName);
|
||||
// AddData(pet.DescriptionId, pet, (m) => m.Description);
|
||||
// foreach (var work in pet.Works)
|
||||
// AddData(work.Id, work, (m) => m.Name);
|
||||
// }
|
||||
// model.Pets.CollectionChanged += (s, e) =>
|
||||
// {
|
||||
// if (e.Action is NotifyCollectionChangedAction.Add)
|
||||
// {
|
||||
// var newModel = (PetModel)e.NewItems[0];
|
||||
// AddData(newModel.ID, newModel, (m) => m.Name);
|
||||
// AddData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
// foreach (var work in newModel.Works)
|
||||
// AddData(work.Id, work, (m) => m.Name);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Remove)
|
||||
// {
|
||||
// var oldModel = (PetModel)e.OldItems[0];
|
||||
// if (oldModel.FromMain.Value)
|
||||
// return;
|
||||
// RemoveData(oldModel.ID, oldModel, (m) => m.Name);
|
||||
// RemoveData(oldModel.DescriptionId, oldModel, (m) => m.Description);
|
||||
// foreach (var work in oldModel.Works)
|
||||
// RemoveData(work.Id, work, (m) => m.Name);
|
||||
// }
|
||||
// else if (e.Action is NotifyCollectionChangedAction.Replace)
|
||||
// {
|
||||
// var newModel = (PetModel)e.NewItems[0];
|
||||
// var oldModel = (PetModel)e.OldItems[0];
|
||||
// ReplaceData(newModel.ID, newModel, (m) => m.Name);
|
||||
// ReplaceData(newModel.DescriptionId, newModel, (m) => m.Description);
|
||||
// foreach (var work in newModel.Works)
|
||||
// ReplaceData(work.Id, work, (m) => m.Name);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
/// <summary>
|
||||
/// 替换I18n数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="i18nModel"></param>
|
||||
/// <param name="i18nValue"></param>
|
||||
private void ReplaceData<T>(
|
||||
ObservableValue<string> id,
|
||||
I18nModel<T> i18nModel,
|
||||
Func<T, ObservableValue<string>> i18nValue
|
||||
)
|
||||
where T : class, new()
|
||||
{
|
||||
var data = AllI18nDatas[id.Value];
|
||||
foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
{
|
||||
var oldValue = data.Datas[culture.Index];
|
||||
var newValue = i18nValue(i18nModel.I18nDatas[culture.Value]);
|
||||
if (oldValue.Group is ObservableValueGroup<string> group)
|
||||
{
|
||||
group.Add(newValue);
|
||||
group.Remove(oldValue);
|
||||
}
|
||||
data.Datas[culture.Index] = newValue;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
// #region DatEdit
|
||||
// /// <summary>
|
||||
// /// 添加数据
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <param name="id"></param>
|
||||
// /// <param name="i18nModel"></param>
|
||||
// /// <param name="i18nValue"></param>
|
||||
// private void AddData<T>(
|
||||
// ObservableValue<string> id,
|
||||
// I18nModel<T> i18nModel,
|
||||
// Func<T, ObservableValue<string>> i18nValue
|
||||
// )
|
||||
// where T : class, new()
|
||||
// {
|
||||
// if (AllI18nDatas.TryGetValue(id.Value, out var outData))
|
||||
// {
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
// {
|
||||
// if (outData.Datas[culture.Index].Group is null)
|
||||
// {
|
||||
// var group = new ObservableValueGroup<string>() { outData.Datas[culture.Index] };
|
||||
// }
|
||||
// outData
|
||||
// .Datas[culture.Index]
|
||||
// .Group!.Add(i18nValue(i18nModel.I18nDatas[culture.Value]));
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var data = new I18nData();
|
||||
// data.Id = id.Value;
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
// data.Datas.Add(i18nValue(i18nModel.I18nDatas[culture]));
|
||||
// I18nDatas.Add(data);
|
||||
// AllI18nDatas.Add(id.Value, data);
|
||||
// //id.ValueChanged += IdChange;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void Close()
|
||||
{
|
||||
I18nHelper.Current.CultureNames.CollectionChanged -= CultureNames_CollectionChanged;
|
||||
foreach (var i18nData in AllI18nDatas)
|
||||
{
|
||||
foreach (var data in i18nData.Value.Datas)
|
||||
data.Group?.Clear();
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// Id改变
|
||||
// /// </summary>
|
||||
// /// <param name="oldValue"></param>
|
||||
// /// <param name="newValue"></param>
|
||||
// private void IdChange(ObservableValue<string> sender, ValueChangedEventArgs<string> e)
|
||||
// {
|
||||
// var sourceData = AllI18nDatas[e.OldValue];
|
||||
// //sourceData.Id.Group?.Remove(sourceData.Id); //TODO
|
||||
// if (AllI18nDatas.TryGetValue(e.OldValue, out var outData))
|
||||
// {
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
// {
|
||||
// if (outData.Datas[culture.Index].Group is null)
|
||||
// {
|
||||
// var group = new ObservableValueGroup<string>() { outData.Datas[culture.Index] };
|
||||
// }
|
||||
// outData.Datas[culture.Index].Group!.Add(sourceData.Datas[culture.Index]);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// sourceData.Id = e.NewValue;
|
||||
// AllI18nDatas.Remove(e.OldValue);
|
||||
// AllI18nDatas.Add(e.NewValue, sourceData);
|
||||
// }
|
||||
// }
|
||||
|
||||
#region Event
|
||||
private void AddCulture(string culture)
|
||||
{
|
||||
CultureChanged?.Invoke(null, culture);
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 删除I18n数据
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <param name="id"></param>
|
||||
// /// <param name="i18nModel"></param>
|
||||
// /// <param name="i18nValue"></param>
|
||||
// private void RemoveData<T>(
|
||||
// ObservableValue<string> id,
|
||||
// I18nModel<T> i18nModel,
|
||||
// Func<T, ObservableValue<string>> i18nValue
|
||||
// )
|
||||
// where T : class, new()
|
||||
// {
|
||||
// var data = AllI18nDatas[id.Value];
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
// {
|
||||
// if (data.Datas[culture.Index].Group is ObservableValueGroup<string> group)
|
||||
// {
|
||||
// group.Remove(i18nValue(i18nModel.I18nDatas[culture.Value]));
|
||||
// if (group.Count == 1)
|
||||
// {
|
||||
// group.Clear();
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// I18nDatas.Remove(data);
|
||||
// AllI18nDatas.Remove(id.Value);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void RemoveCulture(string culture)
|
||||
{
|
||||
CultureChanged?.Invoke(culture, string.Empty);
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 替换I18n数据
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <param name="id"></param>
|
||||
// /// <param name="i18nModel"></param>
|
||||
// /// <param name="i18nValue"></param>
|
||||
// private void ReplaceData<T>(
|
||||
// ObservableValue<string> id,
|
||||
// I18nModel<T> i18nModel,
|
||||
// Func<T, ObservableValue<string>> i18nValue
|
||||
// )
|
||||
// where T : class, new()
|
||||
// {
|
||||
// var data = AllI18nDatas[id.Value];
|
||||
// foreach (var culture in I18nHelper.Current.CultureNames.EnumerateIndex())
|
||||
// {
|
||||
// var oldValue = data.Datas[culture.Index];
|
||||
// var newValue = i18nValue(i18nModel.I18nDatas[culture.Value]);
|
||||
// if (oldValue.Group is ObservableValueGroup<string> group)
|
||||
// {
|
||||
// group.Add(newValue);
|
||||
// group.Remove(oldValue);
|
||||
// }
|
||||
// data.Datas[culture.Index] = newValue;
|
||||
// }
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
private void ReplaceCulture(string oldCulture, string newCulture)
|
||||
{
|
||||
CultureChanged?.Invoke(oldCulture, newCulture);
|
||||
}
|
||||
// public void Close()
|
||||
// {
|
||||
// I18nHelper.Current.CultureNames.CollectionChanged -= CultureNames_CollectionChanged;
|
||||
// foreach (var i18nData in AllI18nDatas)
|
||||
// {
|
||||
// foreach (var data in i18nData.Value.Datas)
|
||||
// data.Group?.Clear();
|
||||
// }
|
||||
// }
|
||||
|
||||
public event EventHandler<string> CultureChanged;
|
||||
#endregion
|
||||
}
|
||||
// #region Event
|
||||
// private void AddCulture(string culture)
|
||||
// {
|
||||
// CultureChanged?.Invoke(null, culture);
|
||||
// }
|
||||
|
||||
// private void RemoveCulture(string culture)
|
||||
// {
|
||||
// CultureChanged?.Invoke(culture, string.Empty);
|
||||
// }
|
||||
|
||||
// private void ReplaceCulture(string oldCulture, string newCulture)
|
||||
// {
|
||||
// CultureChanged?.Invoke(oldCulture, newCulture);
|
||||
// }
|
||||
|
||||
// public event EventHandler<string> CultureChanged;
|
||||
// #endregion
|
||||
//}
|
||||
|
@ -1,21 +1,32 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.LowTextEdit;
|
||||
|
||||
public class LowTextEditWindowVM
|
||||
public class LowTextEditWindowVM : ObservableObjectX<LowTextEditWindowVM>
|
||||
{
|
||||
public I18nHelper I18nData => I18nHelper.Current;
|
||||
#region Value
|
||||
public LowTextModel OldLowText { get; set; }
|
||||
public ObservableValue<LowTextModel> LowText { get; } = new(new());
|
||||
|
||||
#region LowText
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private LowTextModel _lowText;
|
||||
|
||||
public LowTextModel LowText
|
||||
{
|
||||
get => _lowText;
|
||||
set => SetProperty(ref _lowText, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -1,27 +1,46 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Views.ModEdit.LowTextEdit;
|
||||
using Expression = System.Linq.Expressions.Expression;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.LowTextEdit;
|
||||
|
||||
public class LowTextPageVM
|
||||
public class LowTextPageVM : ObservableObjectX<LowTextPageVM>
|
||||
{
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<LowTextModel>> ShowLowTexts { get; } = new();
|
||||
#region ShowLowTexts
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<LowTextModel> _showLowTexts;
|
||||
|
||||
public ObservableCollection<LowTextModel> ShowLowTexts
|
||||
{
|
||||
get => _showLowTexts;
|
||||
set => SetProperty(ref _showLowTexts, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<LowTextModel> LowTexts => ModInfoModel.Current.LowTexts;
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
@ -31,8 +50,8 @@ public class LowTextPageVM
|
||||
|
||||
public LowTextPageVM()
|
||||
{
|
||||
ShowLowTexts.Value = LowTexts;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
ShowLowTexts = LowTexts;
|
||||
//Search.ValueChanged += Search_ValueChanged;//TODO
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
@ -45,14 +64,12 @@ public class LowTextPageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowLowTexts.Value = LowTexts;
|
||||
ShowLowTexts = LowTexts;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowLowTexts.Value = new(
|
||||
LowTexts.Where(
|
||||
m => m.Id.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
ShowLowTexts = new(
|
||||
LowTexts.Where(m => m.Id.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -64,7 +81,7 @@ public class LowTextPageVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
LowTexts.Add(vm.LowText.Value);
|
||||
LowTexts.Add(vm.LowText);
|
||||
}
|
||||
|
||||
public void Edit(LowTextModel model)
|
||||
@ -72,26 +89,26 @@ public class LowTextPageVM
|
||||
var window = new LowTextEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.OldLowText = model;
|
||||
var newLowTest = vm.LowText.Value = new(model);
|
||||
var newLowTest = vm.LowText = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
LowTexts[LowTexts.IndexOf(model)] = newLowTest;
|
||||
if (ShowLowTexts.Value.Count != LowTexts.Count)
|
||||
ShowLowTexts.Value[ShowLowTexts.Value.IndexOf(model)] = newLowTest;
|
||||
if (ShowLowTexts.Count != LowTexts.Count)
|
||||
ShowLowTexts[ShowLowTexts.IndexOf(model)] = newLowTest;
|
||||
}
|
||||
|
||||
private void Remove(LowTextModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowLowTexts.Value.Count == LowTexts.Count)
|
||||
if (ShowLowTexts.Count == LowTexts.Count)
|
||||
{
|
||||
LowTexts.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowLowTexts.Value.Remove(model);
|
||||
ShowLowTexts.Remove(model);
|
||||
LowTexts.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -21,7 +22,7 @@ using VPet.ModMaker.Views.ModEdit.I18nEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit;
|
||||
|
||||
public class ModEditWindowVM
|
||||
public class ModEditWindowVM : ObservableObjectX<ModEditWindowVM>
|
||||
{
|
||||
public ModEditWindow ModEditWindow { get; }
|
||||
|
||||
@ -29,7 +30,16 @@ public class ModEditWindowVM
|
||||
/// <summary>
|
||||
/// 当前模组信息
|
||||
/// </summary>
|
||||
public ObservableValue<ModInfoModel> ModInfo { get; } = new(ModInfoModel.Current);
|
||||
#region ModInfo
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ModInfoModel _modInfo = ModInfoModel.Current;
|
||||
|
||||
public ModInfoModel ModInfo
|
||||
{
|
||||
get => _modInfo;
|
||||
set => SetProperty(ref _modInfo, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// I18n数据
|
||||
@ -103,7 +113,7 @@ public class ModEditWindowVM
|
||||
|
||||
private void SaveAsTranslationMod()
|
||||
{
|
||||
if (ValidationData(ModInfo.Value) is false)
|
||||
if (ValidationData(ModInfo) is false)
|
||||
return;
|
||||
var window = new SaveTranslationModWindow();
|
||||
window.ShowDialog();
|
||||
@ -120,7 +130,7 @@ public class ModEditWindowVM
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
ModInfo.Value.Image.Value?.StreamSource?.Close();
|
||||
ModInfo.Image?.StreamSource?.Close();
|
||||
I18nEditWindow.Current?.Close(true);
|
||||
}
|
||||
|
||||
@ -137,10 +147,8 @@ public class ModEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
ModInfo.Value.Image.Value?.StreamSource?.Close();
|
||||
ModInfo.Value.Image.Value = NativeUtils.LoadImageToMemoryStream(
|
||||
openFileDialog.FileName
|
||||
);
|
||||
ModInfo.Image?.StreamSource?.Close();
|
||||
ModInfo.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,9 +162,9 @@ public class ModEditWindowVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
I18nHelper.Current.CultureNames.Add(window.ViewModel.Culture.Value);
|
||||
I18nHelper.Current.CultureNames.Add(window.ViewModel.Culture);
|
||||
if (I18nHelper.Current.CultureNames.Count == 1)
|
||||
I18nHelper.Current.CultureName.Value = window.ViewModel.Culture.Value;
|
||||
I18nHelper.Current.CultureName = window.ViewModel.Culture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -166,12 +174,12 @@ public class ModEditWindowVM
|
||||
private void EditCulture(string oldCulture)
|
||||
{
|
||||
var window = new AddCultureWindow();
|
||||
window.ViewModel.Culture.Value = oldCulture.Translate();
|
||||
window.ViewModel.Culture = oldCulture.Translate();
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
I18nHelper.Current.CultureNames[I18nHelper.Current.CultureNames.IndexOf(oldCulture)] =
|
||||
window.ViewModel.Culture.Value;
|
||||
window.ViewModel.Culture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -202,29 +210,29 @@ public class ModEditWindowVM
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
ModInfo.Value.I18nDatas[culture].Name.Value = ModInfo.Value.Id.Value;
|
||||
ModInfo.Value.I18nDatas[culture].Description.Value = ModInfo.Value.DescriptionId.Value;
|
||||
foreach (var food in ModInfo.Value.Foods)
|
||||
ModInfo.I18nDatas[culture].Name = ModInfo.Id;
|
||||
ModInfo.I18nDatas[culture].Description = ModInfo.DescriptionId;
|
||||
foreach (var food in ModInfo.Foods)
|
||||
{
|
||||
food.I18nDatas[culture].Name.Value = food.Id.Value;
|
||||
food.I18nDatas[culture].Description.Value = food.DescriptionId.Value;
|
||||
food.I18nDatas[culture].Name = food.Id;
|
||||
food.I18nDatas[culture].Description = food.DescriptionId;
|
||||
}
|
||||
foreach (var text in ModInfo.Value.LowTexts)
|
||||
text.I18nDatas[culture].Text.Value = text.Id.Value;
|
||||
foreach (var text in ModInfo.Value.ClickTexts)
|
||||
text.I18nDatas[culture].Text.Value = text.Id.Value;
|
||||
foreach (var text in ModInfo.Value.SelectTexts)
|
||||
foreach (var text in ModInfo.LowTexts)
|
||||
text.I18nDatas[culture].Text = text.Id;
|
||||
foreach (var text in ModInfo.ClickTexts)
|
||||
text.I18nDatas[culture].Text = text.Id;
|
||||
foreach (var text in ModInfo.SelectTexts)
|
||||
{
|
||||
text.I18nDatas[culture].Text.Value = text.Id.Value;
|
||||
text.I18nDatas[culture].Choose.Value = text.ChooseId.Value;
|
||||
text.I18nDatas[culture].Text = text.Id;
|
||||
text.I18nDatas[culture].Choose = text.ChooseId;
|
||||
}
|
||||
foreach (var pet in ModInfo.Value.Pets)
|
||||
foreach (var pet in ModInfo.Pets)
|
||||
{
|
||||
pet.I18nDatas[culture].Name.Value = pet.Id.Value;
|
||||
pet.I18nDatas[culture].PetName.Value = pet.PetNameId.Value;
|
||||
pet.I18nDatas[culture].Description.Value = pet.DescriptionId.Value;
|
||||
pet.I18nDatas[culture].Name = pet.ID;
|
||||
pet.I18nDatas[culture].PetName = pet.PetNameId;
|
||||
pet.I18nDatas[culture].Description = pet.DescriptionId;
|
||||
foreach (var work in pet.Works)
|
||||
work.I18nDatas[culture].Name.Value = work.Id.Value;
|
||||
work.I18nDatas[culture].Name = work.Id;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@ -235,19 +243,19 @@ public class ModEditWindowVM
|
||||
/// </summary>
|
||||
private void Save()
|
||||
{
|
||||
if (ValidationData(ModInfo.Value) is false)
|
||||
if (ValidationData(ModInfo) is false)
|
||||
return;
|
||||
if (
|
||||
MessageBox.Show("确定保存吗".Translate(), "", MessageBoxButton.YesNo)
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
if (string.IsNullOrEmpty(ModInfo.Value.SourcePath.Value))
|
||||
if (string.IsNullOrEmpty(ModInfo.SourcePath))
|
||||
{
|
||||
MessageBox.Show("源路径为空, 请使用 保存至".Translate());
|
||||
return;
|
||||
}
|
||||
SaveTo(ModInfo.Value.SourcePath.Value);
|
||||
SaveTo(ModInfo.SourcePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -255,7 +263,7 @@ public class ModEditWindowVM
|
||||
/// </summary>
|
||||
private void SaveTo()
|
||||
{
|
||||
if (ValidationData(ModInfo.Value) is false)
|
||||
if (ValidationData(ModInfo) is false)
|
||||
return;
|
||||
var dialog = new VistaFolderBrowserDialog();
|
||||
if (dialog.ShowDialog() is not true)
|
||||
@ -272,9 +280,9 @@ public class ModEditWindowVM
|
||||
var pending = PendingBox.Show("保存中".Translate());
|
||||
try
|
||||
{
|
||||
ModInfo.Value.SaveTo(path);
|
||||
if (string.IsNullOrWhiteSpace(ModInfo.Value.SourcePath.Value))
|
||||
ModInfo.Value.SourcePath.Value = path;
|
||||
ModInfo.SaveTo(path);
|
||||
if (string.IsNullOrWhiteSpace(ModInfo.SourcePath))
|
||||
ModInfo.SourcePath = path;
|
||||
pending.Close();
|
||||
MessageBox.Show(ModEditWindow, "保存成功".Translate());
|
||||
}
|
||||
@ -303,12 +311,12 @@ public class ModEditWindowVM
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(model.Id.Value))
|
||||
if (string.IsNullOrWhiteSpace(model.Id))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(model.Author.Value))
|
||||
if (string.IsNullOrWhiteSpace(model.Author))
|
||||
{
|
||||
MessageBox.Show("作者不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return false;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -11,16 +12,53 @@ using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
|
||||
|
||||
public class MoveEditWindowVM
|
||||
public class MoveEditWindowVM : ObservableObjectX<MoveEditWindowVM>
|
||||
{
|
||||
#region Value
|
||||
public PetModel CurrentPet { get; set; }
|
||||
public MoveModel OldMove { get; set; }
|
||||
public ObservableValue<MoveModel> Move { get; } = new(new());
|
||||
|
||||
#region Move
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private MoveModel _move = new();
|
||||
|
||||
public MoveModel Move
|
||||
{
|
||||
get => _move;
|
||||
set => SetProperty(ref _move, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region BorderLength
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _borderLength = 250;
|
||||
|
||||
public double BorderLength
|
||||
{
|
||||
get => _borderLength;
|
||||
set => SetProperty(ref _borderLength, value);
|
||||
}
|
||||
#endregion
|
||||
#region LengthRatio
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _lengthRatio = 250 / 500;
|
||||
|
||||
public double LengthRatio
|
||||
{
|
||||
get => _lengthRatio;
|
||||
set => SetProperty(ref _lengthRatio, value);
|
||||
}
|
||||
#endregion
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#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();
|
||||
@ -29,7 +67,8 @@ public class MoveEditWindowVM
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImage;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImage;
|
||||
Image.ValueChanged += Image_ValueChanged;
|
||||
//TODO
|
||||
//Image.ValueChanged += Image_ValueChanged;
|
||||
}
|
||||
|
||||
private void Image_ValueChanged(
|
||||
@ -42,7 +81,7 @@ public class MoveEditWindowVM
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image.Value?.StreamSource?.Close();
|
||||
Image?.StreamSource?.Close();
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
@ -55,7 +94,7 @@ public class MoveEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,8 +108,8 @@ public class MoveEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image.Value?.StreamSource?.Close();
|
||||
Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Image?.StreamSource?.Close();
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,48 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Views.ModEdit.MoveEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.MoveEdit;
|
||||
|
||||
public class MovePageVM
|
||||
public class MovePageVM : ObservableObjectX<MovePageVM>
|
||||
{
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<MoveModel>> ShowMoves { get; } = new();
|
||||
#region ShowMoves
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<MoveModel> _showMoves;
|
||||
|
||||
public ObservableCollection<MoveModel> ShowMoves
|
||||
{
|
||||
get => _showMoves;
|
||||
set => SetProperty(ref _showMoves, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<MoveModel> Moves => CurrentPet.Value.Moves;
|
||||
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
@ -31,9 +51,10 @@ public class MovePageVM
|
||||
#endregion
|
||||
public MovePageVM()
|
||||
{
|
||||
ShowMoves.Value = Moves;
|
||||
ShowMoves = Moves;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
@ -45,7 +66,7 @@ public class MovePageVM
|
||||
ValueChangedEventArgs<PetModel> e
|
||||
)
|
||||
{
|
||||
ShowMoves.Value = e.NewValue.Moves;
|
||||
//ShowMoves.Value = e.NewValue.Moves;
|
||||
}
|
||||
|
||||
private void Search_ValueChanged(
|
||||
@ -55,14 +76,12 @@ public class MovePageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowMoves.Value = Moves;
|
||||
ShowMoves = Moves;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMoves.Value = new(
|
||||
Moves.Where(
|
||||
m => m.Graph.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
ShowMoves = new(
|
||||
Moves.Where(m => m.Graph.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -77,7 +96,7 @@ public class MovePageVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Moves.Add(vm.Move.Value);
|
||||
Moves.Add(vm.Move);
|
||||
}
|
||||
|
||||
public void Edit(MoveModel model)
|
||||
@ -86,26 +105,26 @@ public class MovePageVM
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.OldMove = model;
|
||||
var newMove = vm.Move.Value = new(model);
|
||||
var newMove = vm.Move = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Moves[Moves.IndexOf(model)] = newMove;
|
||||
if (ShowMoves.Value.Count != Moves.Count)
|
||||
ShowMoves.Value[ShowMoves.Value.IndexOf(model)] = newMove;
|
||||
if (ShowMoves.Count != Moves.Count)
|
||||
ShowMoves[ShowMoves.IndexOf(model)] = newMove;
|
||||
}
|
||||
|
||||
private void Remove(MoveModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowMoves.Value.Count == Moves.Count)
|
||||
if (ShowMoves.Count == Moves.Count)
|
||||
{
|
||||
Moves.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMoves.Value.Remove(model);
|
||||
ShowMoves.Remove(model);
|
||||
Moves.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -12,15 +13,52 @@ using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.PetEdit;
|
||||
|
||||
public class PetEditWindowVM
|
||||
public class PetEditWindowVM : ObservableObjectX<PetEditWindowVM>
|
||||
{
|
||||
public I18nHelper I18nData => I18nHelper.Current;
|
||||
public PetModel OldPet { get; set; }
|
||||
public ObservableValue<PetModel> Pet { get; } = new(new());
|
||||
|
||||
public ObservableValue<double> BorderLength { get; } = new(250);
|
||||
public ObservableValue<double> LengthRatio { get; } = new(250.0 / 500.0);
|
||||
public ObservableValue<BitmapImage> Image { get; } = new();
|
||||
#region Pet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private PetModel _Pet;
|
||||
|
||||
public PetModel Pet
|
||||
{
|
||||
get => _Pet;
|
||||
set => SetProperty(ref _Pet, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BorderLength
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _borderLength = 250;
|
||||
|
||||
public double BorderLength
|
||||
{
|
||||
get => _borderLength;
|
||||
set => SetProperty(ref _borderLength, value);
|
||||
}
|
||||
#endregion
|
||||
#region LengthRatio
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _lengthRatio = 250 / 500;
|
||||
|
||||
public double LengthRatio
|
||||
{
|
||||
get => _lengthRatio;
|
||||
set => SetProperty(ref _lengthRatio, value);
|
||||
}
|
||||
#endregion
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image;
|
||||
|
||||
public BitmapImage Image
|
||||
{
|
||||
get => _image;
|
||||
set => SetProperty(ref _image, value);
|
||||
}
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddImageCommand { get; } = new();
|
||||
public ObservableCommand ChangeImageCommand { get; } = new();
|
||||
@ -29,7 +67,8 @@ public class PetEditWindowVM
|
||||
{
|
||||
AddImageCommand.ExecuteCommand += AddImage;
|
||||
ChangeImageCommand.ExecuteCommand += ChangeImage;
|
||||
Image.ValueChanged += Image_ValueChanged;
|
||||
//TODO
|
||||
//Image.ValueChanged += Image_ValueChanged;
|
||||
}
|
||||
|
||||
private void Image_ValueChanged(
|
||||
@ -42,7 +81,7 @@ public class PetEditWindowVM
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Image.Value?.CloseStream();
|
||||
Image?.CloseStream();
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
@ -55,7 +94,7 @@ public class PetEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,8 +108,8 @@ public class PetEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Image.Value?.StreamSource?.Close();
|
||||
Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Image?.StreamSource?.Close();
|
||||
Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,46 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.ViewModels.ModEdit.I18nEdit;
|
||||
using VPet.ModMaker.Views.ModEdit.I18nEdit;
|
||||
using VPet.ModMaker.Views.ModEdit.PetEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.PetEdit;
|
||||
|
||||
public class PetPageVM
|
||||
public class PetPageVM : ObservableObjectX<PetPageVM>
|
||||
{
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<PetModel>> ShowPets { get; } = new();
|
||||
#region ShowPets
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<PetModel> _showPets;
|
||||
|
||||
public ObservableCollection<PetModel> ShowPets
|
||||
{
|
||||
get => _showPets;
|
||||
set => SetProperty(ref _showPets, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
@ -30,8 +49,9 @@ public class PetPageVM
|
||||
#endregion
|
||||
public PetPageVM()
|
||||
{
|
||||
ShowPets.Value = Pets;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
//TODO
|
||||
//ShowPets = Pets;
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
@ -45,12 +65,12 @@ public class PetPageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowPets.Value = Pets;
|
||||
ShowPets = Pets;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowPets.Value = new(
|
||||
Pets.Where(m => m.Id.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
ShowPets = new(
|
||||
Pets.Where(m => m.ID.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -64,12 +84,12 @@ public class PetPageVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Pets.Add(vm.Pet.Value);
|
||||
Pets.Add(vm.Pet);
|
||||
}
|
||||
|
||||
public void Edit(PetModel model)
|
||||
{
|
||||
if (model.FromMain.Value)
|
||||
if (model.FromMain)
|
||||
{
|
||||
if (
|
||||
MessageBox.Show("这是本体自带的宠物, 确定要编辑吗".Translate(), "", MessageBoxButton.YesNo)
|
||||
@ -80,11 +100,11 @@ public class PetPageVM
|
||||
var window = new PetEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.OldPet = model;
|
||||
var newPet = vm.Pet.Value = new(model);
|
||||
var newPet = vm.Pet = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
if (model.FromMain.Value)
|
||||
if (model.FromMain)
|
||||
{
|
||||
var index = Pets.IndexOf(model);
|
||||
Pets.Remove(model);
|
||||
@ -94,27 +114,27 @@ public class PetPageVM
|
||||
{
|
||||
Pets[Pets.IndexOf(model)] = newPet;
|
||||
}
|
||||
if (ShowPets.Value.Count != Pets.Count)
|
||||
ShowPets.Value[ShowPets.Value.IndexOf(model)] = newPet;
|
||||
if (ShowPets.Count != Pets.Count)
|
||||
ShowPets[ShowPets.IndexOf(model)] = newPet;
|
||||
model.Close();
|
||||
}
|
||||
|
||||
private void Remove(PetModel model)
|
||||
{
|
||||
if (model.FromMain.Value)
|
||||
if (model.FromMain)
|
||||
{
|
||||
MessageBox.Show("这是本体自带的宠物, 无法删除".Translate());
|
||||
return;
|
||||
}
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowPets.Value.Count == Pets.Count)
|
||||
if (ShowPets.Count == Pets.Count)
|
||||
{
|
||||
Pets.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowPets.Value.Remove(model);
|
||||
ShowPets.Remove(model);
|
||||
Pets.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,33 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit;
|
||||
|
||||
public class SaveTranslationModWindowVM
|
||||
public class SaveTranslationModWindowVM : ObservableObjectX<SaveTranslationModWindowVM>
|
||||
{
|
||||
#region Value
|
||||
public ObservableValue<bool?> CheckAll { get; } = new(true);
|
||||
#region CheckAll
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool? _checkAll;
|
||||
|
||||
public bool? CheckAll
|
||||
{
|
||||
get => _checkAll;
|
||||
set => SetProperty(ref _checkAll, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableCollection<CheckCultureModel> CheckCultures { get; } = [];
|
||||
#endregion
|
||||
@ -28,37 +38,44 @@ public class SaveTranslationModWindowVM
|
||||
|
||||
public SaveTranslationModWindowVM()
|
||||
{
|
||||
foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
{
|
||||
var model = new CheckCultureModel();
|
||||
model.CultureName.Value = culture;
|
||||
CheckCultures.Add(model);
|
||||
CheckAll.AddNotifySender(model.IsChecked);
|
||||
}
|
||||
CheckAll.ValueChanged += CheckAll_ValueChanged;
|
||||
CheckAll.SenderPropertyChanged += CheckAll_SenderPropertyChanged;
|
||||
SaveCommand.ExecuteCommand += Save;
|
||||
//TODO
|
||||
//foreach (var culture in I18nHelper.Current.CultureNames)
|
||||
//{
|
||||
// var model = new CheckCultureModel();
|
||||
// model.CultureName.Value = culture;
|
||||
// CheckCultures.Add(model);
|
||||
// CheckAll.AddNotifySender(model.IsChecked);
|
||||
//}
|
||||
//CheckAll.ValueChanged += CheckAll_ValueChanged;
|
||||
//CheckAll.SenderPropertyChanged += CheckAll_SenderPropertyChanged;
|
||||
//SaveCommand.ExecuteCommand += Save;
|
||||
}
|
||||
|
||||
private void CheckAll_ValueChanged(ObservableValue<bool?> sender, ValueChangedEventArgs<bool?> e)
|
||||
private void CheckAll_ValueChanged(
|
||||
ObservableValue<bool?> sender,
|
||||
ValueChangedEventArgs<bool?> e
|
||||
)
|
||||
{
|
||||
if (e.NewValue is null)
|
||||
{
|
||||
if (CheckCultures.All(m => m.IsChecked.Value))
|
||||
CheckAll.Value = false;
|
||||
else if (CheckCultures.All(m => m.IsChecked.Value is false))
|
||||
CheckAll.Value = true;
|
||||
if (CheckCultures.All(m => m.IsChecked))
|
||||
CheckAll = false;
|
||||
else if (CheckCultures.All(m => m.IsChecked is false))
|
||||
CheckAll = true;
|
||||
return;
|
||||
}
|
||||
foreach (var model in CheckCultures)
|
||||
model.IsChecked.Value = e.NewValue.Value;
|
||||
model.IsChecked = e.NewValue.Value;
|
||||
}
|
||||
|
||||
private void CheckAll_SenderPropertyChanged(ObservableValue<bool?> source, INotifyPropertyChanged sender)
|
||||
private void CheckAll_SenderPropertyChanged(
|
||||
ObservableValue<bool?> source,
|
||||
INotifyPropertyChanged sender
|
||||
)
|
||||
{
|
||||
var count = 0;
|
||||
foreach (var model in CheckCultures)
|
||||
if (model.IsChecked.Value)
|
||||
if (model.IsChecked)
|
||||
count += 1;
|
||||
|
||||
if (count == CheckCultures.Count)
|
||||
@ -71,17 +88,21 @@ public class SaveTranslationModWindowVM
|
||||
|
||||
public void Save()
|
||||
{
|
||||
SaveFileDialog saveFileDialog = new()
|
||||
{
|
||||
Title = "保存模组信息文件,并在文件夹内保存模组数据".Translate(),
|
||||
Filter = $"LPS文件|*.lps;".Translate(),
|
||||
FileName = "info.lps".Translate()
|
||||
};
|
||||
SaveFileDialog saveFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "保存模组信息文件,并在文件夹内保存模组数据".Translate(),
|
||||
Filter = $"LPS文件|*.lps;".Translate(),
|
||||
FileName = "info.lps".Translate()
|
||||
};
|
||||
if (saveFileDialog.ShowDialog() is not true)
|
||||
return;
|
||||
try
|
||||
{
|
||||
ModInfoModel.Current.SaveTranslationMod(Path.GetDirectoryName(saveFileDialog.FileName), CheckCultures.Where(m => m.IsChecked.Value).Select(m => m.CultureName.Value));
|
||||
ModInfoModel.Current.SaveTranslationMod(
|
||||
Path.GetDirectoryName(saveFileDialog.FileName),
|
||||
CheckCultures.Where(m => m.IsChecked).Select(m => m.CultureName)
|
||||
);
|
||||
MessageBox.Show("保存成功".Translate());
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -91,8 +112,26 @@ public class SaveTranslationModWindowVM
|
||||
}
|
||||
}
|
||||
|
||||
public class CheckCultureModel
|
||||
public class CheckCultureModel : ObservableObjectX<CheckCultureModel>
|
||||
{
|
||||
public ObservableValue<bool> IsChecked { get; } = new(true);
|
||||
public ObservableValue<string> CultureName { get; } = new();
|
||||
#region IsChecked
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private bool _isChecked;
|
||||
|
||||
public bool IsChecked
|
||||
{
|
||||
get => _isChecked;
|
||||
set => SetProperty(ref _isChecked, value);
|
||||
}
|
||||
#endregion
|
||||
#region CultureName
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _cultureName = string.Empty;
|
||||
|
||||
public string CultureName
|
||||
{
|
||||
get => _cultureName;
|
||||
set => SetProperty(ref _cultureName, value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,18 +1,29 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet.ModMaker.Models;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.SelectTextEdit;
|
||||
|
||||
public class SelectTextEditWindowVM
|
||||
public class SelectTextEditWindowVM : ObservableObjectX<SelectTextEditWindowVM>
|
||||
{
|
||||
public I18nHelper I18nData => I18nHelper.Current;
|
||||
#region Value
|
||||
public SelectTextModel OldSelectText { get; set; }
|
||||
public ObservableValue<SelectTextModel> SelectText { get; } = new(new());
|
||||
|
||||
#region SelectText
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private SelectTextModel _selectText = new();
|
||||
|
||||
public SelectTextModel SelectText
|
||||
{
|
||||
get => _selectText;
|
||||
set => SetProperty(ref _selectText, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,24 +1,43 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Views.ModEdit.SelectTextEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.SelectTextEdit;
|
||||
|
||||
public class SelectTextPageVM
|
||||
public class SelectTextPageVM : ObservableObjectX<SelectTextPageVM>
|
||||
{
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<SelectTextModel>> ShowSelectTexts { get; } = new();
|
||||
#region ShowSelectTexts
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<SelectTextModel> _showSelectTexts;
|
||||
|
||||
public ObservableCollection<SelectTextModel> ShowSelectTexts
|
||||
{
|
||||
get => _showSelectTexts;
|
||||
set => SetProperty(ref _showSelectTexts, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<SelectTextModel> SelectTexts => ModInfoModel.Current.SelectTexts;
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
@ -28,8 +47,9 @@ public class SelectTextPageVM
|
||||
|
||||
public SelectTextPageVM()
|
||||
{
|
||||
ShowSelectTexts.Value = SelectTexts;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
ShowSelectTexts = SelectTexts;
|
||||
//TODO
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
RemoveCommand.ExecuteCommand += Remove;
|
||||
@ -42,13 +62,13 @@ public class SelectTextPageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowSelectTexts.Value = SelectTexts;
|
||||
ShowSelectTexts = SelectTexts;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowSelectTexts.Value = new(
|
||||
SelectTexts.Where(
|
||||
m => m.Id.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
ShowSelectTexts = new(
|
||||
SelectTexts.Where(m =>
|
||||
m.Id.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -61,7 +81,7 @@ public class SelectTextPageVM
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
SelectTexts.Add(vm.SelectText.Value);
|
||||
SelectTexts.Add(vm.SelectText);
|
||||
}
|
||||
|
||||
public void Edit(SelectTextModel model)
|
||||
@ -69,26 +89,26 @@ public class SelectTextPageVM
|
||||
var window = new SelectTextEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.OldSelectText = model;
|
||||
var newLowTest = vm.SelectText.Value = new(model);
|
||||
var newLowTest = vm.SelectText = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
SelectTexts[SelectTexts.IndexOf(model)] = newLowTest;
|
||||
if (ShowSelectTexts.Value.Count != SelectTexts.Count)
|
||||
ShowSelectTexts.Value[ShowSelectTexts.Value.IndexOf(model)] = newLowTest;
|
||||
if (ShowSelectTexts.Count != SelectTexts.Count)
|
||||
ShowSelectTexts[ShowSelectTexts.IndexOf(model)] = newLowTest;
|
||||
}
|
||||
|
||||
private void Remove(SelectTextModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowSelectTexts.Value.Count == SelectTexts.Count)
|
||||
if (ShowSelectTexts.Count == SelectTexts.Count)
|
||||
{
|
||||
SelectTexts.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowSelectTexts.Value.Remove(model);
|
||||
ShowSelectTexts.Remove(model);
|
||||
SelectTexts.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -12,17 +13,45 @@ using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.WorkEdit;
|
||||
|
||||
public class WorkEditWindowVM
|
||||
public class WorkEditWindowVM : ObservableObjectX<WorkEditWindowVM>
|
||||
{
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
public static I18nHelper I18nData => I18nHelper.Current;
|
||||
#region Value
|
||||
public PetModel CurrentPet { get; set; }
|
||||
public WorkModel OldWork { get; set; }
|
||||
public ObservableValue<WorkModel> Work { get; } = new(new());
|
||||
|
||||
#region Work
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private WorkModel _work;
|
||||
|
||||
public WorkModel Work
|
||||
{
|
||||
get => _work;
|
||||
set => SetProperty(ref _work, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region BorderLength
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _borderLength = 250;
|
||||
|
||||
public double BorderLength
|
||||
{
|
||||
get => _borderLength;
|
||||
set => SetProperty(ref _borderLength, value);
|
||||
}
|
||||
#endregion
|
||||
#region LengthRatio
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private double _lengthRatio = 250 / 500;
|
||||
|
||||
public double LengthRatio
|
||||
{
|
||||
get => _lengthRatio;
|
||||
set => SetProperty(ref _lengthRatio, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableValue<double> BorderLength { get; } = new(250);
|
||||
public ObservableValue<double> LengthRatio { get; } = new(250.0 / 500.0);
|
||||
#region Command
|
||||
public ObservableCommand AddImageCommand { get; } = new();
|
||||
public ObservableCommand ChangeImageCommand { get; } = new();
|
||||
@ -38,9 +67,9 @@ public class WorkEditWindowVM
|
||||
|
||||
private void FixOverLoadCommand_ExecuteCommand()
|
||||
{
|
||||
var work = Work.Value.ToWork();
|
||||
work.FixOverLoad();
|
||||
Work.Value = new(work);
|
||||
//var work = Work.ToWork();
|
||||
//work.FixOverLoad();
|
||||
//Work = new(work);
|
||||
}
|
||||
|
||||
private void AddImage()
|
||||
@ -53,7 +82,7 @@ public class WorkEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Work.Value.Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Work.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,8 +96,8 @@ public class WorkEditWindowVM
|
||||
};
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
Work.Value.Image.Value?.CloseStream();
|
||||
Work.Value.Image.Value = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
Work.Image?.CloseStream();
|
||||
Work.Image = NativeUtils.LoadImageToMemoryStream(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -12,16 +13,46 @@ using VPet.ModMaker.Views.ModEdit.WorkEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels.ModEdit.WorkEdit;
|
||||
|
||||
public class WorkPageVM
|
||||
public class WorkPageVM : ObservableObjectX<WorkPageVM>
|
||||
{
|
||||
public static ModInfoModel ModInfo => ModInfoModel.Current;
|
||||
|
||||
#region Value
|
||||
public ObservableValue<ObservableCollection<WorkModel>> ShowWorks { get; } = new();
|
||||
public ObservableCollection<WorkModel> Works => CurrentPet.Value.Works;
|
||||
#region ShowWorks
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<WorkModel> _showWorks;
|
||||
|
||||
public ObservableCollection<WorkModel> ShowWorks
|
||||
{
|
||||
get => _showWorks;
|
||||
set => SetProperty(ref _showWorks, value);
|
||||
}
|
||||
#endregion
|
||||
public ObservableCollection<WorkModel> Works => CurrentPet.Works;
|
||||
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
|
||||
#region CurrentPet
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private PetModel _currentPet;
|
||||
|
||||
public PetModel CurrentPet
|
||||
{
|
||||
get => _currentPet;
|
||||
set => SetProperty(ref _currentPet, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Search
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _search;
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set => SetProperty(ref _search, value);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region Command
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
@ -30,9 +61,10 @@ public class WorkPageVM
|
||||
#endregion
|
||||
public WorkPageVM()
|
||||
{
|
||||
ShowWorks.Value = Works;
|
||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
Search.ValueChanged += Search_ValueChanged;
|
||||
ShowWorks = Works;
|
||||
//TODO
|
||||
//CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||
//Search.ValueChanged += Search_ValueChanged;
|
||||
|
||||
AddCommand.ExecuteCommand += Add;
|
||||
EditCommand.ExecuteCommand += Edit;
|
||||
@ -44,7 +76,7 @@ public class WorkPageVM
|
||||
ValueChangedEventArgs<PetModel> e
|
||||
)
|
||||
{
|
||||
ShowWorks.Value = e.NewValue.Works;
|
||||
ShowWorks = e.NewValue.Works;
|
||||
}
|
||||
|
||||
private void Search_ValueChanged(
|
||||
@ -54,14 +86,12 @@ public class WorkPageVM
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.NewValue))
|
||||
{
|
||||
ShowWorks.Value = Works;
|
||||
ShowWorks = Works;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowWorks.Value = new(
|
||||
Works.Where(m =>
|
||||
m.Id.Value.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
ShowWorks = new(
|
||||
Works.Where(m => m.Id.Contains(e.NewValue, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -70,39 +100,39 @@ public class WorkPageVM
|
||||
{
|
||||
var window = new WorkEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Works.Add(vm.Work.Value);
|
||||
Works.Add(vm.Work);
|
||||
}
|
||||
|
||||
public void Edit(WorkModel model)
|
||||
{
|
||||
var window = new WorkEditWindow();
|
||||
var vm = window.ViewModel;
|
||||
vm.CurrentPet = CurrentPet.Value;
|
||||
vm.CurrentPet = CurrentPet;
|
||||
vm.OldWork = model;
|
||||
var newWork = vm.Work.Value = new(model);
|
||||
var newWork = vm.Work = new(model);
|
||||
window.ShowDialog();
|
||||
if (window.IsCancel)
|
||||
return;
|
||||
Works[Works.IndexOf(model)] = newWork;
|
||||
if (ShowWorks.Value.Count != Works.Count)
|
||||
ShowWorks.Value[ShowWorks.Value.IndexOf(model)] = newWork;
|
||||
if (ShowWorks.Count != Works.Count)
|
||||
ShowWorks[ShowWorks.IndexOf(model)] = newWork;
|
||||
}
|
||||
|
||||
private void Remove(WorkModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowWorks.Value.Count == Works.Count)
|
||||
if (ShowWorks.Count == Works.Count)
|
||||
{
|
||||
Works.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowWorks.Value.Remove(model);
|
||||
ShowWorks.Remove(model);
|
||||
Works.Remove(model);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,19 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript;
|
||||
using LinePutScript.Converter;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using Panuon.WPF.UI;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript;
|
||||
using LinePutScript.Converter;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using Panuon.WPF.UI;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Views;
|
||||
using VPet.ModMaker.Views.ModEdit;
|
||||
@ -20,7 +21,7 @@ using VPet.ModMaker.Views.ModEdit.I18nEdit;
|
||||
|
||||
namespace VPet.ModMaker.ViewModels;
|
||||
|
||||
public class ModMakerWindowVM
|
||||
public class ModMakerWindowVM : ObservableObjectX<ModMakerWindowVM>
|
||||
{
|
||||
#region Value
|
||||
public ModMakerWindow ModMakerWindow { get; }
|
||||
@ -30,12 +31,30 @@ public class ModMakerWindowVM
|
||||
/// <summary>
|
||||
/// 历史搜索文本
|
||||
/// </summary>
|
||||
public ObservableValue<string> HistoriesSearchText { get; } = new();
|
||||
#region HistoriesSearchText
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _historiesSearchText;
|
||||
|
||||
public string HistoriesSearchText
|
||||
{
|
||||
get => _historiesSearchText;
|
||||
set => SetProperty(ref _historiesSearchText, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 显示的历史
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<ModMakeHistory>> ShowHistories { get; } = new();
|
||||
#region ShowHistories
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private ObservableCollection<ModMakeHistory> _showHistories;
|
||||
|
||||
public ObservableCollection<ModMakeHistory> ShowHistories
|
||||
{
|
||||
get => _showHistories;
|
||||
set => SetProperty(ref _showHistories, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 历史
|
||||
@ -68,12 +87,13 @@ public class ModMakerWindowVM
|
||||
{
|
||||
LoadHistories();
|
||||
ModMakerWindow = window;
|
||||
ShowHistories.Value = Histories;
|
||||
//TODO
|
||||
//ShowHistories.Value = Histories;
|
||||
CreateNewModCommand.ExecuteCommand += CreateNewMod;
|
||||
LoadModFromFileCommand.ExecuteCommand += LoadModFromFile;
|
||||
ClearHistoriesCommand.ExecuteCommand += ClearHistories;
|
||||
RemoveHistoryCommand.ExecuteCommand += RemoveHistory;
|
||||
HistoriesSearchText.ValueChanged += HistoriesSearchText_ValueChanged;
|
||||
//HistoriesSearchText.ValueChanged += HistoriesSearchText_ValueChanged;
|
||||
}
|
||||
|
||||
private void HistoriesSearchText_ValueChanged(
|
||||
@ -82,9 +102,9 @@ public class ModMakerWindowVM
|
||||
)
|
||||
{
|
||||
if (string.IsNullOrEmpty(e.NewValue))
|
||||
ShowHistories.Value = Histories;
|
||||
ShowHistories = Histories;
|
||||
else
|
||||
ShowHistories.Value = new(Histories.Where(i => i.Id.Contains(e.NewValue)));
|
||||
ShowHistories = new(Histories.Where(i => i.Id.Contains(e.NewValue)));
|
||||
}
|
||||
|
||||
#region History
|
||||
@ -133,12 +153,12 @@ public class ModMakerWindowVM
|
||||
private void AddHistories(ModInfoModel modInfo)
|
||||
{
|
||||
if (
|
||||
Histories.FirstOrDefault(h => h.SourcePath == modInfo.SourcePath.Value)
|
||||
Histories.FirstOrDefault(h => h.SourcePath == modInfo.SourcePath)
|
||||
is ModMakeHistory history
|
||||
)
|
||||
{
|
||||
history.Id = modInfo.Id.Value;
|
||||
history.SourcePath = modInfo.SourcePath.Value;
|
||||
history.Id = modInfo.Id;
|
||||
history.SourcePath = modInfo.SourcePath;
|
||||
history.LastTime = DateTime.Now;
|
||||
}
|
||||
else
|
||||
@ -146,8 +166,8 @@ public class ModMakerWindowVM
|
||||
Histories.Add(
|
||||
new()
|
||||
{
|
||||
Id = modInfo.Id.Value,
|
||||
SourcePath = modInfo.SourcePath.Value,
|
||||
Id = modInfo.Id,
|
||||
SourcePath = modInfo.SourcePath,
|
||||
LastTime = DateTime.Now,
|
||||
}
|
||||
);
|
||||
@ -161,7 +181,7 @@ public class ModMakerWindowVM
|
||||
is not MessageBoxResult.Yes
|
||||
)
|
||||
return;
|
||||
ShowHistories.Value.Clear();
|
||||
ShowHistories.Clear();
|
||||
Histories.Clear();
|
||||
File.WriteAllText(ModMakerInfo.HistoryFile, string.Empty);
|
||||
}
|
||||
@ -195,7 +215,7 @@ public class ModMakerWindowVM
|
||||
GC.Collect();
|
||||
ModMakerWindow.Hide();
|
||||
// 将当前模组添加到历史
|
||||
if (string.IsNullOrEmpty(ModInfoModel.Current.SourcePath.Value) is false)
|
||||
if (string.IsNullOrEmpty(ModInfoModel.Current.SourcePath) is false)
|
||||
AddHistories(ModInfoModel.Current);
|
||||
SaveHistories();
|
||||
ModEditWindow = new();
|
||||
@ -204,7 +224,7 @@ public class ModMakerWindowVM
|
||||
ModEditWindow.Closed += (s, e) =>
|
||||
{
|
||||
var modInfo = ModInfoModel.Current;
|
||||
if (string.IsNullOrEmpty(modInfo.SourcePath.Value) is false)
|
||||
if (string.IsNullOrEmpty(modInfo.SourcePath) is false)
|
||||
{
|
||||
AddHistories(modInfo);
|
||||
SaveHistories();
|
||||
|
@ -1,7 +1,4 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Panuon.WPF.UI;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
@ -16,6 +13,9 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Panuon.WPF.UI;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.ViewModels;
|
||||
using VPet.ModMaker.ViewModels.ModEdit;
|
||||
@ -46,12 +46,12 @@ public partial class AddCultureWindow : WindowX
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Culture.Value))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Culture))
|
||||
{
|
||||
MessageBox.Show("文化不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (I18nHelper.Current.CultureNames.Contains(ViewModel.Culture.Value))
|
||||
if (I18nHelper.Current.CultureNames.Contains(ViewModel.Culture))
|
||||
{
|
||||
MessageBox.Show("此文化已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
|
@ -11,9 +11,11 @@
|
||||
Title="{ll:Str 编辑动画}"
|
||||
Width="1000"
|
||||
Height="600"
|
||||
d:DataContext="{d:DesignInstance Type=vm:AnimeEditWindowVM}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<d:Window.DataContext>
|
||||
<vm:AnimeEditWindowVM />
|
||||
</d:Window.DataContext>
|
||||
<Window.Resources>
|
||||
<Style
|
||||
x:Key="ListBoxItem_Style"
|
||||
@ -35,19 +37,19 @@
|
||||
Command="{Binding PlacementTarget.Tag.AddImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 添加图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="清空图片"
|
||||
Command="{Binding PlacementTarget.Tag.ClearImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 清空图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="删除此项"
|
||||
Command="{Binding PlacementTarget.Tag.RemoveAnimeCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 删除此项}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</Expander.ContextMenu>
|
||||
<Expander.Header>
|
||||
@ -67,14 +69,14 @@
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 动画Id(非必要)}"
|
||||
Text="{Binding Id.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Id, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<!-- pu:TextBoxHelper.Watermark="{ll:Str 动画Id(非必要)}" -->
|
||||
<ComboBox
|
||||
Grid.Column="2"
|
||||
Margin="10,0,0,0"
|
||||
ItemsSource="{Binding DataContext.Anime.Value.AnimatTypes, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding AnimeType.Value}"
|
||||
Visibility="{Binding DataContext.HasMultiType.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
ItemsSource="{Binding DataContext.Anime.AnimatTypes, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding AnimeType}"
|
||||
Visibility="{Binding DataContext.HasMultiType, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
<ListBox
|
||||
@ -86,7 +88,7 @@
|
||||
PreviewMouseWheel="ListBox_PreviewMouseWheel"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
SelectedItem="{Binding DataContext.CurrentImageModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding DataContext.CurrentImageModel, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectionChanged="ListBox_SelectionChanged">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@ -103,13 +105,13 @@
|
||||
Command="{Binding PlacementTarget.Tag.ChangeImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 修改图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="删除图片"
|
||||
Command="{Binding PlacementTarget.Tag.RemoveImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 删除图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid.RowDefinitions>
|
||||
@ -121,12 +123,12 @@
|
||||
Height="150"
|
||||
d:DataContext=""
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
|
||||
Source="{Binding Image.Value, IsAsync=True}">
|
||||
Source="{Binding Image, IsAsync=True}">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Image.Value, IsAsync=True}" />
|
||||
Source="{Binding Image, IsAsync=True}" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
@ -135,7 +137,7 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label d:Content="持续时间(ms)" Content="{ll:Str 持续时间(ms)}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration.Value, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
@ -158,12 +160,12 @@
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding CurrentImageModel.Value.Image.Value}">
|
||||
Source="{Binding CurrentImageModel.Image}">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
Width="500"
|
||||
Height="500"
|
||||
Source="{Binding CurrentImageModel.Value.Image.Value}" />
|
||||
Source="{Binding CurrentImageModel.Image}" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
@ -184,7 +186,7 @@
|
||||
<ToggleButton
|
||||
Grid.Column="2"
|
||||
Content="{ll:Str 循环}"
|
||||
IsChecked="{Binding Loop.Value}"
|
||||
IsChecked="{Binding Loop}"
|
||||
Style="{DynamicResource StndardToggleButtonStyle}" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
@ -199,17 +201,17 @@
|
||||
<!--<Label Content="{ll:Str 动画Id}" />
|
||||
<TextBox Grid.Column="1" />-->
|
||||
<Label Content="{ll:Str 动画类型}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Anime.Value.GraphType.Value}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Anime.GraphType}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Content="{ll:Str 动画名称}"
|
||||
Visibility="{Binding HasAnimeName.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
Visibility="{Binding HasAnimeName, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 动画名称}"
|
||||
Text="{Binding Anime.Value.Name.Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasAnimeName.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
Text="{Binding Anime.Name, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasAnimeName, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
@ -222,7 +224,7 @@
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="Anime.Value.HappyAnimes.Count" />
|
||||
<Binding Path="Anime.HappyAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -231,14 +233,14 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.HappyAnimes, IsAsync=True}"
|
||||
ItemsSource="{Binding Anime.HappyAnimes, IsAsync=True}"
|
||||
SelectionChanged="ListBox_Animes_SelectionChanged" />
|
||||
</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" />
|
||||
<Binding Path="Anime.NomalAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -246,13 +248,13 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.NomalAnimes, IsAsync=True}" />
|
||||
ItemsSource="{Binding Anime.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" />
|
||||
<Binding Path="Anime.PoorConditionAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -260,13 +262,13 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.PoorConditionAnimes, IsAsync=True}" />
|
||||
ItemsSource="{Binding Anime.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" />
|
||||
<Binding Path="Anime.IllAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -274,7 +276,7 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.IllAnimes, IsAsync=True}" />
|
||||
ItemsSource="{Binding Anime.IllAnimes, IsAsync=True}" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<Grid Grid.Row="1">
|
||||
|
@ -65,8 +65,8 @@ public partial class AnimeEditWindow : Window
|
||||
if (Enum.TryParse<ModeType>(str, true, out var mode))
|
||||
{
|
||||
ViewModel.CurrentMode = mode;
|
||||
ViewModel.CurrentImageModel.Value = null;
|
||||
ViewModel.CurrentAnimeModel.Value = null;
|
||||
ViewModel.CurrentImageModel = null;
|
||||
ViewModel.CurrentAnimeModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ public partial class AnimeEditWindow : Window
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
if (listBox.DataContext is AnimeModel model)
|
||||
ViewModel.CurrentAnimeModel.Value = model;
|
||||
ViewModel.CurrentAnimeModel = model;
|
||||
listBox.ScrollIntoView(listBox.SelectedItem);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}" Text="{Binding Search.Value, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}" Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox.Style>
|
||||
<Style BasedOn="{StaticResource StandardTextBoxStyle}" TargetType="TextBox">
|
||||
<Setter Property="IsEnabled" Value="True" />
|
||||
@ -40,19 +40,19 @@
|
||||
Grid.Column="1"
|
||||
pu:ComboBoxHelper.Watermark="{ll:Str 选择宠物}"
|
||||
ItemsSource="{Binding Pets}"
|
||||
SelectedItem="{Binding CurrentPet.Value}"
|
||||
SelectedItem="{Binding CurrentPet}"
|
||||
Style="{DynamicResource StandardComboBoxStyle}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="ComboBoxItem">
|
||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Value.Name.Value}" />
|
||||
<Setter Property="ToolTip" Value="{Binding CurrentI18nData.Name}" />
|
||||
<Setter Property="Visibility">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource AllTrueToCollapsedConverter}">
|
||||
<Binding
|
||||
Converter="{StaticResource BoolInverter}"
|
||||
Path="DataContext.ModInfo.ShowMainPet.Value"
|
||||
Path="DataContext.ModInfo.ShowMainPet"
|
||||
RelativeSource="{RelativeSource AncestorType=Page}" />
|
||||
<Binding Path="FromMain.Value" />
|
||||
<Binding Path="FromMain" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@ -61,7 +61,7 @@
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Id.Value}" />
|
||||
<TextBlock Text="{Binding Id}" />
|
||||
<TextBlock Text="{ll:Str {} (来自本体)}" Visibility="{Binding FromMain, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
@ -85,7 +85,7 @@
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowAnimes.Value}"
|
||||
ItemsSource="{Binding ShowAnimes}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="50"
|
||||
@ -100,40 +100,40 @@
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Id.Value}"
|
||||
Binding="{Binding Id}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 动画类型}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding HappyAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 开心状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding NomalAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 普通状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding PoorConditionAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 不开心状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding IllAnimes.Count}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 生病状态动画数量}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button
|
||||
|
@ -40,7 +40,7 @@
|
||||
Command="{Binding PlacementTarget.Tag.RemoveAnimeCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 删除此动画}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -59,7 +59,7 @@
|
||||
<!--<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 动画Id(非必要)}"
|
||||
Text="{Binding Id.Value, UpdateSourceTrigger=PropertyChanged}" />-->
|
||||
Text="{Binding Id, UpdateSourceTrigger=PropertyChanged}" />-->
|
||||
<!-- pu:TextBoxHelper.Watermark="{ll:Str 动画Id(非必要)}" -->
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
@ -79,13 +79,13 @@
|
||||
Command="{Binding PlacementTarget.Tag.AddFrontImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 添加图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="添加图片"
|
||||
Command="{Binding PlacementTarget.Tag.ClearFrontImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 清空图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</StackPanel.ContextMenu>
|
||||
<Label d:Content="顶层图片" Content="{ll:Str 顶层图片}" />
|
||||
@ -107,7 +107,7 @@
|
||||
PreviewMouseMove="ListBox_PreviewMouseMove"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
SelectedItem="{Binding DataContext.CurrentFrontImageModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding DataContext.CurrentFrontImageModel, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectionChanged="ListBox_SelectionChanged">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@ -124,13 +124,13 @@
|
||||
Command="{Binding PlacementTarget.Tag.ChangeFrontImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 修改图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="删除图片"
|
||||
Command="{Binding PlacementTarget.Tag.RemoveFrontImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 删除图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid.RowDefinitions>
|
||||
@ -142,12 +142,12 @@
|
||||
Height="150"
|
||||
d:DataContext=""
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
|
||||
Source="{Binding Image.Value, IsAsync=True}">
|
||||
Source="{Binding Image, IsAsync=True}">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Image.Value, IsAsync=True}" />
|
||||
Source="{Binding Image, IsAsync=True}" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
@ -156,7 +156,7 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label d:Content="持续时间(ms)" Content="{ll:Str 持续时间(ms)}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration.Value, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
@ -173,13 +173,13 @@
|
||||
Command="{Binding PlacementTarget.Tag.AddBackImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 添加图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="添加图片"
|
||||
Command="{Binding PlacementTarget.Tag.ClearBackImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 清空图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</StackPanel.ContextMenu>
|
||||
<Label d:Content="底层图片" Content="{ll:Str 底层图片}" />
|
||||
@ -201,7 +201,7 @@
|
||||
PreviewMouseMove="ListBox_PreviewMouseMove"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
SelectedItem="{Binding DataContext.CurrentBackImageModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding DataContext.CurrentBackImageModel, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectionChanged="ListBox_SelectionChanged">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@ -218,13 +218,13 @@
|
||||
Command="{Binding PlacementTarget.Tag.ChangeBackImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 修改图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="删除图片"
|
||||
Command="{Binding PlacementTarget.Tag.RemoveBackImageCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 删除图片}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid.RowDefinitions>
|
||||
@ -236,12 +236,12 @@
|
||||
Height="150"
|
||||
d:DataContext=""
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
|
||||
Source="{Binding Image.Value, IsAsync=True}">
|
||||
Source="{Binding Image, IsAsync=True}">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Image.Value, IsAsync=True}" />
|
||||
Source="{Binding Image, IsAsync=True}" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
<Grid Grid.Row="1">
|
||||
@ -250,7 +250,7 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label d:Content="持续时间(ms)" Content="{ll:Str 持续时间(ms)}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration.Value, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding DataContext.Duration, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
@ -267,13 +267,13 @@
|
||||
Command="{Binding PlacementTarget.Tag.AddFoodLocationCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 添加食物定位}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
<MenuItem
|
||||
d:Header="清空食物定位"
|
||||
Command="{Binding PlacementTarget.Tag.ClearFoodLocationCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 清空食物定位}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</StackPanel.ContextMenu>
|
||||
<Label d:Content="食物位置" Content="{ll:Str 食物位置}" />
|
||||
@ -291,7 +291,7 @@
|
||||
ItemsSource="{Binding FoodLocations, IsAsync=True}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
SelectedItem="{Binding DataContext.CurrentFoodLocationModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectedItem="{Binding DataContext.CurrentFoodLocationModel, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
|
||||
SelectionChanged="ListBox_SelectionChanged">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@ -308,7 +308,7 @@
|
||||
Command="{Binding PlacementTarget.Tag.RemoveFoodLocationCommand, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}"
|
||||
Header="{ll:Str 删除食物定位}"
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute.Value, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
IsEnabled="{Binding PlacementTarget.Tag.PlayCommand.CurrentCanExecute, RelativeSource={RelativeSource AncestorType=ContextMenu, Mode=FindAncestor}}" />
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -324,7 +324,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label d:Content="持续时间 (ms)" Content="{ll:Str 持续时间 (ms)}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Duration.Value}" />
|
||||
<pu:NumberInput Grid.Column="1" Value="{Binding Duration}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
d:Content="旋转角度"
|
||||
@ -332,7 +332,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Rotate.Value}" />
|
||||
Value="{Binding Rotate}" />
|
||||
<Label
|
||||
Grid.Row="2"
|
||||
d:Content="透明度"
|
||||
@ -340,7 +340,7 @@
|
||||
<pu:NumberInput
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Opacity.Value}" />
|
||||
Value="{Binding Opacity}" />
|
||||
<Label
|
||||
Grid.Row="3"
|
||||
d:Content="长度"
|
||||
@ -399,7 +399,7 @@
|
||||
<MenuItem Command="{Binding ResetFoodImageCommand}" Header="{ll:Str 重置测试食物图片}">
|
||||
<MenuItem.IsEnabled>
|
||||
<MultiBinding Converter="{StaticResource NotEqualsConverter}">
|
||||
<Binding Path="FoodImage.Value" />
|
||||
<Binding Path="FoodImage" />
|
||||
<Binding Path="DefaultFoodImage" />
|
||||
</MultiBinding>
|
||||
</MenuItem.IsEnabled>
|
||||
@ -410,20 +410,20 @@
|
||||
x:Name="Image_Back"
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding CurrentBackImageModel.Value.Image.Value}" />
|
||||
Source="{Binding CurrentBackImageModel.Image}" />
|
||||
<Image
|
||||
x:Name="Image_Food"
|
||||
Height="{Binding Width, RelativeSource={RelativeSource Mode=Self}}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Opacity="{Binding CurrentFoodLocationModel.Value.Opacity.Value}"
|
||||
Opacity="{Binding CurrentFoodLocationModel.Opacity}"
|
||||
RenderTransformOrigin="0,0"
|
||||
Source="{Binding FoodImage.Value}">
|
||||
Source="{Binding FoodImage}">
|
||||
<Image.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform />
|
||||
<SkewTransform />
|
||||
<RotateTransform Angle="{Binding CurrentFoodLocationModel.Value.Rotate.Value}" />
|
||||
<RotateTransform Angle="{Binding CurrentFoodLocationModel.Rotate}" />
|
||||
<TranslateTransform />
|
||||
</TransformGroup>
|
||||
</Image.RenderTransform>
|
||||
@ -432,17 +432,17 @@
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Width" />
|
||||
<Binding Path="LengthRatio.Value" />
|
||||
<Binding Path="CurrentFoodLocationModel.Rect.Width" />
|
||||
<Binding Path="LengthRatio" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Margin">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Path="LengthRatio.Value" />
|
||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.X" />
|
||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Y" />
|
||||
<Binding Path="LengthRatio" />
|
||||
<Binding Path="CurrentFoodLocationModel.Rect.X" />
|
||||
<Binding Path="CurrentFoodLocationModel.Rect.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@ -453,25 +453,25 @@
|
||||
x:Name="Image_Front"
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding CurrentFrontImageModel.Value.Image.Value}">
|
||||
Source="{Binding CurrentFrontImageModel.Image}">
|
||||
<Image.ToolTip>
|
||||
<Grid>
|
||||
<Image
|
||||
Width="500"
|
||||
Height="500"
|
||||
Source="{Binding CurrentBackImageModel.Value.Image.Value}" />
|
||||
Source="{Binding CurrentBackImageModel.Image}" />
|
||||
<Image
|
||||
Height="{Binding Width, RelativeSource={RelativeSource Mode=Self}}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Opacity="{Binding CurrentFoodLocationModel.Value.Opacity.Value}"
|
||||
Opacity="{Binding CurrentFoodLocationModel.Opacity}"
|
||||
RenderTransformOrigin="0,0"
|
||||
Source="{Binding FoodImage.Value}">
|
||||
Source="{Binding FoodImage}">
|
||||
<Image.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform />
|
||||
<SkewTransform />
|
||||
<RotateTransform Angle="{Binding CurrentFoodLocationModel.Value.Rotate.Value}" />
|
||||
<RotateTransform Angle="{Binding CurrentFoodLocationModel.Rotate}" />
|
||||
<TranslateTransform />
|
||||
</TransformGroup>
|
||||
</Image.RenderTransform>
|
||||
@ -480,7 +480,7 @@
|
||||
<Setter Property="Width">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource CalculatorConverter}" ConverterParameter="*">
|
||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Width" />
|
||||
<Binding Path="CurrentFoodLocationModel.Rect.Width" />
|
||||
<Binding Source="1" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
@ -489,8 +489,8 @@
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource RatioMarginConverter}">
|
||||
<Binding Source="1" />
|
||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.X" />
|
||||
<Binding Path="CurrentFoodLocationModel.Value.Rect.Y" />
|
||||
<Binding Path="CurrentFoodLocationModel.Rect.X" />
|
||||
<Binding Path="CurrentFoodLocationModel.Rect.Y" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@ -500,7 +500,7 @@
|
||||
<Image
|
||||
Width="500"
|
||||
Height="500"
|
||||
Source="{Binding CurrentFrontImageModel.Value.Image.Value}" />
|
||||
Source="{Binding CurrentFrontImageModel.Image}" />
|
||||
</Grid>
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
@ -523,7 +523,7 @@
|
||||
<ToggleButton
|
||||
Grid.Column="2"
|
||||
Content="{ll:Str 循环}"
|
||||
IsChecked="{Binding Loop.Value}"
|
||||
IsChecked="{Binding Loop}"
|
||||
Style="{DynamicResource StndardToggleButtonStyle}" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
@ -538,17 +538,17 @@
|
||||
<!--<Label Content="{ll:Str 动画Id}" />
|
||||
<TextBox Grid.Column="1" />-->
|
||||
<Label Content="{ll:Str 动画类型}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Anime.Value.GraphType}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Anime.GraphType}" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Content="{ll:Str 动画名称}"
|
||||
Visibility="{Binding HasAnimeName.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
Visibility="{Binding HasAnimeName, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 动画名称}"
|
||||
Text="{Binding Anime.Value.Name.Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasAnimeName.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
Text="{Binding Anime.Name, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasAnimeName, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
@ -561,7 +561,7 @@
|
||||
<TabItem.Header>
|
||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||
<Binding Path="Anime.Value.HappyAnimes.Count" />
|
||||
<Binding Path="Anime.HappyAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -570,14 +570,14 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.HappyAnimes, IsAsync=True}"
|
||||
ItemsSource="{Binding Anime.HappyAnimes, IsAsync=True}"
|
||||
SelectionChanged="ListBox_Animes_SelectionChanged" />
|
||||
</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" />
|
||||
<Binding Path="Anime.NomalAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -585,13 +585,13 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.NomalAnimes, IsAsync=True}" />
|
||||
ItemsSource="{Binding Anime.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" />
|
||||
<Binding Path="Anime.PoorConditionAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -599,13 +599,13 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.PoorConditionAnimes, IsAsync=True}" />
|
||||
ItemsSource="{Binding Anime.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" />
|
||||
<Binding Path="Anime.IllAnimes.Count" />
|
||||
</MultiBinding>
|
||||
</TabItem.Header>
|
||||
<ListBox
|
||||
@ -613,7 +613,7 @@
|
||||
d:SelectedIndex="0"
|
||||
ItemContainerStyle="{StaticResource ListBoxItem_Style}"
|
||||
ItemTemplate="{StaticResource Expander_AnimeItem}"
|
||||
ItemsSource="{Binding Anime.Value.IllAnimes, IsAsync=True}" />
|
||||
ItemsSource="{Binding Anime.IllAnimes, IsAsync=True}" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<Grid Grid.Row="1">
|
||||
|
@ -68,10 +68,10 @@ public partial class FoodAnimeEditWindow : Window
|
||||
if (Enum.TryParse<ModeType>(str, true, out var mode))
|
||||
{
|
||||
ViewModel.CurrentMode = mode;
|
||||
ViewModel.CurrentFrontImageModel.Value = null;
|
||||
ViewModel.CurrentBackImageModel.Value = null;
|
||||
ViewModel.CurrentFoodLocationModel.Value = null;
|
||||
ViewModel.CurrentAnimeModel.Value = null;
|
||||
ViewModel.CurrentFrontImageModel = null;
|
||||
ViewModel.CurrentBackImageModel = null;
|
||||
ViewModel.CurrentFoodLocationModel = null;
|
||||
ViewModel.CurrentAnimeModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ public partial class FoodAnimeEditWindow : Window
|
||||
if (sender is not ListBox listBox)
|
||||
return;
|
||||
if (listBox.DataContext is FoodAnimeModel model)
|
||||
ViewModel.CurrentAnimeModel.Value = model;
|
||||
ViewModel.CurrentAnimeModel = model;
|
||||
listBox.ScrollIntoView(listBox.SelectedItem);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
@ -44,13 +44,13 @@
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
Content="{ll:Str 动画名称}"
|
||||
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding AnimeName.Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToCollapsedConverter}}" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
@ -1,6 +1,4 @@
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
@ -14,6 +12,8 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.Models.ModModel;
|
||||
using VPet_Simulator.Core;
|
||||
@ -58,7 +58,7 @@ public partial class SelectGraphTypeWindow : Window
|
||||
)
|
||||
{
|
||||
GraphTypes.Value = new(
|
||||
AnimeTypeModel.GraphTypes.Except(CurrentPet.Value.Animes.Select(m => m.GraphType.Value))
|
||||
AnimeTypeModel.GraphTypes.Except(CurrentPet.Value.Animes.Select(m => m.GraphType))
|
||||
);
|
||||
// 可添加多个项的类型
|
||||
foreach (var graphType in AnimeTypeModel.HasNameAnimes)
|
||||
|
@ -38,7 +38,7 @@
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="Id"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding ClickText.Value.Id.Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
Text="{Binding ClickText.Id, UpdateSourceTrigger=PropertyChanged}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<TextBox
|
||||
@ -47,7 +47,7 @@
|
||||
d:Text="这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,这是一个测试文本,"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 文本}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding ClickText.Value.CurrentI18nData.Value.Text.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding ClickText.CurrentI18nData.Text, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
@ -72,7 +72,7 @@
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 非必要}"
|
||||
Text="{Binding ClickText.Value.Working.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding ClickText.Working, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="3" Content="{ll:Str 宠物状态}" />
|
||||
<Grid Grid.Row="3" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -81,20 +81,20 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{Binding ClickText.Value.Mode.EnumValue.Value}" />
|
||||
<TextBlock Text="{Binding ClickText.Mode.Value}" />
|
||||
<ComboBox
|
||||
x:Name="ComboBox_Mode"
|
||||
Grid.Column="1"
|
||||
ItemsSource="{Binding ClickText.Value.ModeTypes}"
|
||||
ItemsSource="{Binding ClickText.ModeTypes}"
|
||||
SelectedIndex="0" />
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Command="{Binding ClickText.Value.Mode.AddCommand}"
|
||||
Command="{Binding ClickText.Mode.AddCommand}"
|
||||
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_Mode}"
|
||||
Content="+" />
|
||||
<Button
|
||||
Grid.Column="3"
|
||||
Command="{Binding ClickText.Value.Mode.RemoveCommand}"
|
||||
Command="{Binding ClickText.Mode.RemoveCommand}"
|
||||
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_Mode}"
|
||||
Content="-" />
|
||||
</Grid>
|
||||
@ -102,8 +102,8 @@
|
||||
<ComboBox
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
ItemsSource="{Binding ClickText.Value.WorkingStates}"
|
||||
SelectedItem="{Binding ClickText.Value.WorkingState.Value}" />
|
||||
ItemsSource="{Binding ClickText.WorkingStates}"
|
||||
SelectedItem="{Binding ClickText.WorkingState}" />
|
||||
<Label Grid.Row="5" Content="{ll:Str 日期区间}" />
|
||||
<Grid Grid.Row="5" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -112,54 +112,54 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{Binding ClickText.Value.DayTime.EnumValue.Value}" />
|
||||
<TextBlock Text="{Binding ClickText.DayTime.Value}" />
|
||||
<ComboBox
|
||||
x:Name="ComboBox_DayTime"
|
||||
Grid.Column="1"
|
||||
ItemsSource="{Binding ClickText.Value.DayTimes}"
|
||||
ItemsSource="{Binding ClickText.DayTimes}"
|
||||
SelectedIndex="0" />
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Command="{Binding ClickText.Value.DayTime.AddCommand}"
|
||||
Command="{Binding ClickText.DayTime.AddCommand}"
|
||||
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_DayTime}"
|
||||
Content="+" />
|
||||
<Button
|
||||
Grid.Column="3"
|
||||
Command="{Binding ClickText.Value.DayTime.RemoveCommand}"
|
||||
Command="{Binding ClickText.DayTime.RemoveCommand}"
|
||||
CommandParameter="{Binding SelectedItem, ElementName=ComboBox_DayTime}"
|
||||
Content="-" />
|
||||
</Grid>
|
||||
<ListBox Grid.Row="6" Grid.ColumnSpan="2">
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Like}"
|
||||
DataContext="{Binding ClickText.Like}"
|
||||
Tag="{ll:Str 好感度范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Health}"
|
||||
DataContext="{Binding ClickText.Health}"
|
||||
Tag="{ll:Str 健康度范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Level}"
|
||||
DataContext="{Binding ClickText.Level}"
|
||||
Tag="{ll:Str 等级范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Money}"
|
||||
DataContext="{Binding ClickText.Money}"
|
||||
Tag="{ll:Str 金钱范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Food}"
|
||||
DataContext="{Binding ClickText.Food}"
|
||||
Tag="{ll:Str 食物范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Drink}"
|
||||
DataContext="{Binding ClickText.Drink}"
|
||||
Tag="{ll:Str 口渴范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Feel}"
|
||||
DataContext="{Binding ClickText.Feel}"
|
||||
Tag="{ll:Str 心情范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
<ListBoxItem
|
||||
DataContext="{Binding ClickText.Value.Strength}"
|
||||
DataContext="{Binding ClickText.Strength}"
|
||||
Tag="{ll:Str 体力范围}"
|
||||
Template="{StaticResource ListBoxItem_RangeData}" />
|
||||
</ListBox>
|
||||
|
@ -1,5 +1,4 @@
|
||||
using LinePutScript.Localization.WPF;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -12,6 +11,7 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.ViewModels.ModEdit.ClickTextEdit;
|
||||
|
||||
@ -46,22 +46,20 @@ public partial class ClickTextEditWindow : Window
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.Value.Id.Value))
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.Id))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
ViewModel.OldClickText?.Id.Value != ViewModel.ClickText.Value.Id.Value
|
||||
&& ModInfoModel.Current.ClickTexts.Any(
|
||||
i => i.Id.Value == ViewModel.ClickText.Value.Id.Value
|
||||
)
|
||||
ViewModel.OldClickText?.Id != ViewModel.ClickText.Id
|
||||
&& ModInfoModel.Current.ClickTexts.Any(i => i.Id == ViewModel.ClickText.Id)
|
||||
)
|
||||
{
|
||||
MessageBox.Show("此Id已存在".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.Value.CurrentI18nData.Value.Text.Value))
|
||||
if (string.IsNullOrEmpty(ViewModel.ClickText.CurrentI18nData.Text))
|
||||
{
|
||||
MessageBox.Show("文本不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
|
@ -21,7 +21,7 @@
|
||||
<TextBox
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding Search.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<DataGrid
|
||||
Grid.Row="1"
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
@ -29,7 +29,7 @@
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowClickTexts.Value}"
|
||||
ItemsSource="{Binding ShowClickTexts}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="64"
|
||||
@ -45,41 +45,41 @@
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
MaxWidth="200"
|
||||
Binding="{Binding Id.Value}"
|
||||
Binding="{Binding Id}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{StaticResource TextBlock_Wrap}"
|
||||
Header="Id"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="300"
|
||||
Binding="{Binding CurrentI18nData.Value.Text.Value}"
|
||||
Binding="{Binding CurrentI18nData.Text}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{StaticResource TextBlock_Wrap}"
|
||||
Header="{ll:Str 文本}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Value.Text.Value" />
|
||||
SortMemberPath="CurrentI18nData.Text" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Mode.EnumValue.Value}"
|
||||
Binding="{Binding Mode.EnumValue}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 状态}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Mode.EnumValue.Value" />
|
||||
SortMemberPath="Mode.EnumValue" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Working.Value}"
|
||||
Binding="{Binding Working}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 指定工作}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Working.Value" />
|
||||
SortMemberPath="Working" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding WorkingState.Value}"
|
||||
Binding="{Binding WorkingState}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 工作状态}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="WorkingState.Value" />
|
||||
SortMemberPath="WorkingState" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding DayTime.EnumValue}"
|
||||
CanUserSort="True"
|
||||
|
@ -30,7 +30,7 @@
|
||||
x:Name="Image_FoodImage"
|
||||
Width="250"
|
||||
Height="250"
|
||||
Source="{Binding Food.Value.Image.Value}"
|
||||
Source="{Binding Food.Image}"
|
||||
Stretch="Uniform">
|
||||
<Image.ContextMenu>
|
||||
<ContextMenu>
|
||||
@ -44,7 +44,7 @@
|
||||
Command="{Binding AddImageCommand}"
|
||||
Content="{ll:Str 添加图片}"
|
||||
Style="{DynamicResource Button_HiddenOnTagNull}"
|
||||
Tag="{Binding Food.Value.Image.Value}" />
|
||||
Tag="{Binding Food.Image}" />
|
||||
</Grid>
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
|
||||
<Grid>
|
||||
@ -63,33 +63,33 @@
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="Id"
|
||||
Text="{Binding Food.Value.Id.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Food.Id, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="1" Content="{ll:Str 食物类型}" />
|
||||
<ComboBox
|
||||
x:Name="ComboBox_FoodType"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
ItemsSource="{Binding Food.Value.FoodTypes}"
|
||||
SelectedItem="{Binding Food.Value.Type.Value}" />
|
||||
ItemsSource="{Binding Food.FoodTypes}"
|
||||
SelectedItem="{Binding Food.Type}" />
|
||||
<Label Grid.Row="2" Content="{ll:Str 动画名称}" />
|
||||
<TextBox
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 绑定的动画名称(非必要)}"
|
||||
Text="{Binding Food.Value.Graph.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Food.Graph, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="3" Content="{ll:Str 食物名称}" />
|
||||
<TextBox
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 食物名称}"
|
||||
Text="{Binding Food.Value.CurrentI18nData.Value.Name.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Food.CurrentI18nData.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Grid.Row="4" Content="{ll:Str 食物描述}" />
|
||||
<TextBox
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 食物描述}"
|
||||
Style="{StaticResource TextBox_Wrap}"
|
||||
Text="{Binding Food.Value.CurrentI18nData.Value.Description.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Food.CurrentI18nData.Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
@ -122,42 +122,42 @@
|
||||
<pu:NumberInput
|
||||
x:Name="NumberInput_StrengthFood"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.StrengthFood.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.StrengthFood, Mode=TwoWay}" />
|
||||
<Label Grid.Row="2" Content="{ll:Str 口渴值}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.StrengthDrink.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.StrengthDrink, Mode=TwoWay}" />
|
||||
<Label Grid.Row="3" Content="{ll:Str 健康值}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.Health.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.Health, Mode=TwoWay}" />
|
||||
<Label Grid.Row="4" Content="{ll:Str 体力值}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.Strength.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.Strength, Mode=TwoWay}" />
|
||||
<Label Grid.Row="5" Content="{ll:Str 心情值}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.Feeling.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.Feeling, Mode=TwoWay}" />
|
||||
<Label Grid.Row="6" Content="{ll:Str 好感值}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.Likability.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.Likability, Mode=TwoWay}" />
|
||||
<Label Grid.Row="7" Content="{ll:Str 经验值}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.Exp.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.Exp, Mode=TwoWay}" />
|
||||
<Label Grid.Row="8" Content="{ll:Str 价格}" />
|
||||
<pu:NumberInput
|
||||
Grid.Row="8"
|
||||
Grid.Column="1"
|
||||
Value="{Binding Food.Value.Price.Value, Mode=TwoWay}" />
|
||||
Value="{Binding Food.Price, Mode=TwoWay}" />
|
||||
<Label Grid.Row="9" Content="{ll:Str 参考价格}" />
|
||||
<Grid Grid.Row="9" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -165,11 +165,11 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Food.Value.ReferencePrice.Value}" />
|
||||
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Food.ReferencePrice}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Command="{Binding SetReferencePriceCommand}"
|
||||
CommandParameter="{Binding Food.Value.ReferencePrice.Value}"
|
||||
CommandParameter="{Binding Food.ReferencePrice}"
|
||||
Content="{ll:Str 设置}"
|
||||
Style="{DynamicResource ThemedButtonStyle}" />
|
||||
<pu:Switch
|
||||
@ -177,7 +177,7 @@
|
||||
BoxHeight="16"
|
||||
BoxWidth="30"
|
||||
Content="{ll:Str 自动设置}"
|
||||
IsChecked="{Binding ModInfo.AutoSetFoodPrice.Value}" />
|
||||
IsChecked="{Binding ModInfo.AutoSetFoodPrice}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
@ -1,6 +1,4 @@
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -13,6 +11,8 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using VPet.ModMaker.Models;
|
||||
using VPet.ModMaker.ViewModels.ModEdit.FoodEdit;
|
||||
using VPet_Simulator.Windows.Interface;
|
||||
@ -51,19 +51,19 @@ public partial class FoodEditWindow : Window
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Food.Value.Id.Value))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Food.Id))
|
||||
{
|
||||
MessageBox.Show("Id不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (ViewModel.Food.Value.Image.Value is null)
|
||||
if (ViewModel.Food.Image is null)
|
||||
{
|
||||
MessageBox.Show("图像不可为空".Translate(), "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
ViewModel.OldFood?.Id.Value != ViewModel.Food.Value.Id.Value
|
||||
&& ModInfoModel.Current.Foods.Any(i => i.Id == ViewModel.Food.Value.Id)
|
||||
ViewModel.OldFood?.Id != ViewModel.Food.Id
|
||||
&& ModInfoModel.Current.Foods.Any(i => i.Id == ViewModel.Food.Id)
|
||||
)
|
||||
{
|
||||
MessageBox.Show("此Id已存在", "", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
|
@ -21,7 +21,7 @@
|
||||
<TextBox
|
||||
pu:TextBoxHelper.Watermark="{ll:Str 搜索Id}"
|
||||
Style="{DynamicResource StandardTextBoxStyle}"
|
||||
Text="{Binding Search.Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<DataGrid
|
||||
Grid.Row="1"
|
||||
d:ItemsSource="{d:SampleData ItemCount=5}"
|
||||
@ -29,7 +29,7 @@
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
ItemsSource="{Binding ShowFoods.Value}"
|
||||
ItemsSource="{Binding ShowFoods}"
|
||||
MouseDoubleClick="DataGrid_MouseDoubleClick"
|
||||
RowDetailsVisibilityMode="Visible"
|
||||
RowHeight="64"
|
||||
@ -44,12 +44,12 @@
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Id.Value}"
|
||||
Binding="{Binding Id}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="Id"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Id.Value" />
|
||||
SortMemberPath="Id" />
|
||||
<DataGridTemplateColumn Header="{ll:Str 食物图片}" IsReadOnly="True">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@ -58,7 +58,7 @@
|
||||
Height="64"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Source="{Binding Image.Value, IsAsync=True}"
|
||||
Source="{Binding Image, IsAsync=True}"
|
||||
Stretch="Uniform">
|
||||
<Image.ToolTip>
|
||||
<Image
|
||||
@ -66,7 +66,7 @@
|
||||
Height="256"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Source="{Binding Image.Value, IsAsync=True}"
|
||||
Source="{Binding Image, IsAsync=True}"
|
||||
Stretch="Uniform" />
|
||||
</Image.ToolTip>
|
||||
</Image>
|
||||
@ -74,90 +74,90 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding CurrentI18nData.Value.Name.Value}"
|
||||
Binding="{Binding CurrentI18nData.Name}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 食物名称}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Value.Name.Value" />
|
||||
SortMemberPath="CurrentI18nData.Name" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Type.Value}"
|
||||
Binding="{Binding Type}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 食物类型}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Type.Value" />
|
||||
SortMemberPath="Type" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Graph.Value}"
|
||||
Binding="{Binding Graph}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 指定动画}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Type.Value" />
|
||||
SortMemberPath="Type" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding StrengthFood.Value}"
|
||||
Binding="{Binding StrengthFood}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 饱腹值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="StrengthFood.Value" />
|
||||
SortMemberPath="StrengthFood" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding StrengthDrink.Value}"
|
||||
Binding="{Binding StrengthDrink}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 口渴值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="StrengthDrink.Value" />
|
||||
SortMemberPath="StrengthDrink" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Health.Value}"
|
||||
Binding="{Binding Health}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 健康值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Health.Value" />
|
||||
SortMemberPath="Health" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Strength.Value}"
|
||||
Binding="{Binding Strength}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 体力值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Strength.Value" />
|
||||
SortMemberPath="Strength" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Feeling.Value}"
|
||||
Binding="{Binding Feeling}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 心情值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Feeling.Value" />
|
||||
SortMemberPath="Feeling" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Likability.Value}"
|
||||
Binding="{Binding Likability}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 好感值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Likability.Value" />
|
||||
SortMemberPath="Likability" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Exp.Value}"
|
||||
Binding="{Binding Exp}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 经验值}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Exp.Value" />
|
||||
SortMemberPath="Exp" />
|
||||
<DataGridTextColumn
|
||||
Binding="{Binding Price.Value}"
|
||||
Binding="{Binding Price}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
|
||||
Header="{ll:Str 价格}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Price.Value" />
|
||||
SortMemberPath="Price" />
|
||||
<DataGridTextColumn
|
||||
MaxWidth="300"
|
||||
Binding="{Binding CurrentI18nData.Value.Description.Value}"
|
||||
Binding="{Binding CurrentI18nData.Description}"
|
||||
CanUserSort="True"
|
||||
ElementStyle="{DynamicResource TextBlock_Wrap}"
|
||||
Header="{ll:Str 描述}"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="CurrentI18nData.Value.Description.Value" />
|
||||
SortMemberPath="CurrentI18nData.Description" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user