增加画面开始暂停

This commit is contained in:
ww-rm
2025-03-24 21:01:07 +08:00
parent 50e6e414ee
commit afa6ce2113
4 changed files with 223 additions and 110 deletions

View File

@@ -29,12 +29,21 @@
private void InitializeComponent() private void InitializeComponent()
{ {
panel = new Panel(); panel = new Panel();
tableLayoutPanel1 = new TableLayoutPanel();
panel_Container = new Panel();
flowLayoutPanel1 = new FlowLayoutPanel();
button_Stop = new Button();
button_Start = new Button();
button_Pause = new Button();
tableLayoutPanel1.SuspendLayout();
panel_Container.SuspendLayout();
flowLayoutPanel1.SuspendLayout();
SuspendLayout(); SuspendLayout();
// //
// panel // panel
// //
panel.BackColor = SystemColors.ControlDarkDark; panel.BackColor = SystemColors.ControlDarkDark;
panel.Location = new Point(160, 160); panel.Location = new Point(143, 124);
panel.Margin = new Padding(0); panel.Margin = new Padding(0);
panel.Name = "panel"; panel.Name = "panel";
panel.Size = new Size(320, 320); panel.Size = new Size(320, 320);
@@ -44,20 +53,100 @@
panel.MouseUp += panel_MouseUp; panel.MouseUp += panel_MouseUp;
panel.MouseWheel += panel_MouseWheel; panel.MouseWheel += panel_MouseWheel;
// //
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(panel_Container, 0, 0);
tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 1);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Margin = new Padding(0);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 2;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(641, 636);
tableLayoutPanel1.TabIndex = 2;
//
// panel_Container
//
panel_Container.BackColor = SystemColors.ControlDark;
panel_Container.Controls.Add(panel);
panel_Container.Dock = DockStyle.Fill;
panel_Container.Location = new Point(0, 0);
panel_Container.Margin = new Padding(0);
panel_Container.Name = "panel_Container";
panel_Container.Size = new Size(641, 596);
panel_Container.TabIndex = 0;
//
// flowLayoutPanel1
//
flowLayoutPanel1.Anchor = AnchorStyles.None;
flowLayoutPanel1.AutoSize = true;
flowLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
flowLayoutPanel1.Controls.Add(button_Stop);
flowLayoutPanel1.Controls.Add(button_Start);
flowLayoutPanel1.Controls.Add(button_Pause);
flowLayoutPanel1.Location = new Point(143, 596);
flowLayoutPanel1.Margin = new Padding(0);
flowLayoutPanel1.Name = "flowLayoutPanel1";
flowLayoutPanel1.Size = new Size(354, 40);
flowLayoutPanel1.TabIndex = 1;
//
// button_Stop
//
button_Stop.Location = new Point(3, 3);
button_Stop.Name = "button_Stop";
button_Stop.Size = new Size(112, 34);
button_Stop.TabIndex = 0;
button_Stop.Text = "停止";
button_Stop.UseVisualStyleBackColor = true;
button_Stop.Click += button_Stop_Click;
//
// button_Start
//
button_Start.Location = new Point(121, 3);
button_Start.Name = "button_Start";
button_Start.Size = new Size(112, 34);
button_Start.TabIndex = 1;
button_Start.Text = "开始";
button_Start.UseVisualStyleBackColor = true;
button_Start.Click += button_Start_Click;
//
// button_Pause
//
button_Pause.Location = new Point(239, 3);
button_Pause.Name = "button_Pause";
button_Pause.Size = new Size(112, 34);
button_Pause.TabIndex = 2;
button_Pause.Text = "暂停";
button_Pause.UseVisualStyleBackColor = true;
button_Pause.Click += button_Pause_Click;
//
// SpinePreviewer // SpinePreviewer
// //
AutoScaleDimensions = new SizeF(11F, 24F); AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
BackColor = SystemColors.ControlDark; Controls.Add(tableLayoutPanel1);
Controls.Add(panel);
Name = "SpinePreviewer"; Name = "SpinePreviewer";
Size = new Size(640, 640); Size = new Size(641, 636);
SizeChanged += SpinePreviewer_SizeChanged; SizeChanged += SpinePreviewer_SizeChanged;
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
panel_Container.ResumeLayout(false);
flowLayoutPanel1.ResumeLayout(false);
ResumeLayout(false); ResumeLayout(false);
} }
#endregion #endregion
private Panel panel; private Panel panel;
private TableLayoutPanel tableLayoutPanel1;
private Panel panel_Container;
private FlowLayoutPanel flowLayoutPanel1;
private Button button_Stop;
private Button button_Start;
private Button button_Pause;
} }
} }

