增加仅渲染选中模式

This commit is contained in:
ww-rm
2025-03-24 00:01:28 +08:00
parent 8dda8c8ff3
commit 7bf30eb54a

View File

@@ -40,6 +40,9 @@ namespace SpineViewer.Controls
[Category("导出"), DisplayName("垂直翻转")] [Category("导出"), DisplayName("垂直翻转")]
public bool FlipY { get => previewer.FlipY; set => previewer.FlipY = value; } public bool FlipY { get => previewer.FlipY; set => previewer.FlipY = value; }
[Category("导出"), DisplayName("仅渲染选中")]
public bool RenderSelectedOnly { get => previewer.RenderSelectedOnly; set => previewer.RenderSelectedOnly = value; }
[Category("预览"), DisplayName("显示坐标轴")] [Category("预览"), DisplayName("显示坐标轴")]
public bool ShowAxis { get => previewer.ShowAxis; set => previewer.ShowAxis = value; } public bool ShowAxis { get => previewer.ShowAxis; set => previewer.ShowAxis = value; }
@@ -89,21 +92,11 @@ namespace SpineViewer.Controls
/// </summary> /// </summary>
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220); private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
/// <summary>
/// TODO: 转移到 Spine 对象
/// </summary>
private static readonly SFML.Graphics.Color BoundsColor = new(120, 200, 0);
/// <summary> /// <summary>
/// 坐标轴顶点缓冲区 /// 坐标轴顶点缓冲区
/// </summary> /// </summary>
private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2); private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2);
/// <summary>
/// TODO: 转移到 Spine 对象
/// </summary>
private readonly SFML.Graphics.VertexArray BoundsRect = new(SFML.Graphics.PrimitiveType.LineStrip, 5);
/// <summary> /// <summary>
/// 渲染窗口 /// 渲染窗口
/// </summary> /// </summary>
@@ -265,6 +258,13 @@ namespace SpineViewer.Controls
} }
} }
/// <summary>
/// 仅渲染选中
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public bool RenderSelectedOnly { get; set; } = false;
/// <summary> /// <summary>
/// 显示坐标轴 /// 显示坐标轴
/// </summary> /// </summary>
@@ -296,7 +296,7 @@ namespace SpineViewer.Controls
/// <summary> /// <summary>
/// 预览画面帧参数 /// 预览画面帧参数
/// </summary> /// </summary>
public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView()); public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView(), RenderSelectedOnly);
/// <summary> /// <summary>
/// 开始预览 /// 开始预览
@@ -364,20 +364,12 @@ namespace SpineViewer.Controls
var spine = spines[i]; var spine = spines[i];
spine.Update(delta); spine.Update(delta);
if (RenderSelectedOnly && !spine.IsSelected)
continue;
spine.IsDebug = true; spine.IsDebug = true;
RenderWindow.Draw(spine); RenderWindow.Draw(spine);
spine.IsDebug = false; 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,20 +425,37 @@ namespace SpineViewer.Controls
draggingSrc = RenderWindow.MapPixelToCoords(new(e.X, e.Y)); draggingSrc = RenderWindow.MapPixelToCoords(new(e.X, e.Y));
var src = new PointF(((SFML.System.Vector2f)draggingSrc).X, ((SFML.System.Vector2f)draggingSrc).Y); var src = new PointF(((SFML.System.Vector2f)draggingSrc).X, ((SFML.System.Vector2f)draggingSrc).Y);
if (SpineListView is not null) if (SpineListView is null)
{ return;
lock (SpineListView.Spines) lock (SpineListView.Spines)
{ {
var spines = 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 键就只选中点击的那个, 所以先清空选中列表 // 没有按下 Ctrl 键就只选中点击的那个, 所以先清空选中列表
if ((ModifierKeys & Keys.Control) == 0) if ((ModifierKeys & Keys.Control) == 0)
{ {
bool hit = false; bool hit = false;
for (int i = 0; i < spines.Count; i++) for (int i = 0; i < spines.Count; i++)
{ {
if (spines[i].Bounds.Contains(src)) if (!spines[i].Bounds.Contains(src)) continue;
{
hit = true; hit = true;
// 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的 // 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的
@@ -457,18 +466,17 @@ namespace SpineViewer.Controls
} }
break; break;
} }
}
// 如果点了空白的地方, 就清空选中列表 // 如果点了空白的地方, 就清空选中列表
if (!hit) if (!hit) SpineListView.SelectedIndices.Clear();
SpineListView.SelectedIndices.Clear();
} }
else else
{ {
for (int i = 0; i < spines.Count; i++) for (int i = 0; i < spines.Count; i++)
{ {
if (spines[i].Bounds.Contains(src)) if (!spines[i].Bounds.Contains(src))
{ continue;
SpineListView.SelectedIndices.Add(i); SpineListView.SelectedIndices.Add(i);
break; break;
} }
@@ -477,7 +485,6 @@ namespace SpineViewer.Controls
} }
} }
} }
}
private void panel_MouseMove(object sender, MouseEventArgs e) private void panel_MouseMove(object sender, MouseEventArgs e)
{ {
@@ -536,7 +543,7 @@ namespace SpineViewer.Controls
/// <summary> /// <summary>
/// 预览画面帧参数 /// 预览画面帧参数
/// </summary> /// </summary>
public class SpinePreviewerFrameArgs(Size resolution, SFML.Graphics.View view) public class SpinePreviewerFrameArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly)
{ {
/// <summary> /// <summary>
/// 分辨率 /// 分辨率
@@ -547,6 +554,11 @@ namespace SpineViewer.Controls
/// 渲染视窗 /// 渲染视窗
/// </summary> /// </summary>
public SFML.Graphics.View View => view; public SFML.Graphics.View View => view;
/// <summary>
/// 是否仅渲染/导出选中骨骼
/// </summary>
public bool RenderSelectedOnly => renderSelectedOnly;
} }
} }