Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3442ace981 | ||
|
|
547cebf5a9 | ||
|
|
7a24d22bc6 | ||
|
|
8f5728afe4 | ||
|
|
41b5ac2c61 | ||
|
|
694ca3bf25 | ||
|
|
674d314b55 | ||
|
|
08a35cc5d1 | ||
|
|
176e5db4d9 | ||
|
|
2535a9ebf9 | ||
|
|
8ff99ee925 | ||
|
|
abc8218487 | ||
|
|
e4765750c3 | ||
|
|
02cddf556b | ||
|
|
e1e6d3c72d |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -1,28 +1,38 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.10.6
|
||||||
|
|
||||||
|
- 增加文件夹检测
|
||||||
|
- 增加从剪贴板添加(可复制本地文件/文件夹直接打开)
|
||||||
|
- 修复预览图导致的批量添加可能卡死
|
||||||
|
|
||||||
|
## v0.10.5
|
||||||
|
|
||||||
|
- 修复一些问题
|
||||||
|
|
||||||
## v0.10.4
|
## v0.10.4
|
||||||
|
|
||||||
- <EFBFBD><EFBFBD>һЩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
- 修复一些问题
|
||||||
|
|
||||||
## v0.10.3
|
## v0.10.3
|
||||||
|
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD>汾<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
- 增加自动版本检测
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>ϷŴ<EFBFBD><EFBFBD><EFBFBD>
|
- 增加文件拖放打开
|
||||||
|
|
||||||
## v0.10.2
|
## v0.10.2
|
||||||
|
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD>Ҽ<EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>
|
- 增加列表右键菜单快捷键
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
- 增加预览缩略图复制
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD>л<EFBFBD>
|
- 增加列表视图切换
|
||||||
|
|
||||||
## v0.10.1
|
## v0.10.1
|
||||||
|
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>Ԥ<EFBFBD><EFBFBD>ͼ
|
- 增加列表预览图
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>Ԥ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
- 增加列表预览图导出
|
||||||
|
|
||||||
## v0.10.0
|
## v0.10.0
|
||||||
|
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>
|
- 增加了画面和列表的选择联动,并删除了预览画面显示包围盒选项
|
||||||
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ʽת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD>Ŀǰ<EFBFBD><EFBFBD>֧<EFBFBD>ֲ<EFBFBD><EFBFBD>ְ汾<EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
- 增加了骨骼文件格式转换功能,目前仅支持部分版本的不完整功能
|
||||||
- <EFBFBD>Ż<EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
- 优化了部分使用体验
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
| `4.2.x` | :white_check_mark: | |
|
| `4.2.x` | :white_check_mark: | |
|
||||||
| `4.3.x` | | |
|
| `4.3.x` | | |
|
||||||
|
|
||||||
- 支持文件拖放打开
|
- 支持文件拖放/复制到剪贴板打开
|
||||||
- 支持自动检测版本
|
- 支持自动检测版本
|
||||||
- 支持列表缩略图预览
|
- 支持列表缩略图预览
|
||||||
- 支持多骨骼文件动画预览
|
- 支持多骨骼文件动画预览
|
||||||
|
|||||||
14
SpineViewer/Controls/SpineListView.Designer.cs
generated
14
SpineViewer/Controls/SpineListView.Designer.cs
generated
@@ -53,6 +53,7 @@
|
|||||||
toolStripMenuItem_DetailsView = new ToolStripMenuItem();
|
toolStripMenuItem_DetailsView = new ToolStripMenuItem();
|
||||||
imageList_LargeIcon = new ImageList(components);
|
imageList_LargeIcon = new ImageList(components);
|
||||||
imageList_SmallIcon = new ImageList(components);
|
imageList_SmallIcon = new ImageList(components);
|
||||||
|
toolStripMenuItem_AddFromClipboard = new ToolStripMenuItem();
|
||||||
contextMenuStrip.SuspendLayout();
|
contextMenuStrip.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
@@ -88,9 +89,9 @@
|
|||||||
// contextMenuStrip
|
// contextMenuStrip
|
||||||
//
|
//
|
||||||
contextMenuStrip.ImageScalingSize = new Size(24, 24);
|
contextMenuStrip.ImageScalingSize = new Size(24, 24);
|
||||||
contextMenuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_Add, toolStripMenuItem_Insert, toolStripMenuItem_Remove, toolStripSeparator1, toolStripMenuItem_BatchAdd, toolStripMenuItem_RemoveAll, toolStripSeparator2, toolStripMenuItem_MoveUp, toolStripMenuItem_MoveDown, toolStripMenuItem_MoveTop, toolStripMenuItem_MoveBottom, toolStripSeparator3, toolStripMenuItem_SelectAll, toolStripMenuItem_CopyPreview, toolStripSeparator4, toolStripMenuItem_ChangeView });
|
contextMenuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_Add, toolStripMenuItem_Insert, toolStripMenuItem_Remove, toolStripSeparator1, toolStripMenuItem_BatchAdd, toolStripMenuItem_RemoveAll, toolStripSeparator2, toolStripMenuItem_MoveUp, toolStripMenuItem_MoveDown, toolStripMenuItem_MoveTop, toolStripMenuItem_MoveBottom, toolStripSeparator3, toolStripMenuItem_CopyPreview, toolStripMenuItem_AddFromClipboard, toolStripMenuItem_SelectAll, toolStripSeparator4, toolStripMenuItem_ChangeView });
|
||||||
contextMenuStrip.Name = "contextMenuStrip";
|
contextMenuStrip.Name = "contextMenuStrip";
|
||||||
contextMenuStrip.Size = new Size(329, 388);
|
contextMenuStrip.Size = new Size(329, 451);
|
||||||
contextMenuStrip.Closed += contextMenuStrip_Closed;
|
contextMenuStrip.Closed += contextMenuStrip_Closed;
|
||||||
contextMenuStrip.Opening += contextMenuStrip_Opening;
|
contextMenuStrip.Opening += contextMenuStrip_Opening;
|
||||||
//
|
//
|
||||||
@@ -241,6 +242,14 @@
|
|||||||
imageList_SmallIcon.ImageSize = new Size(48, 48);
|
imageList_SmallIcon.ImageSize = new Size(48, 48);
|
||||||
imageList_SmallIcon.TransparentColor = Color.Transparent;
|
imageList_SmallIcon.TransparentColor = Color.Transparent;
|
||||||
//
|
//
|
||||||
|
// toolStripMenuItem_AddFromClipboard
|
||||||
|
//
|
||||||
|
toolStripMenuItem_AddFromClipboard.Name = "toolStripMenuItem_AddFromClipboard";
|
||||||
|
toolStripMenuItem_AddFromClipboard.ShortcutKeys = Keys.Control | Keys.V;
|
||||||
|
toolStripMenuItem_AddFromClipboard.Size = new Size(328, 30);
|
||||||
|
toolStripMenuItem_AddFromClipboard.Text = "从剪贴板添加";
|
||||||
|
toolStripMenuItem_AddFromClipboard.Click += toolStripMenuItem_AddFromClipboard_Click;
|
||||||
|
//
|
||||||
// SpineListView
|
// SpineListView
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||||
@@ -277,5 +286,6 @@
|
|||||||
private ToolStripMenuItem toolStripMenuItem_CopyPreview;
|
private ToolStripMenuItem toolStripMenuItem_CopyPreview;
|
||||||
private ToolStripMenuItem toolStripMenuItem_SelectAll;
|
private ToolStripMenuItem toolStripMenuItem_SelectAll;
|
||||||
private ToolStripSeparator toolStripSeparator4;
|
private ToolStripSeparator toolStripSeparator4;
|
||||||
|
private ToolStripMenuItem toolStripMenuItem_AddFromClipboard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,30 +64,6 @@ namespace SpineViewer.Controls
|
|||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 弹出对话框导出列表预览图
|
|
||||||
/// </summary>
|
|
||||||
public void ExportPreviews()
|
|
||||||
{
|
|
||||||
lock (Spines)
|
|
||||||
{
|
|
||||||
if (spines.Count <= 0)
|
|
||||||
{
|
|
||||||
MessageBox.Show("请至少打开一个骨骼文件", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var saveDialog = new Dialogs.ExportPreviewDialog();
|
|
||||||
if (saveDialog.ShowDialog() != DialogResult.OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
|
||||||
progressDialog.DoWork += ExportPreview_Work;
|
|
||||||
progressDialog.RunWorkerAsync(saveDialog);
|
|
||||||
progressDialog.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listView_SelectedIndexChanged(object sender, EventArgs e)
|
private void listView_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (PropertyGrid is not null)
|
if (PropertyGrid is not null)
|
||||||
@@ -107,12 +83,14 @@ namespace SpineViewer.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BUG: 图标显示的时候没法自动刷新顺序, 只能切换视图刷新, 不知道什么原理
|
// XXX: 图标显示的时候没法自动刷新顺序, 只能切换视图刷新, 不知道什么原理
|
||||||
listView.BeginUpdate();
|
if (listView.View == View.LargeIcon)
|
||||||
var tmp = listView.View;
|
{
|
||||||
listView.View = View.List;
|
listView.BeginUpdate();
|
||||||
listView.View = tmp;
|
listView.View = View.List;
|
||||||
listView.EndUpdate();
|
listView.View = View.LargeIcon;
|
||||||
|
listView.EndUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
if (listView.SelectedItems.Count > 0)
|
if (listView.SelectedItems.Count > 0)
|
||||||
listView.SelectedItems[0].EnsureVisible();
|
listView.SelectedItems[0].EnsureVisible();
|
||||||
@@ -136,7 +114,7 @@ namespace SpineViewer.Controls
|
|||||||
private void listView_DragOver(object sender, DragEventArgs e)
|
private void listView_DragOver(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Data.GetDataPresent(DataFormats.Serializable))
|
if (e.Data.GetDataPresent(DataFormats.Serializable))
|
||||||
{
|
{
|
||||||
// 获取鼠标位置并确定目标索引
|
// 获取鼠标位置并确定目标索引
|
||||||
var point = listView.PointToClient(new(e.X, e.Y));
|
var point = listView.PointToClient(new(e.X, e.Y));
|
||||||
var targetItem = listView.GetItemAt(point.X, point.Y);
|
var targetItem = listView.GetItemAt(point.X, point.Y);
|
||||||
@@ -195,23 +173,7 @@ namespace SpineViewer.Controls
|
|||||||
}
|
}
|
||||||
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||||
{
|
{
|
||||||
var validPaths = ((string[])e.Data.GetData(DataFormats.FileDrop)).Where(
|
AddFromFileDrop((string[])e.Data.GetData(DataFormats.FileDrop));
|
||||||
path => File.Exists(path) &&
|
|
||||||
(Path.GetExtension(path).Equals(".skel", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
Path.GetExtension(path).Equals(".json", StringComparison.OrdinalIgnoreCase))
|
|
||||||
).ToArray();
|
|
||||||
|
|
||||||
if (validPaths.Length > 1)
|
|
||||||
{
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
|
||||||
progressDialog.DoWork += BatchAdd_Work;
|
|
||||||
progressDialog.RunWorkerAsync(new Dialogs.BatchOpenSpineDialogResult(Spine.Version.Auto, validPaths));
|
|
||||||
progressDialog.ShowDialog();
|
|
||||||
}
|
|
||||||
else if (validPaths.Length > 0)
|
|
||||||
{
|
|
||||||
Insert(new Dialogs.OpenSpineDialogResult(Spine.Version.Auto, validPaths[0]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,12 +309,9 @@ namespace SpineViewer.Controls
|
|||||||
{
|
{
|
||||||
lock (Spines)
|
lock (Spines)
|
||||||
{
|
{
|
||||||
lock (Spines)
|
var spine = spines[index];
|
||||||
{
|
spines.RemoveAt(index);
|
||||||
var spine = spines[index];
|
spines.Add(spine);
|
||||||
spines.RemoveAt(index);
|
|
||||||
spines.Add(spine);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var item = listView.Items[index];
|
var item = listView.Items[index];
|
||||||
listView.Items.RemoveAt(index);
|
listView.Items.RemoveAt(index);
|
||||||
@@ -381,14 +340,6 @@ namespace SpineViewer.Controls
|
|||||||
PropertyGrid.SelectedObject = null;
|
PropertyGrid.SelectedObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
listView.BeginUpdate();
|
|
||||||
foreach (ListViewItem item in listView.Items)
|
|
||||||
item.Selected = true;
|
|
||||||
listView.EndUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toolStripMenuItem_CopyPreview_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_CopyPreview_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var fileDropList = new StringCollection();
|
var fileDropList = new StringCollection();
|
||||||
@@ -409,6 +360,25 @@ namespace SpineViewer.Controls
|
|||||||
Clipboard.SetFileDropList(fileDropList);
|
Clipboard.SetFileDropList(fileDropList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void toolStripMenuItem_AddFromClipboard_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Clipboard.ContainsFileDropList())
|
||||||
|
{
|
||||||
|
var fileDropList = Clipboard.GetFileDropList();
|
||||||
|
var paths = new string[fileDropList.Count];
|
||||||
|
fileDropList.CopyTo(paths, 0);
|
||||||
|
AddFromFileDrop(paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
listView.BeginUpdate();
|
||||||
|
foreach (ListViewItem item in listView.Items)
|
||||||
|
item.Selected = true;
|
||||||
|
listView.EndUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_LargeIconView_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_LargeIconView_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
listView.View = View.LargeIcon;
|
listView.View = View.LargeIcon;
|
||||||
@@ -526,57 +496,42 @@ namespace SpineViewer.Controls
|
|||||||
Program.Logger.Info($"Current memory usage: {Program.Process.WorkingSet64 / 1024.0 / 1024.0:F2} MB");
|
Program.Logger.Info($"Current memory usage: {Program.Process.WorkingSet64 / 1024.0 / 1024.0:F2} MB");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExportPreview_Work(object? sender, DoWorkEventArgs e)
|
private void AddFromFileDrop(string[] paths)
|
||||||
{
|
{
|
||||||
var worker = sender as BackgroundWorker;
|
List<string> validPaths = [];
|
||||||
var arguments = e.Argument as Dialogs.ExportPreviewDialog;
|
foreach (var path in paths)
|
||||||
var outputDir = arguments.OutputDir;
|
|
||||||
var width = arguments.PreviewWidth;
|
|
||||||
var height = arguments.PreviewHeight;
|
|
||||||
|
|
||||||
int success = 0;
|
|
||||||
int error = 0;
|
|
||||||
lock (Spines)
|
|
||||||
{
|
{
|
||||||
int totalCount = spines.Count;
|
if (File.Exists(path))
|
||||||
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
|
||||||
for (int i = 0; i < totalCount; i++)
|
|
||||||
{
|
{
|
||||||
if (worker.CancellationPending)
|
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
|
||||||
|
validPaths.Add(path);
|
||||||
|
}
|
||||||
|
else if (Directory.Exists(path))
|
||||||
|
{
|
||||||
|
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
e.Cancel = true;
|
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||||
break;
|
validPaths.Add(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
var spine = spines[i];
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var preview = spine.GetPreview(width, height);
|
|
||||||
var savePath = Path.Combine(outputDir, $"{spine.Name}.png");
|
|
||||||
preview.SaveToFile(savePath);
|
|
||||||
success++;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Program.Logger.Error(ex.ToString());
|
|
||||||
Program.Logger.Error("Failed to save preview {}", spine.SkelPath);
|
|
||||||
error++;
|
|
||||||
}
|
|
||||||
|
|
||||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error > 0)
|
if (validPaths.Count > 1)
|
||||||
{
|
{
|
||||||
Program.Logger.Warn("Preview save {} successfully, {} failed", success, error);
|
if (validPaths.Count > 100)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show($"共发现 {validPaths.Count} 个可加载骨骼,数量较大,是否一次性全部加载?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
|
progressDialog.DoWork += BatchAdd_Work;
|
||||||
|
progressDialog.RunWorkerAsync(new Dialogs.BatchOpenSpineDialogResult(Spine.Version.Auto, validPaths.ToArray()));
|
||||||
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
else
|
else if (validPaths.Count > 0)
|
||||||
{
|
{
|
||||||
Program.Logger.Info("{} preview saved successfully", success);
|
Insert(new Dialogs.OpenSpineDialogResult(Spine.Version.Auto, validPaths[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.Logger.Info($"Current memory usage: {Program.Process.WorkingSet64 / 1024.0 / 1024.0:F2} MB");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -458,8 +458,13 @@ namespace SpineViewer.Controls
|
|||||||
{
|
{
|
||||||
lock (SpineListView.Spines)
|
lock (SpineListView.Spines)
|
||||||
{
|
{
|
||||||
foreach (var spine in SpineListView.Spines.Reverse())
|
var spines = SpineListView.Spines;
|
||||||
|
for (int i = spines.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
|
if (cancelToken is not null && cancelToken.IsCancellationRequested)
|
||||||
|
break; // 提前中止
|
||||||
|
|
||||||
|
var spine = spines[i];
|
||||||
spine.Update(delta);
|
spine.Update(delta);
|
||||||
RenderWindow.Draw(spine);
|
RenderWindow.Draw(spine);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace SpineViewer.Dialogs
|
|||||||
public BatchOpenSpineDialog()
|
public BatchOpenSpineDialog()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
comboBox_Version.DataSource = VersionHelper.Versions.ToList();
|
comboBox_Version.DataSource = VersionHelper.Names.ToList();
|
||||||
comboBox_Version.DisplayMember = "Value";
|
comboBox_Version.DisplayMember = "Value";
|
||||||
comboBox_Version.ValueMember = "Key";
|
comboBox_Version.ValueMember = "Key";
|
||||||
comboBox_Version.SelectedValue = Spine.Version.Auto;
|
comboBox_Version.SelectedValue = Spine.Version.Auto;
|
||||||
@@ -61,7 +61,7 @@ namespace SpineViewer.Dialogs
|
|||||||
|
|
||||||
if (version != Spine.Version.Auto && !Spine.Spine.ImplementedVersions.Contains(version))
|
if (version != Spine.Version.Auto && !Spine.Spine.ImplementedVersions.Contains(version))
|
||||||
{
|
{
|
||||||
MessageBox.Show($"{version.String()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show($"{version.GetName()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace SpineViewer.Dialogs
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
// XXX: 文件格式转换暂时不支持自动检测版本
|
// XXX: 文件格式转换暂时不支持自动检测版本
|
||||||
var impVersions = VersionHelper.Versions.ToDictionary();
|
var impVersions = VersionHelper.Names.ToDictionary();
|
||||||
impVersions.Remove(Spine.Version.Auto);
|
impVersions.Remove(Spine.Version.Auto);
|
||||||
|
|
||||||
comboBox_SourceVersion.DataSource = impVersions.ToList();
|
comboBox_SourceVersion.DataSource = impVersions.ToList();
|
||||||
@@ -77,13 +77,13 @@ namespace SpineViewer.Dialogs
|
|||||||
|
|
||||||
if (!SkeletonConverter.ImplementedVersions.Contains(sourceVersion))
|
if (!SkeletonConverter.ImplementedVersions.Contains(sourceVersion))
|
||||||
{
|
{
|
||||||
MessageBox.Show($"{sourceVersion.String()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show($"{sourceVersion.GetName()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SkeletonConverter.ImplementedVersions.Contains(targetVersion))
|
if (!SkeletonConverter.ImplementedVersions.Contains(targetVersion))
|
||||||
{
|
{
|
||||||
MessageBox.Show($"{targetVersion.String()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show($"{targetVersion.GetName()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace SpineViewer.Dialogs
|
|||||||
public OpenSpineDialog()
|
public OpenSpineDialog()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
comboBox_Version.DataSource = VersionHelper.Versions.ToList();
|
comboBox_Version.DataSource = VersionHelper.Names.ToList();
|
||||||
comboBox_Version.DisplayMember = "Value";
|
comboBox_Version.DisplayMember = "Value";
|
||||||
comboBox_Version.ValueMember = "Key";
|
comboBox_Version.ValueMember = "Key";
|
||||||
comboBox_Version.SelectedValue = Spine.Version.Auto;
|
comboBox_Version.SelectedValue = Spine.Version.Auto;
|
||||||
@@ -78,7 +78,7 @@ namespace SpineViewer.Dialogs
|
|||||||
|
|
||||||
if (version != Spine.Version.Auto && !Spine.Spine.ImplementedVersions.Contains(version))
|
if (version != Spine.Version.Auto && !Spine.Spine.ImplementedVersions.Contains(version))
|
||||||
{
|
{
|
||||||
MessageBox.Show($"{version.String()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show($"{version.GetName()} 版本尚未实现(咕咕咕~)", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,23 @@ namespace SpineViewer
|
|||||||
|
|
||||||
private void toolStripMenuItem_ExportPreview_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportPreview_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
spineListView.ExportPreviews();
|
lock (spineListView.Spines)
|
||||||
|
{
|
||||||
|
if (spineListView.Spines.Count <= 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请至少打开一个骨骼文件", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var saveDialog = new Dialogs.ExportPreviewDialog();
|
||||||
|
if (saveDialog.ShowDialog() != DialogResult.OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
|
progressDialog.DoWork += ExportPreview_Work;
|
||||||
|
progressDialog.RunWorkerAsync(saveDialog);
|
||||||
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
||||||
@@ -200,6 +216,62 @@ namespace SpineViewer
|
|||||||
spinePreviewer.StartPreview();
|
spinePreviewer.StartPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ExportPreview_Work(object? sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
var worker = sender as BackgroundWorker;
|
||||||
|
var arguments = e.Argument as Dialogs.ExportPreviewDialog;
|
||||||
|
var outputDir = arguments.OutputDir;
|
||||||
|
var width = arguments.PreviewWidth;
|
||||||
|
var height = arguments.PreviewHeight;
|
||||||
|
|
||||||
|
int success = 0;
|
||||||
|
int error = 0;
|
||||||
|
spinePreviewer.StopPreview();
|
||||||
|
lock (spineListView.Spines)
|
||||||
|
{
|
||||||
|
var spines = spineListView.Spines;
|
||||||
|
int totalCount = spines.Count;
|
||||||
|
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
||||||
|
for (int i = 0; i < totalCount; i++)
|
||||||
|
{
|
||||||
|
if (worker.CancellationPending)
|
||||||
|
{
|
||||||
|
e.Cancel = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var spine = spines[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var preview = spine.GetPreview(width, height);
|
||||||
|
var savePath = Path.Combine(outputDir, $"{spine.Name}.png");
|
||||||
|
preview.SaveToFile(savePath);
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Program.Logger.Error(ex.ToString());
|
||||||
|
Program.Logger.Error("Failed to save preview {}", spine.SkelPath);
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinePreviewer.StartPreview();
|
||||||
|
|
||||||
|
if (error > 0)
|
||||||
|
{
|
||||||
|
Program.Logger.Warn("Preview save {} successfully, {} failed", success, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Program.Logger.Info("{} preview saved successfully", success);
|
||||||
|
}
|
||||||
|
|
||||||
|
Program.Logger.Info($"Current memory usage: {Program.Process.WorkingSet64 / 1024.0 / 1024.0:F2} MB");
|
||||||
|
}
|
||||||
|
|
||||||
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
||||||
{
|
{
|
||||||
var worker = sender as BackgroundWorker;
|
var worker = sender as BackgroundWorker;
|
||||||
|
|||||||
@@ -1093,6 +1093,25 @@ namespace SpineViewer.Spine.Implementations.SkeletonConverter
|
|||||||
writer.WriteVarInt(name2idx[(string)name]);
|
writer.WriteVarInt(name2idx[(string)name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override JsonObject ReadJson(string jsonPath)
|
||||||
|
{
|
||||||
|
// replace 3.8.75 to another version to avoid detection in official runtime
|
||||||
|
var root = base.ReadJson(jsonPath);
|
||||||
|
var skeleton = root["skeleton"].AsObject();
|
||||||
|
var version = (string)skeleton["spine"];
|
||||||
|
if (version == "3.8.75") skeleton["spine"] = "3.8.76";
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonObject root, string jsonPath)
|
||||||
|
{
|
||||||
|
// replace 3.8.75 to another version to avoid detection in official runtime
|
||||||
|
var skeleton = root["skeleton"].AsObject();
|
||||||
|
var version = (string)skeleton["spine"];
|
||||||
|
if (version == "3.8.75") skeleton["spine"] = "3.8.76";
|
||||||
|
base.WriteJson(root, jsonPath);
|
||||||
|
}
|
||||||
|
|
||||||
public override JsonObject ToVersion(JsonObject root, Version version)
|
public override JsonObject ToVersion(JsonObject root, Version version)
|
||||||
{
|
{
|
||||||
root = version switch
|
root = version switch
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace SpineViewer.Spine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取 Json 对象
|
/// 读取 Json 对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public JsonObject ReadJson(string jsonPath)
|
public virtual JsonObject ReadJson(string jsonPath)
|
||||||
{
|
{
|
||||||
using var input = File.OpenRead(jsonPath);
|
using var input = File.OpenRead(jsonPath);
|
||||||
if (JsonNode.Parse(input) is JsonObject root)
|
if (JsonNode.Parse(input) is JsonObject root)
|
||||||
@@ -104,7 +104,7 @@ namespace SpineViewer.Spine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 写入 Json 对象
|
/// 写入 Json 对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void WriteJson(JsonObject root, string jsonPath)
|
public virtual void WriteJson(JsonObject root, string jsonPath)
|
||||||
{
|
{
|
||||||
using var output = File.Create(jsonPath);
|
using var output = File.Create(jsonPath);
|
||||||
using var writer = new Utf8JsonWriter(output, jsonWriterOptions);
|
using var writer = new Utf8JsonWriter(output, jsonWriterOptions);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using System.Reflection;
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace SpineViewer.Spine
|
namespace SpineViewer.Spine
|
||||||
{
|
{
|
||||||
@@ -37,6 +38,11 @@ namespace SpineViewer.Spine
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Spine : SFML.Graphics.Drawable, IDisposable
|
public abstract class Spine : SFML.Graphics.Drawable, IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 常规骨骼文件后缀集合
|
||||||
|
/// </summary>
|
||||||
|
public static readonly ImmutableHashSet<string> CommonSkelSuffix = [".skel", ".json"];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 空动画标记
|
/// 空动画标记
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -120,8 +126,9 @@ namespace SpineViewer.Spine
|
|||||||
// try json format
|
// try json format
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (JsonNode.Parse(input) is JsonObject root && root.TryGetPropertyValue("spine", out var node))
|
if (JsonNode.Parse(input) is JsonObject root && root.TryGetPropertyValue("skeleton", out var node) &&
|
||||||
versionString = (string)node;
|
node is JsonObject _skeleton && _skeleton.TryGetPropertyValue("spine", out var _version))
|
||||||
|
versionString = (string)_version;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
@@ -163,6 +170,7 @@ namespace SpineViewer.Spine
|
|||||||
else if (versionString.StartsWith("4.1.")) version = Version.V41;
|
else if (versionString.StartsWith("4.1.")) version = Version.V41;
|
||||||
else if (versionString.StartsWith("4.2.")) version = Version.V42;
|
else if (versionString.StartsWith("4.2.")) version = Version.V42;
|
||||||
else if (versionString.StartsWith("4.3.")) version = Version.V43;
|
else if (versionString.StartsWith("4.3.")) version = Version.V43;
|
||||||
|
else Program.Logger.Error("Unknown verison: {}, {}", versionString, skelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return version;
|
return version;
|
||||||
@@ -209,6 +217,7 @@ namespace SpineViewer.Spine
|
|||||||
|
|
||||||
// 设置 Version
|
// 设置 Version
|
||||||
Version = attr.Version;
|
Version = attr.Version;
|
||||||
|
AssetsDir = Directory.GetParent(skelPath).FullName;
|
||||||
SkelPath = Path.GetFullPath(skelPath);
|
SkelPath = Path.GetFullPath(skelPath);
|
||||||
AtlasPath = Path.GetFullPath(atlasPath);
|
AtlasPath = Path.GetFullPath(atlasPath);
|
||||||
Name = Path.GetFileNameWithoutExtension(skelPath);
|
Name = Path.GetFileNameWithoutExtension(skelPath);
|
||||||
@@ -225,6 +234,12 @@ namespace SpineViewer.Spine
|
|||||||
[Category("基本信息"), DisplayName("运行时版本")]
|
[Category("基本信息"), DisplayName("运行时版本")]
|
||||||
public Version Version { get; }
|
public Version Version { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源所在完整目录
|
||||||
|
/// </summary>
|
||||||
|
[Category("基本信息"), DisplayName("资源目录")]
|
||||||
|
public string AssetsDir { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// skel 文件完整路径
|
/// skel 文件完整路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -237,6 +252,9 @@ namespace SpineViewer.Spine
|
|||||||
[Category("基本信息"), DisplayName("atlas文件路径")]
|
[Category("基本信息"), DisplayName("atlas文件路径")]
|
||||||
public string AtlasPath { get; }
|
public string AtlasPath { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
[Category("基本信息"), DisplayName("名称")]
|
[Category("基本信息"), DisplayName("名称")]
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
@@ -352,7 +370,9 @@ namespace SpineViewer.Spine
|
|||||||
viewX *= scale;
|
viewX *= scale;
|
||||||
viewY *= scale;
|
viewY *= scale;
|
||||||
|
|
||||||
using var tex = new SFML.Graphics.RenderTexture(width, height);
|
// XXX: 貌似无法使用 using 或者 Dispose 主动释放 tex 资源
|
||||||
|
// 在批量添加的中途, 如果触发 GC? 会卡死, 目前未知原因
|
||||||
|
var tex = new SFML.Graphics.RenderTexture(width, height);
|
||||||
var view = tex.GetView();
|
var view = tex.GetView();
|
||||||
view.Center = new(bounds.X + viewX / 2, bounds.Y + viewY / 2);
|
view.Center = new(bounds.X + viewX / 2, bounds.Y + viewY / 2);
|
||||||
view.Size = new(viewX, -viewY);
|
view.Size = new(viewX, -viewY);
|
||||||
@@ -395,5 +415,23 @@ namespace SpineViewer.Spine
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public bool IsSelected { get; set; } = false;
|
public bool IsSelected { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示调试
|
||||||
|
/// </summary>
|
||||||
|
[Browsable(false)]
|
||||||
|
public bool IsDebug { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示包围盒
|
||||||
|
/// </summary>
|
||||||
|
[Browsable(false)]
|
||||||
|
public bool DebugBounds { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示骨骼
|
||||||
|
/// </summary>
|
||||||
|
[Browsable(false)]
|
||||||
|
public bool DebugBones { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace SpineViewer.Spine
|
|||||||
if (destinationType == typeof(string) && value is Version version)
|
if (destinationType == typeof(string) && value is Version version)
|
||||||
{
|
{
|
||||||
// 调用自定义的 String() 方法
|
// 调用自定义的 String() 方法
|
||||||
return version.String();
|
return version.GetName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
|
|||||||
@@ -12,10 +12,15 @@ namespace SpineViewer.Spine
|
|||||||
public static class VersionHelper
|
public static class VersionHelper
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 描述缓存
|
/// 版本名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly ReadOnlyDictionary<Version, string> Versions;
|
public static readonly ReadOnlyDictionary<Version, string> Names;
|
||||||
private static readonly Dictionary<Version, string> versions = [];
|
private static readonly Dictionary<Version, string> names = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runtime 版本字符串
|
||||||
|
/// </summary>
|
||||||
|
private static readonly Dictionary<Version, string> runtimes = [];
|
||||||
|
|
||||||
static VersionHelper()
|
static VersionHelper()
|
||||||
{
|
{
|
||||||
@@ -24,17 +29,33 @@ namespace SpineViewer.Spine
|
|||||||
{
|
{
|
||||||
var field = typeof(Version).GetField(value.ToString());
|
var field = typeof(Version).GetField(value.ToString());
|
||||||
var attribute = field?.GetCustomAttribute<DescriptionAttribute>();
|
var attribute = field?.GetCustomAttribute<DescriptionAttribute>();
|
||||||
versions[(Version)value] = attribute?.Description ?? value.ToString();
|
names[(Version)value] = attribute?.Description ?? value.ToString();
|
||||||
}
|
}
|
||||||
Versions = versions.AsReadOnly();
|
Names = names.AsReadOnly();
|
||||||
|
|
||||||
|
runtimes[Version.V21] = Assembly.GetAssembly(typeof(SpineRuntime21.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
runtimes[Version.V36] = Assembly.GetAssembly(typeof(SpineRuntime36.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
runtimes[Version.V37] = Assembly.GetAssembly(typeof(SpineRuntime37.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
runtimes[Version.V38] = Assembly.GetAssembly(typeof(SpineRuntime38.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
runtimes[Version.V40] = Assembly.GetAssembly(typeof(SpineRuntime40.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
runtimes[Version.V41] = Assembly.GetAssembly(typeof(SpineRuntime41.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
runtimes[Version.V42] = Assembly.GetAssembly(typeof(SpineRuntime42.Skeleton)).GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 版本号字符串
|
/// 版本字符串名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string String(this Version version)
|
public static string GetName(this Version version)
|
||||||
{
|
{
|
||||||
return Versions.TryGetValue(version, out var description) ? description : version.ToString();
|
return Names.TryGetValue(version, out var val) ? val : version.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runtime 版本字符串名称
|
||||||
|
/// </summary>
|
||||||
|
public static string GetRuntime(this Version version)
|
||||||
|
{
|
||||||
|
return runtimes.TryGetValue(version, out var val) ? val : GetName(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||||
<Version>0.10.4</Version>
|
<Version>0.10.6</Version>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
||||||
|
|||||||
Reference in New Issue
Block a user