feat: add pref window view model
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
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 BallanceTasEditor.Frontend.Converters {
|
||||||
|
|
||||||
|
internal class GenericEnumRadioButtonConverter<T> where T: struct {
|
||||||
|
public object Convert(object value, object parameter) {
|
||||||
|
var susValue = value as T?;
|
||||||
|
var susParam = parameter as T?;
|
||||||
|
|
||||||
|
if (susValue is null || susParam is null) {
|
||||||
|
return Binding.DoNothing;
|
||||||
|
} else {
|
||||||
|
return susValue.Value.Equals(susParam.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, object parameter) {
|
||||||
|
var susValue = value as bool?;
|
||||||
|
var susParam = parameter as T?;
|
||||||
|
|
||||||
|
if (susValue is null || susParam is null) {
|
||||||
|
return Binding.DoNothing;
|
||||||
|
} else {
|
||||||
|
return susValue.Value ? susParam.Value : Binding.DoNothing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ValueConversion(typeof(Shared.SequenceKind), typeof(bool))]
|
||||||
|
public class SequenceKindRadioButtonConverter : IValueConverter {
|
||||||
|
public static readonly SequenceKindRadioButtonConverter Instance = new();
|
||||||
|
|
||||||
|
private readonly GenericEnumRadioButtonConverter<Shared.SequenceKind> m_Inner = new();
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
|
return m_Inner.Convert(value, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
|
return m_Inner.ConvertBack(value, parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ValueConversion(typeof(Shared.EditorLayoutKind), typeof(bool))]
|
||||||
|
public class EditorLayoutKindRadioButtonConverter : IValueConverter {
|
||||||
|
public static readonly EditorLayoutKindRadioButtonConverter Instance = new();
|
||||||
|
|
||||||
|
private readonly GenericEnumRadioButtonConverter<Shared.EditorLayoutKind> m_Inner = new();
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
|
return m_Inner.Convert(value, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
|
return m_Inner.ConvertBack(value, parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ValueConversion(typeof(Shared.EditorPasteBehavior), typeof(bool))]
|
||||||
|
public class EditorPasteBehaviorRadioButtonConverter : IValueConverter {
|
||||||
|
public static readonly EditorPasteBehaviorRadioButtonConverter Instance = new();
|
||||||
|
|
||||||
|
private readonly GenericEnumRadioButtonConverter<Shared.EditorPasteBehavior> m_Inner = new();
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
|
return m_Inner.Convert(value, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||||
|
return m_Inner.ConvertBack(value, parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,11 +23,11 @@ namespace BallanceTasEditor.Frontend.Models {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Shared.TasSequenceKind sequenceKind;
|
private Shared.SequenceKind sequenceKind;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Shared.EditorLayoutKind editorLayout;
|
private Shared.EditorLayoutKind editorLayout;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Shared.EditorPasteMode pasteMode;
|
private Shared.EditorPasteBehavior pasteBehavior;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int frameCount;
|
private int frameCount;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -35,7 +35,7 @@ namespace BallanceTasEditor.Frontend.Models {
|
|||||||
|
|
||||||
[MemberNotNull(nameof(SequenceKind))]
|
[MemberNotNull(nameof(SequenceKind))]
|
||||||
[MemberNotNull(nameof(EditorLayout))]
|
[MemberNotNull(nameof(EditorLayout))]
|
||||||
[MemberNotNull(nameof(PasteMode))]
|
[MemberNotNull(nameof(PasteBehavior))]
|
||||||
[MemberNotNull(nameof(FrameCount))]
|
[MemberNotNull(nameof(FrameCount))]
|
||||||
[MemberNotNull(nameof(GamePath))]
|
[MemberNotNull(nameof(GamePath))]
|
||||||
private void FromSingleton() {
|
private void FromSingleton() {
|
||||||
@@ -43,7 +43,7 @@ namespace BallanceTasEditor.Frontend.Models {
|
|||||||
|
|
||||||
SequenceKind = singleton.SequenceKind;
|
SequenceKind = singleton.SequenceKind;
|
||||||
EditorLayout = singleton.EditorLayout;
|
EditorLayout = singleton.EditorLayout;
|
||||||
PasteMode = singleton.PasteMode;
|
PasteBehavior = singleton.PasteBehavior;
|
||||||
FrameCount = singleton.FrameCount;
|
FrameCount = singleton.FrameCount;
|
||||||
GamePath = singleton.GamePath;
|
GamePath = singleton.GamePath;
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ namespace BallanceTasEditor.Frontend.Models {
|
|||||||
|
|
||||||
singleton.SequenceKind = SequenceKind;
|
singleton.SequenceKind = SequenceKind;
|
||||||
singleton.EditorLayout = EditorLayout;
|
singleton.EditorLayout = EditorLayout;
|
||||||
singleton.PasteMode = PasteMode;
|
singleton.PasteBehavior = PasteBehavior;
|
||||||
singleton.FrameCount = FrameCount;
|
singleton.FrameCount = FrameCount;
|
||||||
singleton.GamePath = GamePath;
|
singleton.GamePath = GamePath;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,28 +30,28 @@ namespace BallanceTasEditor.Frontend.Models {
|
|||||||
get => FileBody is null;
|
get => FileBody is null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NewFile(Shared.TasSequenceKind kind, int count, uint fps) {
|
public void NewFile(Shared.SequenceKind kind, int count, uint fps) {
|
||||||
// Check status
|
// Check status
|
||||||
if (IsFileLoaded) {
|
if (IsFileLoaded) {
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize sequence
|
// Initialize sequence
|
||||||
var seq = Shared.TasSequenceKindHelper.CreateSequenceByKind(kind);
|
var seq = Shared.SequenceKindHelper.CreateSequenceByKind(kind);
|
||||||
// Initialize items
|
// Initialize items
|
||||||
Backend.TasStorage.Init(seq, count, fps);
|
Backend.TasStorage.Init(seq, count, fps);
|
||||||
// Set members
|
// Set members
|
||||||
FileBody = seq;
|
FileBody = seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFile(Shared.TasSequenceKind kind, string path) {
|
public void LoadFile(Shared.SequenceKind kind, string path) {
|
||||||
// Check status
|
// Check status
|
||||||
if (IsFileLoaded) {
|
if (IsFileLoaded) {
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize sequence
|
// Initialize sequence
|
||||||
var seq = Shared.TasSequenceKindHelper.CreateSequenceByKind(kind);
|
var seq = Shared.SequenceKindHelper.CreateSequenceByKind(kind);
|
||||||
// Load into sequence
|
// Load into sequence
|
||||||
Backend.TasStorage.Load(path, seq);
|
Backend.TasStorage.Load(path, seq);
|
||||||
// Set members
|
// Set members
|
||||||
|
|||||||
@@ -18,21 +18,21 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TasSequenceKind SequenceKind { get; set; }
|
public SequenceKind SequenceKind { get; set; }
|
||||||
public EditorLayoutKind EditorLayout { get; set; }
|
public EditorLayoutKind EditorLayout { get; set; }
|
||||||
public EditorPasteMode PasteMode { get; set; }
|
public EditorPasteBehavior PasteBehavior { get; set; }
|
||||||
public int FrameCount { get; set; }
|
public int FrameCount { get; set; }
|
||||||
public string GamePath { get; set; }
|
public string GamePath { get; set; }
|
||||||
|
|
||||||
[MemberNotNull(nameof(SequenceKind))]
|
[MemberNotNull(nameof(SequenceKind))]
|
||||||
[MemberNotNull(nameof(EditorLayout))]
|
[MemberNotNull(nameof(EditorLayout))]
|
||||||
[MemberNotNull(nameof(PasteMode))]
|
[MemberNotNull(nameof(PasteBehavior))]
|
||||||
[MemberNotNull(nameof(FrameCount))]
|
[MemberNotNull(nameof(FrameCount))]
|
||||||
[MemberNotNull(nameof(GamePath))]
|
[MemberNotNull(nameof(GamePath))]
|
||||||
private void FromRaw(RawEditorConfiguration raw) {
|
private void FromRaw(RawEditorConfiguration raw) {
|
||||||
SequenceKind = raw.SequenceKind;
|
SequenceKind = raw.SequenceKind;
|
||||||
EditorLayout = raw.EditorLayout;
|
EditorLayout = raw.EditorLayout;
|
||||||
PasteMode = raw.PasteMode;
|
PasteBehavior = raw.PasteBehavior;
|
||||||
FrameCount = raw.FrameCount;
|
FrameCount = raw.FrameCount;
|
||||||
GamePath = raw.GamePath;
|
GamePath = raw.GamePath;
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
return new RawEditorConfiguration {
|
return new RawEditorConfiguration {
|
||||||
SequenceKind = SequenceKind,
|
SequenceKind = SequenceKind,
|
||||||
EditorLayout = EditorLayout,
|
EditorLayout = EditorLayout,
|
||||||
PasteMode = PasteMode,
|
PasteBehavior = PasteBehavior,
|
||||||
FrameCount = FrameCount,
|
FrameCount = FrameCount,
|
||||||
GamePath = GamePath
|
GamePath = GamePath
|
||||||
};
|
};
|
||||||
@@ -69,7 +69,7 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
|
|
||||||
[MemberNotNull(nameof(SequenceKind))]
|
[MemberNotNull(nameof(SequenceKind))]
|
||||||
[MemberNotNull(nameof(EditorLayout))]
|
[MemberNotNull(nameof(EditorLayout))]
|
||||||
[MemberNotNull(nameof(PasteMode))]
|
[MemberNotNull(nameof(PasteBehavior))]
|
||||||
[MemberNotNull(nameof(FrameCount))]
|
[MemberNotNull(nameof(FrameCount))]
|
||||||
[MemberNotNull(nameof(GamePath))]
|
[MemberNotNull(nameof(GamePath))]
|
||||||
private void Init() {
|
private void Init() {
|
||||||
@@ -103,15 +103,15 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
private class RawEditorConfiguration {
|
private class RawEditorConfiguration {
|
||||||
[JsonProperty("sequence_kind", Required = Required.Always)]
|
[JsonProperty("sequence_kind", Required = Required.Always)]
|
||||||
[JsonConverter(typeof(TasSequenceKindConverter))]
|
[JsonConverter(typeof(TasSequenceKindConverter))]
|
||||||
public TasSequenceKind SequenceKind { get; set; } = TasSequenceKind.Array;
|
public SequenceKind SequenceKind { get; set; } = SequenceKind.Array;
|
||||||
|
|
||||||
[JsonProperty("editor_layout", Required = Required.Always)]
|
[JsonProperty("editor_layout", Required = Required.Always)]
|
||||||
[JsonConverter(typeof(EditorLayoutKindConverter))]
|
[JsonConverter(typeof(EditorLayoutKindConverter))]
|
||||||
public EditorLayoutKind EditorLayout { get; set; } = EditorLayoutKind.Vertical;
|
public EditorLayoutKind EditorLayout { get; set; } = EditorLayoutKind.Vertical;
|
||||||
|
|
||||||
[JsonProperty("paste_mode", Required = Required.Always)]
|
[JsonProperty("paste_behavior", Required = Required.Always)]
|
||||||
[JsonConverter(typeof(EditorPasteModeConverter))]
|
[JsonConverter(typeof(EditorPasteBehaviorConverter))]
|
||||||
public EditorPasteMode PasteMode { get; set; } = EditorPasteMode.Insert;
|
public EditorPasteBehavior PasteBehavior { get; set; } = EditorPasteBehavior.Insert;
|
||||||
|
|
||||||
[JsonProperty("frame_count", Required = Required.Always)]
|
[JsonProperty("frame_count", Required = Required.Always)]
|
||||||
public int FrameCount { get; set; } = 20;
|
public int FrameCount { get; set; } = 20;
|
||||||
@@ -122,11 +122,11 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
|
|
||||||
#region Custom JSON Converter
|
#region Custom JSON Converter
|
||||||
|
|
||||||
private class TasSequenceKindConverter : JsonConverter<TasSequenceKind> {
|
private class TasSequenceKindConverter : JsonConverter<SequenceKind> {
|
||||||
public override TasSequenceKind ReadJson(JsonReader reader, Type objectType, TasSequenceKind existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
public override SequenceKind ReadJson(JsonReader reader, Type objectType, SequenceKind existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||||
if (reader.TokenType == JsonToken.String) {
|
if (reader.TokenType == JsonToken.String) {
|
||||||
var value = (reader.Value as string).Unwrap();
|
var value = (reader.Value as string).Unwrap();
|
||||||
if (TasSequenceKindHelper.TryParse(value, out var kind)) {
|
if (SequenceKindHelper.TryParse(value, out var kind)) {
|
||||||
return kind;
|
return kind;
|
||||||
} else {
|
} else {
|
||||||
throw new JsonSerializationException($"given string can not be parsed as TasSequenceKind: {value}");
|
throw new JsonSerializationException($"given string can not be parsed as TasSequenceKind: {value}");
|
||||||
@@ -136,8 +136,8 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, TasSequenceKind value, JsonSerializer serializer) {
|
public override void WriteJson(JsonWriter writer, SequenceKind value, JsonSerializer serializer) {
|
||||||
writer.WriteValue(TasSequenceKindHelper.ToString(value));
|
writer.WriteValue(SequenceKindHelper.ToString(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,22 +160,22 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EditorPasteModeConverter : JsonConverter<EditorPasteMode> {
|
private class EditorPasteBehaviorConverter : JsonConverter<EditorPasteBehavior> {
|
||||||
public override EditorPasteMode ReadJson(JsonReader reader, Type objectType, EditorPasteMode existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
public override EditorPasteBehavior ReadJson(JsonReader reader, Type objectType, EditorPasteBehavior existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||||
if (reader.TokenType == JsonToken.String) {
|
if (reader.TokenType == JsonToken.String) {
|
||||||
var value = (reader.Value as string).Unwrap();
|
var value = (reader.Value as string).Unwrap();
|
||||||
if (EditorPasteModeHelper.TryParse(value, out var kind)) {
|
if (EditorPasteBehaviorHelper.TryParse(value, out var kind)) {
|
||||||
return kind;
|
return kind;
|
||||||
} else {
|
} else {
|
||||||
throw new JsonSerializationException($"given string can not be parsed as EditorPasteMode: {value}");
|
throw new JsonSerializationException($"given string can not be parsed as EditorPasteBehavior: {value}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new JsonSerializationException($"expect a integer but got {reader.TokenType}");
|
throw new JsonSerializationException($"expect a integer but got {reader.TokenType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, EditorPasteMode value, JsonSerializer serializer) {
|
public override void WriteJson(JsonWriter writer, EditorPasteBehavior value, JsonSerializer serializer) {
|
||||||
writer.WriteValue(EditorPasteModeHelper.ToString(value));
|
writer.WriteValue(EditorPasteBehaviorHelper.ToString(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,27 +8,27 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace BallanceTasEditor.Frontend.Shared {
|
namespace BallanceTasEditor.Frontend.Shared {
|
||||||
|
|
||||||
public enum TasSequenceKind {
|
public enum SequenceKind {
|
||||||
Array,
|
Array,
|
||||||
DoubleLinkedList
|
DoubleLinkedList
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TasSequenceKindHelper {
|
public static class SequenceKindHelper {
|
||||||
public static Backend.ITasSequence CreateSequenceByKind(TasSequenceKind kind) {
|
public static Backend.ITasSequence CreateSequenceByKind(SequenceKind kind) {
|
||||||
return kind switch {
|
return kind switch {
|
||||||
TasSequenceKind.Array => new Backend.ListTasSequence(),
|
SequenceKind.Array => new Backend.ListTasSequence(),
|
||||||
TasSequenceKind.DoubleLinkedList => new Backend.LegacyTasSequence(),
|
SequenceKind.DoubleLinkedList => new Backend.LegacyTasSequence(),
|
||||||
_ => throw new UnreachableException(),
|
_ => throw new UnreachableException(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryParse(string s, out TasSequenceKind value) {
|
public static bool TryParse(string s, out SequenceKind value) {
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case "array":
|
case "array":
|
||||||
value = TasSequenceKind.Array;
|
value = SequenceKind.Array;
|
||||||
return true;
|
return true;
|
||||||
case "double_linked_list":
|
case "double_linked_list":
|
||||||
value = TasSequenceKind.DoubleLinkedList;
|
value = SequenceKind.DoubleLinkedList;
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
value = default;
|
value = default;
|
||||||
@@ -36,10 +36,10 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToString(TasSequenceKind kind) {
|
public static string ToString(SequenceKind kind) {
|
||||||
return kind switch {
|
return kind switch {
|
||||||
TasSequenceKind.Array => "array",
|
SequenceKind.Array => "array",
|
||||||
TasSequenceKind.DoubleLinkedList => "double_linked_list",
|
SequenceKind.DoubleLinkedList => "double_linked_list",
|
||||||
_ => throw new UnreachableException(),
|
_ => throw new UnreachableException(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -73,19 +73,19 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EditorPasteMode {
|
public enum EditorPasteBehavior {
|
||||||
Insert,
|
Insert,
|
||||||
Override
|
Override
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EditorPasteModeHelper {
|
public static class EditorPasteBehaviorHelper {
|
||||||
public static bool TryParse(string s, out EditorPasteMode value) {
|
public static bool TryParse(string s, out EditorPasteBehavior value) {
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case "insert":
|
case "insert":
|
||||||
value = EditorPasteMode.Insert;
|
value = EditorPasteBehavior.Insert;
|
||||||
return true;
|
return true;
|
||||||
case "override":
|
case "override":
|
||||||
value = EditorPasteMode.Override;
|
value = EditorPasteBehavior.Override;
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
value = default;
|
value = default;
|
||||||
@@ -93,10 +93,10 @@ namespace BallanceTasEditor.Frontend.Shared {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToString(EditorPasteMode mode) {
|
public static string ToString(EditorPasteBehavior mode) {
|
||||||
return mode switch {
|
return mode switch {
|
||||||
EditorPasteMode.Insert => "insert",
|
EditorPasteBehavior.Insert => "insert",
|
||||||
EditorPasteMode.Override => "override",
|
EditorPasteBehavior.Override => "override",
|
||||||
_ => throw new UnreachableException(),
|
_ => throw new UnreachableException(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
|||||||
if (dialog is null) return;
|
if (dialog is null) return;
|
||||||
|
|
||||||
// Create new file
|
// Create new file
|
||||||
TasFile.NewFile(Shared.TasSequenceKind.Array, dialog.Count, dialog.Fps);
|
TasFile.NewFile(Shared.SequenceKind.Array, dialog.Count, dialog.Fps);
|
||||||
// Set members
|
// Set members
|
||||||
TasFilePath = null;
|
TasFilePath = null;
|
||||||
// Send notification
|
// Send notification
|
||||||
@@ -80,7 +80,7 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
|||||||
|
|
||||||
// Load file
|
// Load file
|
||||||
try {
|
try {
|
||||||
TasFile.LoadFile(Shared.TasSequenceKind.Array, dialog.Path);
|
TasFile.LoadFile(Shared.SequenceKind.Array, dialog.Path);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
m_DialogService.ShowOpenFileFailedDialog(e);
|
m_DialogService.ShowOpenFileFailedDialog(e);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,17 +2,47 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
|||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BallanceTasEditor.Frontend.ViewModels {
|
namespace BallanceTasEditor.Frontend.ViewModels {
|
||||||
public partial class PreferenceDialog : ObservableObject {
|
public partial class PreferenceDialog : ObservableValidator {
|
||||||
public PreferenceDialog() {
|
public PreferenceDialog() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private Shared.SequenceKind sequenceKind;
|
||||||
|
[ObservableProperty]
|
||||||
|
private Shared.EditorLayoutKind layoutKind;
|
||||||
|
[ObservableProperty]
|
||||||
|
private Shared.EditorPasteBehavior pasteBehavior;
|
||||||
|
[ObservableProperty]
|
||||||
|
[NotifyDataErrorInfo]
|
||||||
|
[CustomValidation(typeof(PreferenceDialog), nameof(ValidateCount))]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
|
||||||
|
private string frameCount;
|
||||||
|
[ObservableProperty]
|
||||||
|
private string gamePath;
|
||||||
|
|
||||||
|
#region Validators
|
||||||
|
|
||||||
|
private static readonly Validators.ValidatorAdapter<string, int, Validators.CountValidator> g_CountValidator =
|
||||||
|
new Validators.ValidatorAdapter<string, int, Validators.CountValidator>(new Validators.CountValidator());
|
||||||
|
|
||||||
|
public static ValidationResult? ValidateCount(string value, ValidationContext context) {
|
||||||
|
return g_CountValidator.Validate(value, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
//public Shared.NewFileDialogResult GetUserInput() {
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Commands
|
||||||
|
|
||||||
[RelayCommand(CanExecute = nameof(CanOk))]
|
[RelayCommand(CanExecute = nameof(CanOk))]
|
||||||
private void Ok() {
|
private void Ok() {
|
||||||
@@ -20,8 +50,7 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool CanOk() {
|
private bool CanOk() {
|
||||||
// TODO
|
return !HasErrors;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
@@ -29,12 +58,13 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
|||||||
OnRequestCloseDialog(false);
|
OnRequestCloseDialog(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
|
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
|
||||||
|
|
||||||
private void OnRequestCloseDialog(bool result) {
|
private void OnRequestCloseDialog(bool result) {
|
||||||
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
|
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
|
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
|
||||||
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
|
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
|
||||||
|
xmlns:conveter="clr-namespace:BallanceTasEditor.Frontend.Converters"
|
||||||
|
xmlns:shared="clr-namespace:BallanceTasEditor.Frontend.Shared"
|
||||||
xmlns:widget="clr-namespace:BallanceTasEditor.Frontend.Widgets"
|
xmlns:widget="clr-namespace:BallanceTasEditor.Frontend.Widgets"
|
||||||
d:DataContext="{d:DesignInstance vm:PreferenceDialog}"
|
d:DataContext="{d:DesignInstance vm:PreferenceDialog}"
|
||||||
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
|
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
|
||||||
Title="Editor Preference" Height="450" Width="400" Icon="/Frontend/Assets/Preference.ico">
|
Title="Editor Preference" Height="500" Width="400" Icon="/Frontend/Assets/Preference.ico">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
@@ -17,7 +19,7 @@
|
|||||||
|
|
||||||
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Visible">
|
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Visible">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<widget:IconGroupBox GroupBoxText="Editor Layout"
|
<widget:IconGroupBox GroupBoxText="Sequence Kind"
|
||||||
GroupBoxIcon="/Frontend/Assets/EditorLayout.ico"
|
GroupBoxIcon="/Frontend/Assets/EditorLayout.ico"
|
||||||
Margin="10" Padding="10">
|
Margin="10" Padding="10">
|
||||||
<Grid>
|
<Grid>
|
||||||
@@ -25,26 +27,56 @@
|
|||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<RadioButton Content="Horizontal Layout" GroupName="EditorLayout" Grid.Column="0"/>
|
<RadioButton Content="Array" GroupName="SequenceKind"
|
||||||
<RadioButton Content="Vertical Layout" GroupName="EditorLayout" Grid.Column="1"/>
|
ToolTip="Good for browsing. Bad for frequently inserting and removing frames."
|
||||||
|
IsChecked="{Binding SequenceKind, Mode=TwoWay, Converter={x:Static conveter:SequenceKindRadioButtonConverter.Instance}, ConverterParameter={x:Static shared:SequenceKind.Array}}"
|
||||||
|
Grid.Column="0"/>
|
||||||
|
<RadioButton Content="Double Linked List" GroupName="SequenceKind"
|
||||||
|
ToolTip="Good for frequently inserting and removing frames. Bad for browsing."
|
||||||
|
IsChecked="{Binding SequenceKind, Mode=TwoWay, Converter={x:Static conveter:SequenceKindRadioButtonConverter.Instance}, ConverterParameter={x:Static shared:SequenceKind.DoubleLinkedList}}"
|
||||||
|
Grid.Column="1"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</widget:IconGroupBox>
|
</widget:IconGroupBox>
|
||||||
<widget:IconGroupBox GroupBoxText="Paste Behavior"
|
<widget:IconGroupBox GroupBoxText="Editor Layout"
|
||||||
GroupBoxIcon="/Frontend/Assets/PasteFrame.ico"
|
GroupBoxIcon="/Frontend/Assets/EditorLayout.ico"
|
||||||
Margin="10" Padding="10">
|
Margin="10" Padding="10"
|
||||||
|
IsEnabled="False">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<RadioButton Content="Insert Paste" GroupName="PasteBehavior" Grid.Column="0"/>
|
<RadioButton Content="Horizontal Layout" GroupName="EditorLayout"
|
||||||
<RadioButton Content="Overwritten Paste" GroupName="PasteBehavior" Grid.Column="1"/>
|
IsChecked="{Binding LayoutKind, Mode=TwoWay, Converter={x:Static conveter:EditorLayoutKindRadioButtonConverter.Instance}, ConverterParameter={x:Static shared:EditorLayoutKind.Horizontal}}"
|
||||||
|
Grid.Column="0"/>
|
||||||
|
<RadioButton Content="Vertical Layout" GroupName="EditorLayout"
|
||||||
|
IsChecked="{Binding LayoutKind, Mode=TwoWay, Converter={x:Static conveter:EditorLayoutKindRadioButtonConverter.Instance}, ConverterParameter={x:Static shared:EditorLayoutKind.Vertical}}"
|
||||||
|
Grid.Column="1"/>
|
||||||
|
</Grid>
|
||||||
|
</widget:IconGroupBox>
|
||||||
|
<widget:IconGroupBox GroupBoxText="Paste Behavior"
|
||||||
|
GroupBoxIcon="/Frontend/Assets/PasteFrame.ico"
|
||||||
|
Margin="10" Padding="10"
|
||||||
|
IsEnabled="False">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<RadioButton Content="Insert Paste" GroupName="PasteBehavior"
|
||||||
|
IsChecked="{Binding PasteBehavior, Mode=TwoWay, Converter={x:Static conveter:EditorPasteBehaviorRadioButtonConverter.Instance}, ConverterParameter={x:Static shared:EditorPasteBehavior.Insert}}"
|
||||||
|
Grid.Column="0"/>
|
||||||
|
<RadioButton Content="Overwritten Paste" GroupName="PasteBehavior"
|
||||||
|
IsChecked="{Binding PasteBehavior, Mode=TwoWay, Converter={x:Static conveter:EditorPasteBehaviorRadioButtonConverter.Instance}, ConverterParameter={x:Static shared:EditorPasteBehavior.Override}}"
|
||||||
|
Grid.Column="1"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</widget:IconGroupBox>
|
</widget:IconGroupBox>
|
||||||
<widget:IconGroupBox GroupBoxText="Frame Count"
|
<widget:IconGroupBox GroupBoxText="Frame Count"
|
||||||
GroupBoxIcon="/Frontend/Assets/Count.ico"
|
GroupBoxIcon="/Frontend/Assets/Count.ico"
|
||||||
Margin="10" Padding="10">
|
Margin="10" Padding="10">
|
||||||
<TextBox Padding="3"/>
|
<TextBox Padding="3"
|
||||||
|
Text="{Binding FrameCount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}"
|
||||||
|
Style="{StaticResource TextBoxWithErrorNotifyStyle}"/>
|
||||||
</widget:IconGroupBox>
|
</widget:IconGroupBox>
|
||||||
<widget:IconGroupBox GroupBoxText="Game Path"
|
<widget:IconGroupBox GroupBoxText="Game Path"
|
||||||
GroupBoxIcon="/Frontend/Assets/SaveFileThenRunGame.ico"
|
GroupBoxIcon="/Frontend/Assets/SaveFileThenRunGame.ico"
|
||||||
|
|||||||
Reference in New Issue
Block a user