From 7bf30eb54ad431d87e3f622800839c243186302b Mon Sep 17 00:00:00 2001 From: ww-rm Date: Mon, 24 Mar 2025 00:01:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=85=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SpineViewer/Controls/SpinePreviewer.cs | 102 ++++++++++++++----------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/SpineViewer/Controls/SpinePreviewer.cs b/SpineViewer/Controls/SpinePreviewer.cs index bb5642e..2791bc9 100644 --- a/SpineViewer/Controls/SpinePreviewer.cs +++ b/SpineViewer/Controls/SpinePreviewer.cs @@ -40,6 +40,9 @@ namespace SpineViewer.Controls [Category("导出"), DisplayName("垂直翻转")] public bool FlipY { get => previewer.FlipY; set => previewer.FlipY = value; } + [Category("导出"), DisplayName("仅渲染选中")] + public bool RenderSelectedOnly { get => previewer.RenderSelectedOnly; set => previewer.RenderSelectedOnly = value; } + [Category("预览"), DisplayName("显示坐标轴")] public bool ShowAxis { get => previewer.ShowAxis; set => previewer.ShowAxis = value; } @@ -89,21 +92,11 @@ namespace SpineViewer.Controls /// private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220); - /// - /// TODO: 转移到 Spine 对象 - /// - private static readonly SFML.Graphics.Color BoundsColor = new(120, 200, 0); - /// /// 坐标轴顶点缓冲区 /// private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2); - /// - /// TODO: 转移到 Spine 对象 - /// - private readonly SFML.Graphics.VertexArray BoundsRect = new(SFML.Graphics.PrimitiveType.LineStrip, 5); - /// /// 渲染窗口 /// @@ -265,6 +258,13 @@ namespace SpineViewer.Controls } } + /// + /// 仅渲染选中 + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Browsable(false)] + public bool RenderSelectedOnly { get; set; } = false; + /// /// 显示坐标轴 /// @@ -296,7 +296,7 @@ namespace SpineViewer.Controls /// /// 预览画面帧参数 /// - public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView()); + public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView(), RenderSelectedOnly); /// /// 开始预览 @@ -364,20 +364,12 @@ namespace SpineViewer.Controls var spine = spines[i]; spine.Update(delta); + if (RenderSelectedOnly && !spine.IsSelected) + continue; + spine.IsDebug = true; RenderWindow.Draw(spine); spine.IsDebug = false; - - // TODO: 增加渲染模式(仅选中), 包围盒转移到 Spine 类 - if (spine.IsSelected) - { - var bounds = spine.Bounds; - BoundsRect[0] = BoundsRect[4] = new(new(bounds.Left, bounds.Top), BoundsColor); - BoundsRect[1] = new(new(bounds.Right, bounds.Top), BoundsColor); - BoundsRect[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor); - BoundsRect[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor); - RenderWindow.Draw(BoundsRect); - } } } } @@ -433,45 +425,60 @@ namespace SpineViewer.Controls draggingSrc = RenderWindow.MapPixelToCoords(new(e.X, e.Y)); var src = new PointF(((SFML.System.Vector2f)draggingSrc).X, ((SFML.System.Vector2f)draggingSrc).Y); - if (SpineListView is not null) - { - lock (SpineListView.Spines) - { - var spines = SpineListView.Spines; + if (SpineListView is null) + return; + lock (SpineListView.Spines) + { + var spines = SpineListView.Spines; + + // 仅渲染选中模式禁止在画面里选择对象 + if (RenderSelectedOnly) + { + bool hit = false; + foreach (int i in SpineListView.SelectedIndices) + { + if (!spines[i].Bounds.Contains(src)) continue; + hit = true; + break; + } + + // 如果没点到被选中的模型, 则不允许拖动 + if (!hit) draggingSrc = null; + } + else + { // 没有按下 Ctrl 键就只选中点击的那个, 所以先清空选中列表 if ((ModifierKeys & Keys.Control) == 0) { bool hit = false; for (int i = 0; i < spines.Count; i++) { - if (spines[i].Bounds.Contains(src)) - { - hit = true; + if (!spines[i].Bounds.Contains(src)) continue; - // 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的 - if (!SpineListView.SelectedIndices.Contains(i)) - { - SpineListView.SelectedIndices.Clear(); - SpineListView.SelectedIndices.Add(i); - } - break; + hit = true; + + // 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的 + if (!SpineListView.SelectedIndices.Contains(i)) + { + SpineListView.SelectedIndices.Clear(); + SpineListView.SelectedIndices.Add(i); } + break; } // 如果点了空白的地方, 就清空选中列表 - if (!hit) - SpineListView.SelectedIndices.Clear(); + if (!hit) SpineListView.SelectedIndices.Clear(); } else { for (int i = 0; i < spines.Count; i++) { - if (spines[i].Bounds.Contains(src)) - { - SpineListView.SelectedIndices.Add(i); - break; - } + if (!spines[i].Bounds.Contains(src)) + continue; + + SpineListView.SelectedIndices.Add(i); + break; } } } @@ -536,7 +543,7 @@ namespace SpineViewer.Controls /// /// 预览画面帧参数 /// - public class SpinePreviewerFrameArgs(Size resolution, SFML.Graphics.View view) + public class SpinePreviewerFrameArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly) { /// /// 分辨率 @@ -547,6 +554,11 @@ namespace SpineViewer.Controls /// 渲染视窗 /// public SFML.Graphics.View View => view; + + /// + /// 是否仅渲染/导出选中骨骼 + /// + public bool RenderSelectedOnly => renderSelectedOnly; } }