View File

@@ -15,6 +15,45 @@ namespace SpineViewer.Controls
{ {
public partial class SpinePreviewer : UserControl public partial class SpinePreviewer : UserControl
{ {
/// <summary>
/// 画面拖放对象世界坐标源点
/// </summary>
private SFML.System.Vector2f? draggingSrc = null;
/// <summary>
/// 要绑定的 Spine 列表控件
/// </summary>
[Category("自定义"), Description("相关联的 SpineListView")]
public SpineListView? SpineListView { get; set; }
/// <summary>
/// 属性信息面板
/// </summary>
[Category("自定义"), Description("用于显示画面属性的属性页")]
public PropertyGrid? PropertyGrid
{
get => propertyGrid;
set
{
propertyGrid = value;
if (propertyGrid is not null)
propertyGrid.SelectedObject = new PreviewerProperty(this);
}
}
private PropertyGrid? propertyGrid;
#region
/// <summary>
/// 画面缩放最大值
/// </summary>
public const float ZOOM_MAX = 1000f;
/// <summary>
/// 画面缩放最小值
/// </summary>
public const float ZOOM_MIN = 0.001f;
/// <summary> /// <summary>
/// 包装类, 用于属性面板显示 /// 包装类, 用于属性面板显示
/// </summary> /// </summary>
@@ -50,74 +89,6 @@ namespace SpineViewer.Controls
public uint MaxFps { get => previewer.MaxFps; set => previewer.MaxFps = value; } public uint MaxFps { get => previewer.MaxFps; set => previewer.MaxFps = value; }
} }
/// <summary>
/// 要绑定的 Spine 列表控件
/// </summary>
[Category("自定义"), Description("相关联的 SpineListView")]
public SpineListView? SpineListView { get; set; }
/// <summary>
/// 属性信息面板
/// </summary>
[Category("自定义"), Description("用于显示画面属性的属性页")]
public PropertyGrid? PropertyGrid
{
get => propertyGrid;
set
{
propertyGrid = value;
if (propertyGrid is not null)
propertyGrid.SelectedObject = new PreviewerProperty(this);
}
}
private PropertyGrid? propertyGrid;
/// <summary>
/// 画面缩放最大值
/// </summary>
public const float ZOOM_MAX = 1000f;
/// <summary>
/// 画面缩放最小值
/// </summary>
public const float ZOOM_MIN = 0.001f;
/// <summary>
/// 预览画面背景色
/// </summary>
private static readonly SFML.Graphics.Color BackgroundColor = new(105, 105, 105);
/// <summary>
/// 预览画面坐标轴颜色
/// </summary>
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
/// <summary>
/// 坐标轴顶点缓冲区
/// </summary>
private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2);
/// <summary>
/// 渲染窗口
/// </summary>
private readonly SFML.Graphics.RenderWindow RenderWindow;
/// <summary>
/// 帧间隔计时器
/// </summary>
private readonly SFML.System.Clock Clock = new();
/// <summary>
/// 画面拖放对象世界坐标源点
/// </summary>
private SFML.System.Vector2f? draggingSrc = null;
/// <summary>
/// 渲染任务
/// </summary>
private Task? task = null;
private CancellationTokenSource? cancelToken = null;
/// <summary> /// <summary>
/// 分辨率 /// 分辨率
/// </summary> /// </summary>
@@ -280,6 +251,8 @@ namespace SpineViewer.Controls
public uint MaxFps { get => maxFps; set { RenderWindow.SetFramerateLimit(value); maxFps = value; } } public uint MaxFps { get => maxFps; set { RenderWindow.SetFramerateLimit(value); maxFps = value; } }
private uint maxFps = 60; private uint maxFps = 60;
#endregion
public SpinePreviewer() public SpinePreviewer()
{ {
InitializeComponent(); InitializeComponent();
@@ -294,14 +267,27 @@ namespace SpineViewer.Controls
} }
/// <summary> /// <summary>
/// 预览画面帧参数 /// 预览画面帧参数, TODO: 转移到统一导出参数
/// </summary> /// </summary>
public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView(), RenderSelectedOnly); public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView(), RenderSelectedOnly);
#region 线
/// <summary> /// <summary>
/// 开始预览 /// 渲染窗口
/// </summary> /// </summary>
public void StartPreview() private readonly SFML.Graphics.RenderWindow RenderWindow;
/// <summary>
/// 渲染任务
/// </summary>
private Task? task = null;
private CancellationTokenSource? cancelToken = null;
/// <summary>
/// 开始渲染
/// </summary>
public void StartRender()
{ {
if (task is not null) if (task is not null)
return; return;
@@ -310,9 +296,9 @@ namespace SpineViewer.Controls
} }
/// <summary> /// <summary>
/// 停止预览 /// 停止渲染
/// </summary> /// </summary>
public void StopPreview() public void StopRender()
{ {
if (task is null || cancelToken is null) if (task is null || cancelToken is null)
return; return;
@@ -322,6 +308,56 @@ namespace SpineViewer.Controls
task = null; task = null;
} }
#endregion
/// <summary>
/// 是否还在更新画面
/// </summary>
public bool IsUpdating { get; private set; } = true;
/// <summary>
/// 开始更新
/// </summary>
public void StartUpdate() => IsUpdating = true;
/// <summary>
/// 暂停更新
/// </summary>
public void PauseUpdate() => IsUpdating = false;
/// <summary>
/// 停止更新, 将所有模型动画时间重置到 0 时刻
/// </summary>
public void StopUpdate()
{
IsUpdating = false;
lock (SpineListView.Spines)
{
foreach (var spine in SpineListView.Spines)
spine.CurrentAnimation = spine.CurrentAnimation;
}
}
/// <summary>
/// 预览画面背景色
/// </summary>
private static readonly SFML.Graphics.Color BackgroundColor = new(105, 105, 105);
/// <summary>
/// 预览画面坐标轴颜色
/// </summary>
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
/// <summary>
/// 坐标轴顶点缓冲区
/// </summary>
private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2);
/// <summary>
/// 帧间隔计时器
/// </summary>
private readonly SFML.System.Clock Clock = new();
/// <summary> /// <summary>
/// 渲染任务 /// 渲染任务
/// </summary> /// </summary>
@@ -362,7 +398,8 @@ namespace SpineViewer.Controls
break; // 提前中止 break; // 提前中止
var spine = spines[i]; var spine = spines[i];
spine.Update(delta);
spine.Update(IsUpdating ? delta : 0);
if (RenderSelectedOnly && !spine.IsSelected) if (RenderSelectedOnly && !spine.IsSelected)
continue; continue;
@@ -388,8 +425,8 @@ namespace SpineViewer.Controls
if (RenderWindow is null) if (RenderWindow is null)
return; return;
float parentX = Width; float parentX = panel.Parent.Width;
float parentY = Height; float parentY = panel.Parent.Height;
float sizeX = panel.Width; float sizeX = panel.Width;
float sizeY = panel.Height; float sizeY = panel.Height;
@@ -538,6 +575,21 @@ namespace SpineViewer.Controls
Zoom *= (e.Delta > 0 ? 1.1f : 0.9f); Zoom *= (e.Delta > 0 ? 1.1f : 0.9f);
PropertyGrid?.Refresh(); PropertyGrid?.Refresh();
} }
private void button_Stop_Click(object sender, EventArgs e)
{
StopUpdate();
}
private void button_Start_Click(object sender, EventArgs e)
{
StartUpdate();
}
private void button_Pause_Click(object sender, EventArgs e)
{
PauseUpdate();
}
} }
/// <summary> /// <summary>

View File

@@ -39,8 +39,6 @@
toolStripMenuItem_ExportPreview = new ToolStripMenuItem(); toolStripMenuItem_ExportPreview = new ToolStripMenuItem();
toolStripSeparator2 = new ToolStripSeparator(); toolStripSeparator2 = new ToolStripSeparator();
toolStripMenuItem_Exit = new ToolStripMenuItem(); toolStripMenuItem_Exit = new ToolStripMenuItem();
toolStripMenuItem_Function = new ToolStripMenuItem();
toolStripMenuItem_ResetAnimation = new ToolStripMenuItem();
toolStripMenuItem_Tool = new ToolStripMenuItem(); toolStripMenuItem_Tool = new ToolStripMenuItem();
toolStripMenuItem_ConvertFileFormat = new ToolStripMenuItem(); toolStripMenuItem_ConvertFileFormat = new ToolStripMenuItem();
toolStripMenuItem_Download = new ToolStripMenuItem(); toolStripMenuItem_Download = new ToolStripMenuItem();
@@ -92,7 +90,7 @@
// //
menuStrip.BackColor = SystemColors.Control; menuStrip.BackColor = SystemColors.Control;
menuStrip.ImageScalingSize = new Size(24, 24); menuStrip.ImageScalingSize = new Size(24, 24);
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Function, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help }); menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help });
menuStrip.Location = new Point(0, 0); menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip"; menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1748, 32); menuStrip.Size = new Size(1748, 32);
@@ -154,20 +152,6 @@
toolStripMenuItem_Exit.Text = "退出(&X)"; toolStripMenuItem_Exit.Text = "退出(&X)";
toolStripMenuItem_Exit.Click += toolStripMenuItem_Exit_Click; toolStripMenuItem_Exit.Click += toolStripMenuItem_Exit_Click;
// //
// toolStripMenuItem_Function
//
toolStripMenuItem_Function.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ResetAnimation });
toolStripMenuItem_Function.Name = "toolStripMenuItem_Function";
toolStripMenuItem_Function.Size = new Size(87, 28);
toolStripMenuItem_Function.Text = "功能(&G)";
//
// toolStripMenuItem_ResetAnimation
//
toolStripMenuItem_ResetAnimation.Name = "toolStripMenuItem_ResetAnimation";
toolStripMenuItem_ResetAnimation.Size = new Size(242, 34);
toolStripMenuItem_ResetAnimation.Text = "重置动画时间(&R)";
toolStripMenuItem_ResetAnimation.Click += toolStripMenuItem_ResetAnimation_Click;
//
// toolStripMenuItem_Tool // toolStripMenuItem_Tool
// //
toolStripMenuItem_Tool.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ConvertFileFormat }); toolStripMenuItem_Tool.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ConvertFileFormat });
@@ -178,7 +162,7 @@
// toolStripMenuItem_ConvertFileFormat // toolStripMenuItem_ConvertFileFormat
// //
toolStripMenuItem_ConvertFileFormat.Name = "toolStripMenuItem_ConvertFileFormat"; toolStripMenuItem_ConvertFileFormat.Name = "toolStripMenuItem_ConvertFileFormat";
toolStripMenuItem_ConvertFileFormat.Size = new Size(254, 34); toolStripMenuItem_ConvertFileFormat.Size = new Size(270, 34);
toolStripMenuItem_ConvertFileFormat.Text = "转换文件格式(&C)..."; toolStripMenuItem_ConvertFileFormat.Text = "转换文件格式(&C)...";
toolStripMenuItem_ConvertFileFormat.Click += toolStripMenuItem_ConvertFileFormat_Click; toolStripMenuItem_ConvertFileFormat.Click += toolStripMenuItem_ConvertFileFormat_Click;
// //
@@ -408,7 +392,6 @@
// //
// spinePreviewer // spinePreviewer
// //
spinePreviewer.BackColor = SystemColors.ControlDark;
spinePreviewer.Dock = DockStyle.Fill; spinePreviewer.Dock = DockStyle.Fill;
spinePreviewer.Location = new Point(3, 26); spinePreviewer.Location = new Point(3, 26);
spinePreviewer.Name = "spinePreviewer"; spinePreviewer.Name = "spinePreviewer";
@@ -501,8 +484,6 @@
private Controls.SpineListView spineListView; private Controls.SpineListView spineListView;
private PropertyGrid propertyGrid_Previewer; private PropertyGrid propertyGrid_Previewer;
private Controls.SpinePreviewer spinePreviewer; private Controls.SpinePreviewer spinePreviewer;
private ToolStripMenuItem toolStripMenuItem_Function;
private ToolStripMenuItem toolStripMenuItem_ResetAnimation;
private ToolStripMenuItem toolStripMenuItem_Diagnostics; private ToolStripMenuItem toolStripMenuItem_Diagnostics;
private ToolStripSeparator toolStripSeparator3; private ToolStripSeparator toolStripSeparator3;
private ToolStripMenuItem toolStripMenuItem_Download; private ToolStripMenuItem toolStripMenuItem_Download;

View File

@@ -115,15 +115,6 @@ namespace SpineViewer
Close(); Close();
} }
private void toolStripMenuItem_ResetAnimation_Click(object sender, EventArgs e)
{
lock (spineListView.Spines)
{
foreach (var spine in spineListView.Spines)
spine.CurrentAnimation = spine.CurrentAnimation;
}
}
private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e) private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e)
{ {
var openDialog = new Dialogs.ConvertFileFormatDialog(); var openDialog = new Dialogs.ConvertFileFormatDialog();