Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afc011adbb | ||
|
|
da42c14d35 | ||
|
|
a7438e2026 | ||
|
|
47e5314bb3 | ||
|
|
1978c1da11 | ||
|
|
914c9d0ea3 | ||
|
|
7134aebb7f | ||
|
|
abb32e9ed2 | ||
|
|
2c77e385c5 | ||
|
|
ba0f5ac124 | ||
|
|
c4f17e3f06 | ||
|
|
b802ec252a | ||
|
|
68779caab0 | ||
|
|
5d819114d0 | ||
|
|
46b3937236 | ||
|
|
6803b8cf4a | ||
|
|
bd9c5a176b | ||
|
|
76c1d96c87 | ||
|
|
304af805cb | ||
|
|
027d3af619 | ||
|
|
c612c01ac7 | ||
|
|
cd7855a877 | ||
|
|
cdd81e0bfb |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,5 +1,18 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.12.6
|
||||
|
||||
- 增加全屏预览
|
||||
- 增加桌面投影 (实验性功能)
|
||||
- 增加预览画面背景色设置
|
||||
- 增加分辨率和颜色预设列表
|
||||
- 皮肤面板显示 default
|
||||
|
||||
## v0.12.5
|
||||
|
||||
- 增加插槽属性面板
|
||||
- 修改皮肤属性面板设置方式为True/False
|
||||
|
||||
## v0.12.4
|
||||
|
||||
- 增加导出自动分辨率参数
|
||||
|
||||
@@ -10,12 +10,6 @@
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
:sparkles: `v0.12.5` 新特性: 支持自定义槽位附件 :sparkles:
|
||||
|
||||
---
|
||||
|
||||
## 安装
|
||||
|
||||
前往 [Release](https://github.com/ww-rm/SpineViewer/releases) 界面下载压缩包.
|
||||
|
||||
@@ -152,27 +152,13 @@ namespace SpineRuntime36 {
|
||||
|
||||
Bone parent = this.parent;
|
||||
if (parent == null) { // Root bone.
|
||||
float rotationY = rotation + 90 + shearY;
|
||||
float la = MathUtils.CosDeg(rotation + shearX) * scaleX;
|
||||
float lb = MathUtils.CosDeg(rotationY) * scaleY;
|
||||
float lc = MathUtils.SinDeg(rotation + shearX) * scaleX;
|
||||
float ld = MathUtils.SinDeg(rotationY) * scaleY;
|
||||
if (skeleton.flipX) {
|
||||
x = -x;
|
||||
la = -la;
|
||||
lb = -lb;
|
||||
}
|
||||
if (skeleton.flipY != yDown) {
|
||||
y = -y;
|
||||
lc = -lc;
|
||||
ld = -ld;
|
||||
}
|
||||
a = la;
|
||||
b = lb;
|
||||
c = lc;
|
||||
d = ld;
|
||||
worldX = x + skeleton.x;
|
||||
worldY = y + skeleton.y;
|
||||
float rotationY = rotation + 90 + shearY, sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
a = MathUtils.CosDeg(rotation + shearX) * scaleX * sx;
|
||||
b = MathUtils.CosDeg(rotationY) * scaleY * sx;
|
||||
c = MathUtils.SinDeg(rotation + shearX) * scaleX * sy;
|
||||
d = MathUtils.SinDeg(rotationY) * scaleY * sy;
|
||||
worldX = x * sx + skeleton.x;
|
||||
worldY = y * sy + skeleton.y;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,13 +214,16 @@ namespace SpineRuntime36 {
|
||||
case TransformMode.NoScale:
|
||||
case TransformMode.NoScaleOrReflection: {
|
||||
float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation);
|
||||
float za = pa * cos + pb * sin;
|
||||
float zc = pc * cos + pd * sin;
|
||||
float za = (pa * cos + pb * sin) / skeleton.scaleX;
|
||||
float zc = (pc * cos + pd * sin) / skeleton.scaleY;
|
||||
float s = (float)Math.Sqrt(za * za + zc * zc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
za *= s;
|
||||
zc *= s;
|
||||
s = (float)Math.Sqrt(za * za + zc * zc);
|
||||
if (data.transformMode == TransformMode.NoScale
|
||||
&& (pa * pd - pb * pc < 0) != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
|
||||
|
||||
float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
|
||||
float zb = MathUtils.Cos(r) * s;
|
||||
float zd = MathUtils.Sin(r) * s;
|
||||
@@ -242,26 +231,18 @@ namespace SpineRuntime36 {
|
||||
float lb = MathUtils.CosDeg(90 + shearY) * scaleY;
|
||||
float lc = MathUtils.SinDeg(shearX) * scaleX;
|
||||
float ld = MathUtils.SinDeg(90 + shearY) * scaleY;
|
||||
if (data.transformMode != TransformMode.NoScaleOrReflection? pa * pd - pb* pc< 0 : skeleton.flipX != skeleton.flipY) {
|
||||
zb = -zb;
|
||||
zd = -zd;
|
||||
}
|
||||
a = za * la + zb * lc;
|
||||
b = za * lb + zb * ld;
|
||||
c = zc * la + zd * lc;
|
||||
d = zc * lb + zd * ld;
|
||||
return;
|
||||
d = zc * lb + zd * ld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skeleton.flipX) {
|
||||
a = -a;
|
||||
b = -b;
|
||||
}
|
||||
if (skeleton.flipY != Bone.yDown) {
|
||||
c = -c;
|
||||
d = -d;
|
||||
}
|
||||
a *= skeleton.scaleX;
|
||||
b *= skeleton.scaleX;
|
||||
c *= skeleton.scaleY;
|
||||
d *= skeleton.scaleY;
|
||||
}
|
||||
|
||||
public void SetToSetupPose () {
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace SpineRuntime36 {
|
||||
internal Skin skin;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal float time;
|
||||
internal bool flipX, flipY;
|
||||
internal float x, y;
|
||||
internal float scaleX = 1, scaleY = 1;
|
||||
internal float x, y;
|
||||
|
||||
public SkeletonData Data { get { return data; } }
|
||||
public ExposedList<Bone> Bones { get { return bones; } }
|
||||
@@ -64,10 +64,16 @@ namespace SpineRuntime36 {
|
||||
public float Time { get { return time; } set { time = value; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
public bool FlipX { get { return flipX; } set { flipX = value; } }
|
||||
public bool FlipY { get { return flipY; } set { flipY = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
|
||||
public Bone RootBone {
|
||||
[Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")]
|
||||
public bool FlipX { get { return scaleX < 0; } set { scaleX = value ? -1f : 1f; } }
|
||||
|
||||
[Obsolete("Use ScaleY instead. FlipY is when ScaleY is negative.")]
|
||||
public bool FlipY { get { return scaleY < 0; } set { scaleY = value ? -1f : 1f; } }
|
||||
|
||||
public Bone RootBone {
|
||||
get { return bones.Count == 0 ? null : bones.Items[0]; }
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,14 @@ namespace SpineViewer.Controls
|
||||
public SkelFileListBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
Items = listBox.Items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ListBox.Items
|
||||
/// </summary>
|
||||
public readonly ListBox.ObjectCollection Items;
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public ListBox.ObjectCollection Items { get => listBox.Items; }
|
||||
|
||||
/// <summary>
|
||||
/// 从路径列表添加
|
||||
|
||||
@@ -29,12 +29,12 @@ namespace SpineViewer.Controls
|
||||
/// <summary>
|
||||
/// Spine 列表只读视图, 访问时必须使用 lock 语句锁定视图本身
|
||||
/// </summary>
|
||||
public readonly ReadOnlyCollection<Spine.SpineObject> Spines;
|
||||
public readonly ReadOnlyCollection<SpineObject> Spines;
|
||||
|
||||
/// <summary>
|
||||
/// Spine 列表, 访问时必须使用 lock 语句锁定只读视图 Spines
|
||||
/// </summary>
|
||||
private readonly List<Spine.SpineObject> spines = [];
|
||||
private readonly List<SpineObject> spines = [];
|
||||
|
||||
/// <summary>
|
||||
/// 用于属性页显示模型参数的包装类
|
||||
@@ -80,7 +80,7 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
try
|
||||
{
|
||||
var spine = Spine.SpineObject.New(result.Version, result.SkelPath, result.AtlasPath);
|
||||
var spine = SpineObject.New(result.Version, result.SkelPath, result.AtlasPath);
|
||||
|
||||
// 如果索引无效则在末尾添加
|
||||
if (index < 0 || index > listView.Items.Count)
|
||||
@@ -155,7 +155,7 @@ namespace SpineViewer.Controls
|
||||
|
||||
try
|
||||
{
|
||||
var spine = Spine.SpineObject.New(version, skelPath);
|
||||
var spine = SpineObject.New(version, skelPath);
|
||||
var preview = spine.Preview;
|
||||
lock (Spines) { spines.Add(spine); }
|
||||
spinePropertyWrappers[spine.ID] = new(spine);
|
||||
|
||||
118
SpineViewer/Controls/SpinePreviewPanel.Designer.cs
generated
118
SpineViewer/Controls/SpinePreviewPanel.Designer.cs
generated
@@ -32,7 +32,6 @@
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpinePreviewPanel));
|
||||
panel_Render = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
panel_Container = new Panel();
|
||||
flowLayoutPanel1 = new FlowLayoutPanel();
|
||||
button_Stop = new Button();
|
||||
imageList = new ImageList(components);
|
||||
@@ -40,10 +39,16 @@
|
||||
button_Start = new Button();
|
||||
button_ForwardStep = new Button();
|
||||
button_ForwardFast = new Button();
|
||||
button_FullScreen = new Button();
|
||||
panel_ViewContainer = new Panel();
|
||||
panel_RenderContainer = new Panel();
|
||||
toolTip = new ToolTip(components);
|
||||
spinePreviewFullScreenForm = new SpineViewer.Forms.SpinePreviewFullScreenForm();
|
||||
wallpaperForm = new WallpaperForm();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
panel_Container.SuspendLayout();
|
||||
flowLayoutPanel1.SuspendLayout();
|
||||
panel_ViewContainer.SuspendLayout();
|
||||
panel_RenderContainer.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel_Render
|
||||
@@ -63,8 +68,8 @@
|
||||
//
|
||||
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.Controls.Add(panel_ViewContainer, 0, 0);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(0, 0);
|
||||
tableLayoutPanel1.Margin = new Padding(0);
|
||||
@@ -75,17 +80,6 @@
|
||||
tableLayoutPanel1.Size = new Size(641, 636);
|
||||
tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// panel_Container
|
||||
//
|
||||
panel_Container.BackColor = SystemColors.ControlDark;
|
||||
panel_Container.Controls.Add(panel_Render);
|
||||
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, 594);
|
||||
panel_Container.TabIndex = 0;
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
flowLayoutPanel1.Anchor = AnchorStyles.None;
|
||||
@@ -96,10 +90,11 @@
|
||||
flowLayoutPanel1.Controls.Add(button_Start);
|
||||
flowLayoutPanel1.Controls.Add(button_ForwardStep);
|
||||
flowLayoutPanel1.Controls.Add(button_ForwardFast);
|
||||
flowLayoutPanel1.Location = new Point(138, 594);
|
||||
flowLayoutPanel1.Controls.Add(button_FullScreen);
|
||||
flowLayoutPanel1.Location = new Point(101, 594);
|
||||
flowLayoutPanel1.Margin = new Padding(0);
|
||||
flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
flowLayoutPanel1.Size = new Size(365, 42);
|
||||
flowLayoutPanel1.Size = new Size(438, 42);
|
||||
flowLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// button_Stop
|
||||
@@ -122,18 +117,19 @@
|
||||
imageList.ColorDepth = ColorDepth.Depth32Bit;
|
||||
imageList.ImageStream = (ImageListStreamer)resources.GetObject("imageList.ImageStream");
|
||||
imageList.TransparentColor = Color.Transparent;
|
||||
imageList.Images.SetKeyName(0, "stop");
|
||||
imageList.Images.SetKeyName(1, "restart");
|
||||
imageList.Images.SetKeyName(2, "start");
|
||||
imageList.Images.SetKeyName(0, "arrows-maximize");
|
||||
imageList.Images.SetKeyName(1, "forward-fast");
|
||||
imageList.Images.SetKeyName(2, "forward-step");
|
||||
imageList.Images.SetKeyName(3, "pause");
|
||||
imageList.Images.SetKeyName(4, "forward-step");
|
||||
imageList.Images.SetKeyName(5, "forward-fast");
|
||||
imageList.Images.SetKeyName(4, "rotate-left");
|
||||
imageList.Images.SetKeyName(5, "start");
|
||||
imageList.Images.SetKeyName(6, "stop");
|
||||
//
|
||||
// button_Restart
|
||||
//
|
||||
button_Restart.AutoSize = true;
|
||||
button_Restart.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_Restart.ImageKey = "restart";
|
||||
button_Restart.ImageKey = "rotate-left";
|
||||
button_Restart.ImageList = imageList;
|
||||
button_Restart.Location = new Point(76, 3);
|
||||
button_Restart.Name = "button_Restart";
|
||||
@@ -190,6 +186,74 @@
|
||||
button_ForwardFast.UseVisualStyleBackColor = true;
|
||||
button_ForwardFast.Click += button_ForwardFast_Click;
|
||||
//
|
||||
// button_FullScreen
|
||||
//
|
||||
button_FullScreen.AutoSize = true;
|
||||
button_FullScreen.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_FullScreen.ImageKey = "arrows-maximize";
|
||||
button_FullScreen.ImageList = imageList;
|
||||
button_FullScreen.Location = new Point(368, 3);
|
||||
button_FullScreen.Name = "button_FullScreen";
|
||||
button_FullScreen.Padding = new Padding(15, 3, 15, 3);
|
||||
button_FullScreen.Size = new Size(67, 36);
|
||||
button_FullScreen.TabIndex = 5;
|
||||
toolTip.SetToolTip(button_FullScreen, "全屏预览");
|
||||
button_FullScreen.UseVisualStyleBackColor = true;
|
||||
button_FullScreen.Click += button_FullScreen_Click;
|
||||
//
|
||||
// panel_ViewContainer
|
||||
//
|
||||
panel_ViewContainer.Controls.Add(panel_RenderContainer);
|
||||
panel_ViewContainer.Dock = DockStyle.Fill;
|
||||
panel_ViewContainer.Location = new Point(0, 0);
|
||||
panel_ViewContainer.Margin = new Padding(0);
|
||||
panel_ViewContainer.Name = "panel_ViewContainer";
|
||||
panel_ViewContainer.Size = new Size(641, 594);
|
||||
panel_ViewContainer.TabIndex = 6;
|
||||
//
|
||||
// panel_RenderContainer
|
||||
//
|
||||
panel_RenderContainer.BackColor = SystemColors.ControlDark;
|
||||
panel_RenderContainer.Controls.Add(panel_Render);
|
||||
panel_RenderContainer.Dock = DockStyle.Fill;
|
||||
panel_RenderContainer.Location = new Point(0, 0);
|
||||
panel_RenderContainer.Margin = new Padding(0);
|
||||
panel_RenderContainer.Name = "panel_RenderContainer";
|
||||
panel_RenderContainer.Size = new Size(641, 594);
|
||||
panel_RenderContainer.TabIndex = 0;
|
||||
panel_RenderContainer.SizeChanged += panel_RenderContainer_SizeChanged;
|
||||
//
|
||||
// spinePreviewFullScreenForm
|
||||
//
|
||||
spinePreviewFullScreenForm.ClientSize = new Size(2560, 1440);
|
||||
spinePreviewFullScreenForm.ControlBox = false;
|
||||
spinePreviewFullScreenForm.FormBorderStyle = FormBorderStyle.None;
|
||||
spinePreviewFullScreenForm.MaximizeBox = false;
|
||||
spinePreviewFullScreenForm.MinimizeBox = false;
|
||||
spinePreviewFullScreenForm.Name = "SpinePreviewFullScreenForm";
|
||||
spinePreviewFullScreenForm.ShowIcon = false;
|
||||
spinePreviewFullScreenForm.ShowInTaskbar = false;
|
||||
spinePreviewFullScreenForm.StartPosition = FormStartPosition.Manual;
|
||||
spinePreviewFullScreenForm.TopMost = true;
|
||||
spinePreviewFullScreenForm.Visible = false;
|
||||
spinePreviewFullScreenForm.FormClosing += spinePreviewFullScreenForm_FormClosing;
|
||||
spinePreviewFullScreenForm.KeyDown += spinePreviewFullScreenForm_KeyDown;
|
||||
//
|
||||
// wallpaperForm
|
||||
//
|
||||
wallpaperForm.ClientSize = new Size(0, 0);
|
||||
wallpaperForm.ControlBox = false;
|
||||
wallpaperForm.FormBorderStyle = FormBorderStyle.None;
|
||||
wallpaperForm.MaximizeBox = false;
|
||||
wallpaperForm.MinimizeBox = false;
|
||||
wallpaperForm.Name = "WallpaperForm";
|
||||
wallpaperForm.ShowIcon = false;
|
||||
wallpaperForm.ShowInTaskbar = false;
|
||||
wallpaperForm.StartPosition = FormStartPosition.Manual;
|
||||
wallpaperForm.Visible = false;
|
||||
wallpaperForm.WindowState = FormWindowState.Minimized;
|
||||
wallpaperForm.FormClosing += wallpaperForm_FormClosing;
|
||||
//
|
||||
// SpinePreviewPanel
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
@@ -197,12 +261,12 @@
|
||||
Controls.Add(tableLayoutPanel1);
|
||||
Name = "SpinePreviewPanel";
|
||||
Size = new Size(641, 636);
|
||||
SizeChanged += SpinePreviewPanel_SizeChanged;
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
panel_Container.ResumeLayout(false);
|
||||
flowLayoutPanel1.ResumeLayout(false);
|
||||
flowLayoutPanel1.PerformLayout();
|
||||
panel_ViewContainer.ResumeLayout(false);
|
||||
panel_RenderContainer.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
@@ -210,7 +274,7 @@
|
||||
|
||||
private Panel panel_Render;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Panel panel_Container;
|
||||
private Panel panel_RenderContainer;
|
||||
private FlowLayoutPanel flowLayoutPanel1;
|
||||
private Button button_Stop;
|
||||
private Button button_Start;
|
||||
@@ -219,5 +283,9 @@
|
||||
private Button button_ForwardStep;
|
||||
private Button button_ForwardFast;
|
||||
private Button button_Restart;
|
||||
private Button button_FullScreen;
|
||||
private Panel panel_ViewContainer;
|
||||
private Forms.SpinePreviewFullScreenForm spinePreviewFullScreenForm;
|
||||
private WallpaperForm wallpaperForm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Security.Policy;
|
||||
using System.Diagnostics;
|
||||
using NLog;
|
||||
using SpineViewer.Utils;
|
||||
using System.Drawing.Design;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
@@ -19,14 +20,6 @@ namespace SpineViewer.Controls
|
||||
public SpinePreviewPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
renderWindow = new(panel_Render.Handle);
|
||||
renderWindow.SetActive(false);
|
||||
|
||||
// 设置默认参数
|
||||
Resolution = new(2048, 2048);
|
||||
Center = new(0, 0);
|
||||
FlipY = true;
|
||||
MaxFps = 30;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,42 +61,38 @@ namespace SpineViewer.Controls
|
||||
get => resolution;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (value == resolution) return;
|
||||
if (value.Width <= 0) value.Width = 100;
|
||||
if (value.Height <= 0) value.Height = 100;
|
||||
|
||||
float parentX = panel_Render.Parent.Width;
|
||||
float parentY = panel_Render.Parent.Height;
|
||||
float sizeX = value.Width;
|
||||
float sizeY = value.Height;
|
||||
var previousZoom = Zoom;
|
||||
|
||||
if ((sizeY / sizeX) < (parentY / parentX))
|
||||
{
|
||||
// 相同的 X, 子窗口 Y 更小
|
||||
sizeY = parentX * sizeY / sizeX;
|
||||
sizeX = parentX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 相同的 Y, 子窗口 X 更小
|
||||
sizeX = parentY * sizeX / sizeY;
|
||||
sizeY = parentY;
|
||||
}
|
||||
float parentW = panel_Render.Parent.Width;
|
||||
float parentH = panel_Render.Parent.Height;
|
||||
float renderW = value.Width;
|
||||
float renderH = value.Height;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
// 必须通过 SFML 的方法调整窗口
|
||||
renderWindow.Position = new((int)(parentX - sizeX) / 2, (int)(parentY - sizeY) / 2);
|
||||
renderWindow.Size = new((uint)sizeX, (uint)sizeY);
|
||||
|
||||
// 将 view 的大小设置成于 resolution 相同的大小, 其余属性都不变
|
||||
using var view = renderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(value.Width * signX, value.Height * signY);
|
||||
renderWindow.SetView(view);
|
||||
|
||||
renderWindow.Position = new((int)((parentW - renderW) / 2 + 0.5), (int)((parentH - renderH) / 2 + 0.5));
|
||||
renderWindow.Size = new((uint)(renderW + 0.5), (uint)(renderH + 0.5));
|
||||
resolution = value;
|
||||
|
||||
// 设置完 resolution 后还原缩放比例
|
||||
Zoom = previousZoom;
|
||||
|
||||
// 设置壁纸窗口分辨率
|
||||
using var view = renderWindow.GetView();
|
||||
wallpaperWindow.SetView(view);
|
||||
wallpaperForm.Size = value; // 必须两个 Size 都设置
|
||||
wallpaperWindow.Size = new((uint)value.Width, (uint)value.Height);
|
||||
}
|
||||
}
|
||||
private Size resolution = new(0, 0);
|
||||
private Size resolution = new(100, 100);
|
||||
|
||||
/// <summary>
|
||||
/// 画面中心点
|
||||
@@ -114,15 +103,20 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return new(-1, -1);
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var center = view.Center;
|
||||
return new(center.X, center.Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
view.Center = new(value.X, value.Y);
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,17 +129,22 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return -1;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return resolution.Width / Math.Abs(view.Size.X);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
value = Math.Clamp(value, 0.001f, 1000f);
|
||||
using var view = renderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(resolution.Width / value * signX, resolution.Height / value * signY);
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,14 +157,19 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return -1;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Rotation;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
view.Rotation = value;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,17 +182,22 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return false;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Size.X < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.X > 0 && value || size.X < 0 && !value)
|
||||
size.X *= -1;
|
||||
view.Size = size;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,17 +210,22 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return false;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Size.Y < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.Y > 0 && value || size.Y < 0 && !value)
|
||||
size.Y *= -1;
|
||||
view.Size = size;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +248,17 @@ namespace SpineViewer.Controls
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public uint MaxFps { get => maxFps; set { renderWindow.SetFramerateLimit(value); maxFps = value; } }
|
||||
public uint MaxFps
|
||||
{
|
||||
get => maxFps;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
renderWindow.SetFramerateLimit(value);
|
||||
maxFps = value;
|
||||
}
|
||||
}
|
||||
private uint maxFps = 60;
|
||||
|
||||
/// <summary>
|
||||
@@ -242,14 +266,45 @@ namespace SpineViewer.Controls
|
||||
/// </summary>
|
||||
public SFML.Graphics.View GetView() => renderWindow.GetView();
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 是否开启桌面投影
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool EnableDesktopProjection
|
||||
{
|
||||
get => enableDesktopProjection;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
#region 渲染管理
|
||||
if (enableDesktopProjection == value) return;
|
||||
if (value)
|
||||
{
|
||||
var screenBounds = Screen.FromControl(this).Bounds;
|
||||
Resolution = screenBounds.Size;
|
||||
wallpaperWindow.Position = new(screenBounds.X, screenBounds.Y);
|
||||
wallpaperForm.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
wallpaperForm.Hide();
|
||||
}
|
||||
enableDesktopProjection = value;
|
||||
}
|
||||
}
|
||||
private bool enableDesktopProjection = false;
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面背景色
|
||||
/// </summary>
|
||||
private static readonly SFML.Graphics.Color BackgroundColor = new(105, 105, 105);
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public SFML.Graphics.Color BackgroundColor { get; set; } = new(105, 105, 105);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 渲染管理
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面坐标轴颜色
|
||||
@@ -264,7 +319,12 @@ namespace SpineViewer.Controls
|
||||
/// <summary>
|
||||
/// 渲染窗口
|
||||
/// </summary>
|
||||
private readonly SFML.Graphics.RenderWindow renderWindow;
|
||||
private SFML.Graphics.RenderWindow renderWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 壁纸窗口
|
||||
/// </summary>
|
||||
private SFML.Graphics.RenderWindow wallpaperWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 帧间隔计时器
|
||||
@@ -312,11 +372,27 @@ namespace SpineViewer.Controls
|
||||
/// </summary>
|
||||
public void StartRender()
|
||||
{
|
||||
if (task is not null)
|
||||
return;
|
||||
// 延迟到第一次开启渲染时进行初始化
|
||||
if (renderWindow is null)
|
||||
{
|
||||
renderWindow = new(panel_Render.Handle);
|
||||
renderWindow.SetActive(false);
|
||||
wallpaperWindow = new(wallpaperForm.Handle);
|
||||
wallpaperWindow.SetActive(false);
|
||||
|
||||
// 设置默认参数
|
||||
Resolution = new(2048, 2048);
|
||||
Zoom = 1;
|
||||
Center = new(0, 0);
|
||||
FlipY = true;
|
||||
MaxFps = 30;
|
||||
}
|
||||
|
||||
if (task is not null) return;
|
||||
cancelToken = new();
|
||||
task = Task.Run(RenderTask, cancelToken.Token);
|
||||
IsUpdating = true;
|
||||
if (enableDesktopProjection) wallpaperForm.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -324,6 +400,7 @@ namespace SpineViewer.Controls
|
||||
/// </summary>
|
||||
public void StopRender()
|
||||
{
|
||||
wallpaperForm.Hide();
|
||||
IsUpdating = false;
|
||||
if (task is null || cancelToken is null)
|
||||
return;
|
||||
@@ -341,6 +418,7 @@ namespace SpineViewer.Controls
|
||||
try
|
||||
{
|
||||
renderWindow.SetActive(true);
|
||||
wallpaperWindow.SetActive(true);
|
||||
|
||||
float delta;
|
||||
while (cancelToken is not null && !cancelToken.IsCancellationRequested)
|
||||
@@ -359,6 +437,7 @@ namespace SpineViewer.Controls
|
||||
}
|
||||
|
||||
renderWindow.Clear(BackgroundColor);
|
||||
if (enableDesktopProjection) wallpaperWindow.Clear(BackgroundColor);
|
||||
|
||||
if (ShowAxis)
|
||||
{
|
||||
@@ -392,11 +471,15 @@ namespace SpineViewer.Controls
|
||||
spine.EnableDebug = true;
|
||||
renderWindow.Draw(spine);
|
||||
spine.EnableDebug = false;
|
||||
|
||||
if (enableDesktopProjection) wallpaperWindow.Draw(spine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderWindow.Display();
|
||||
|
||||
if (enableDesktopProjection) wallpaperWindow.Display();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -408,6 +491,7 @@ namespace SpineViewer.Controls
|
||||
finally
|
||||
{
|
||||
renderWindow.SetActive(false);
|
||||
wallpaperWindow.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,26 +502,27 @@ namespace SpineViewer.Controls
|
||||
/// </summary>
|
||||
private SFML.System.Vector2f? draggingSrc = null;
|
||||
|
||||
private void SpinePreviewPanel_SizeChanged(object sender, EventArgs e)
|
||||
private void panel_RenderContainer_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (renderWindow is null)
|
||||
return;
|
||||
if (renderWindow is null) return;
|
||||
|
||||
float parentW = panel_Render.Parent.Width;
|
||||
float parentH = panel_Render.Parent.Height;
|
||||
float renderW = panel_Render.Width;
|
||||
float renderH = panel_Render.Height;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderH *= scale;
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
// 必须通过 SFML 的方法调整窗口
|
||||
renderWindow.Position = new((int)(parentW - renderW) / 2, (int)(parentH - renderH) / 2);
|
||||
renderWindow.Size = new((uint)renderW, (uint)renderH);
|
||||
// 必须通过 SFML 的方法调整窗口, 此处必须四舍五入, 否则在全屏和小窗多次切换之后会有明显的舍入误差
|
||||
renderWindow.Position = new((int)((parentW - renderW) / 2 + 0.5), (int)((parentH - renderH) / 2 + 0.5));
|
||||
renderWindow.Size = new((uint)(renderW + 0.5), (uint)(renderH + 0.5));
|
||||
}
|
||||
|
||||
private void panel_Render_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
// 右键优先级高, 进入画面拖动模式, 需要重新记录源点
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
@@ -517,8 +602,9 @@ namespace SpineViewer.Controls
|
||||
|
||||
private void panel_Render_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (draggingSrc is null)
|
||||
return;
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (draggingSrc is null) return;
|
||||
|
||||
var src = (SFML.System.Vector2f)draggingSrc;
|
||||
var dst = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
@@ -645,6 +731,35 @@ namespace SpineViewer.Controls
|
||||
}
|
||||
}
|
||||
|
||||
private void button_FullScreen_Click(object sender, EventArgs e)
|
||||
{
|
||||
var screenBounds = Screen.FromControl(this).Bounds;
|
||||
Resolution = screenBounds.Size;
|
||||
spinePreviewFullScreenForm.Controls.Add(panel_RenderContainer);
|
||||
spinePreviewFullScreenForm.Bounds = screenBounds;
|
||||
spinePreviewFullScreenForm.Show();
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
|
||||
private void spinePreviewFullScreenForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Escape)
|
||||
{
|
||||
spinePreviewFullScreenForm.Hide();
|
||||
panel_ViewContainer.Controls.Add(panel_RenderContainer);
|
||||
}
|
||||
}
|
||||
|
||||
private void spinePreviewFullScreenForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
e.Cancel = e.CloseReason == CloseReason.UserClosing;
|
||||
}
|
||||
|
||||
private void wallpaperForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
e.Cancel = e.CloseReason == CloseReason.UserClosing;
|
||||
}
|
||||
|
||||
//public void ClickStopButton() => button_Stop_Click(button_Stop, EventArgs.Empty);
|
||||
//public void ClickRestartButton() => button_Restart_Click(button_Restart, EventArgs.Empty);
|
||||
//public void ClickStartButton() => button_Start_Click(button_Start, EventArgs.Empty);
|
||||
@@ -660,7 +775,8 @@ namespace SpineViewer.Controls
|
||||
[Browsable(false)]
|
||||
public SpinePreviewPanel PreviewPanel { get; } = previewPanel;
|
||||
|
||||
[TypeConverter(typeof(SizeConverter))]
|
||||
[RefreshProperties(RefreshProperties.All)]
|
||||
[TypeConverter(typeof(ResolutionConverter))]
|
||||
[Category("[0] 导出"), DisplayName("分辨率")]
|
||||
public Size Resolution { get => PreviewPanel.Resolution; set => PreviewPanel.Resolution = value; }
|
||||
|
||||
@@ -688,5 +804,10 @@ namespace SpineViewer.Controls
|
||||
|
||||
[Category("[1] 预览"), DisplayName("最大帧率")]
|
||||
public uint MaxFps { get => PreviewPanel.MaxFps; set => PreviewPanel.MaxFps = value; }
|
||||
|
||||
[Editor(typeof(SFMLColorEditor), typeof(UITypeEditor))]
|
||||
[TypeConverter(typeof(SFMLColorConverter))]
|
||||
[Category("[1] 预览"), DisplayName("背景颜色")]
|
||||
public SFML.Graphics.Color BackgroundColor { get => PreviewPanel.BackgroundColor; set => PreviewPanel.BackgroundColor = value; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,203 +124,170 @@
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAHi0AAAJNU0Z0AUkBTAIBAQYB
|
||||
AAF4AQABeAEAAR8BAAEYAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0q
|
||||
AAQCAy0BRQNbAc0DXwHoA1kBxgMyAU8DDwEUBAIYAAMOARIDQwF3A10BzwNbAc0DLQFFBAIYAANWAbID
|
||||
XwHoA1wB1gNDAXcDFgEeBAIYAAMKAQ0DSQGFA18B4wNfAeUDUQGeAyQBNAMJAQsEARgAAwsBDgM7AWQD
|
||||
XgHSA1YBsv8AEQAEAgMxAUwDYgHhAwAB/wMxAfkDYAHbA0QBewMeASoDBgEIFAADGAEhA1cBwgMhAfsD
|
||||
YgHhAzEBTAQCGAADWQHDAwAB/wMjAfwDXgHrA0gBhAMWAR4YAAMLAQ4DTQGSAy4B+QMQAf4DUwHyA1gB
|
||||
ugM3AVoDEQEWAwIBAxQAAxcBHwNJAYYDXgHrA1kBw/8AEQAEAgMxAUwDYgHhAwAB/wMAAf8DIAH9A2AB
|
||||
4ANQAZoDLgFGAxEBFgMGAQcEAQgAAxoBJANbAc0DAAH/A2IB4QMxAUwEAhgAA1kBwwMAAf8DAAH/AwAB
|
||||
/wNbAdADPgFrAw8BEwMCAQMQAAMLAQ4DTQGSAy4B+QMAAf8DAAH/AzwB9gNcAcsDRAF5Ax4BKgMGAQcM
|
||||
AAQBAxgBIQNKAYsDXAHsA1kBw/8AEQAEAgMxAUwDYgHhAwAB/wMxAfkDXAHnA0QB9QNXAe4DWQG7A0MB
|
||||
dwMoATsDDwEUBAEEAAMaASQDWwHNAwAB/wNiAeEDMQFMBAIYAANZAcMDIgH8A1EB8ANEAfUDMQH5A10B
|
||||
zgNDAXcDGgEjAwIBAwwAAwsBDgNNAZIDLgH5AwEB/wMlAfoDOwH4AzEB+QNeAeMDTgGYAyQBNQMGAQgE
|
||||
AQQABAEDGAEhA0oBiwNcAewDWQHD/wARAAQCAzEBTANiAeEDAAH/A1wB2QM7AWMDWQG7Az8B9wM6AfgD
|
||||
XAHnA1sBxQNBAXMDEwEZAwIBAwMaASQDWwHNAwAB/wNiAeEDMQFMBAIYAANZAcMDXgHrA1ABmgNVAbED
|
||||
TgHzAyEB+wNbAeQDSwGPAxsBJQMDAQQIAAMLAQ4DTQGSAy4B+QMhAf0DXAHZA1oBxwNEAfUDEAH+A14B
|
||||
6wNSAaMDJQE3AwMBBAQABAEDGAEhA0oBiwNcAewDWQHD/wARAAQCAzEBTANiAeEDAAH/A1sBzQMaASQD
|
||||
FgEdA1UBrwMAAf8DAAH/AwAB/wMAAf8DVQGvAxYBHQMaASQDWwHNAwAB/wNiAeEDMQFMBAIYAANZAcMD
|
||||
WwHkAzsBZQMHAQkDSQGGAyEB+wMAAf8DAAH/A1kBwQMdASkIAAMLAQ4DTQGSAy4B+QMuAfkDTQGSAzkE
|
||||
XgHiAwAB/wMAAf8DXgHjAzYBWAMFAQYEAAQBAxgBIQNKAYsDXAHsA1kBw/8AEQAEAgMxAUwDYgHhAwAB
|
||||
/wNbAc0DGgEkAwIBAwMTARoDRgF/A1sB3gMhAfsDEAH+AzoB+ANZAbsDOwFjA1wB2QMAAf8DYgHhAzEB
|
||||
TAQCGAADWQHDA1sB5AM7AWUDBwQJAQwDOgFhA18B1QNDAfUDMQH5A1sBygMyAU8DDwEUAw0BEQNNAZID
|
||||
LgH5Ay4B+QNNAZIDEQEWAy0BRANaAb8DVAHvAyEB+wNdAdwDPwFuAxYBHgMEAQUDGAEhA0oBiwNcAewD
|
||||
WQHD/wARAAQCAzEBTANiAeEDAAH/A1sBzQMaASQEAAQCAxMBGgM9AWcDWQHAA1QB7wMQAf4DPwH3A1wB
|
||||
5wMxAfkDAAH/A2IB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcBCQQAAwsBDgMxAU0DWAG9AzwB9gMxAfkD
|
||||
YAHbA0QBeAMhAS8DTgGVAy4B+QMuAfkDTQGSAwsBDgMGAQgDIAEuA00BkgNdAdwDRAH1A1oB6QNOAZYD
|
||||
KAE8AyABLQNLAY0DXAHsA1kBw/8AEQAEAgMxAUwDYgHhAwAB/wNbAc0DGgEkCAAEAgMMARADLwFJA1IB
|
||||
owNbAeQDPwH3AxAB/gMAAf8DAAH/A2IB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcBCQgAAxABFQM/AW0D
|
||||
XAHWAyUB+gMgAf0DXAHWA0QBeQNUAasDIQH7Ay4B+QNNAZIDCwEOBAADAwEEAxsBJgNBAXMDWgHEA0cB
|
||||
9ANXAe4DVQG0A0QBegNRAaIDVwHuA1kBw/8AEQAEAgMxAUwDYgHhAwAB/wNbAc0DGgEkEAADCAEKAyMB
|
||||
MwNEAXkDVwG8A18B5QMlAfoDAAH/A2IB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcBCQgAAwMBBAMaASQD
|
||||
QgF0A14B0gMhAfsDPAH2A10B0QNgAeADIAH9Ay4B+QNNAZIDCwEOCAADAgEDAxIBFwM1AVUDWAG6A1YB
|
||||
8QM8AfYDWwHeA2AB2wM6AfgDWQHD/wARAAQCAzEBTANiAeEDAAH/A1sBzQMaASQUAAMCAQMDDgESAyMB
|
||||
MgM9AWgDXgHdAwAB/wNiAeEDMQFMBAIYAANZAcMDWwHkAzsBZQMHAQkMAAMCAQMDDwETAzQBUwNdAdED
|
||||
OgH4AyEB/AMhAf0DAAH/Ay4B+QNNAZIDCwEODAAEAQMJAQwDIwEzA1UBrgMiAf0DIAH9AyEB/AMQAf4D
|
||||
WQHD/wARAAQCAzEBTANiAeEDAAH/A1sBzQMaASQgAAMaASQDWwHNAwAB/wNiAeEDMQFMBAIYAANZAcMD
|
||||
WwHkAzsBZQMHAQkYAAMPARQDVwG5AwAB/wMAAf8DAAH/Ay4B+QNNAZIDCwEOGAADRwGAA14B7QMAAf8D
|
||||
AAH/AwAB/wNZAcP/ABEABAIDMQFMA2IB4QMAAf8DWwHNAxoBJBQABAIDBwEJAxYBHQM1AVUDXAHZAwAB
|
||||
/wNiAeEDMQFMBAIYAANZAcMDWwHkAzsBZQMHAQkMAAQBAw0BEQM0AVMDXQHRAzEB+QMRAf4DEAH+AwAB
|
||||
/wMuAfkDTQGSAwsBDgwABAEDCQELAx4BKwNTAakDIgH9AyAB/QMhAfwDEAH+A1kBw/8AEQAEAgMxAUwD
|
||||
YgHhAwAB/wNbAc0DGgEkEAADBwEJAxsBJgM0AVMDTQGSA14B3QMxAfkDAAH/A2IB4QMxAUwEAhgAA1kB
|
||||
wwNbAeQDOwFlAwcBCQgABAIDEAEVAzkBXgNbAc0DIQH7AyEB+wNcAecDVwHuAxAB/gMuAfkDTQGSAwsB
|
||||
DggAAwIBAwMSARcDNQFVA1gBuANWAfEDPAH2A1sB3gNgAdsDOgH4A1kBw/8AEQAEAgMxAUwDYgHhAwAB
|
||||
/wNbAc0DGgEkCAAEAgMMARADLgFGA00BkgNcAcgDXgHrAyAB/QMAAf8DAAH/A2IB4QMxAUwEAhgAA1kB
|
||||
wwNbAeQDOwFlAwcBCQgAAwkBDAMxAU4DWAG3A04B8wMgAf0DXgHdA04BlgNZAb4DIQH8Ay4B+QNNAZID
|
||||
CwEOBAADAwEEAxsBJgNBAXMDWgHEA0cB9ANXAe4DVQG0A0QBegNRAaIDVwHuA1kBw/8AEQAEAgMxAUwD
|
||||
YgHhAwAB/wNbAc0DGgEkBAAEAgMTARoDPQFnA1oBvwNeAesDJQH6Az0B9gNcAecDMQH5AwAB/wNiAeED
|
||||
MQFMBAIYAANZAcMDWwHkAzsBZQMHAQkEAAMLAQ4DLgFHA1UBrQNUAe8DOwH4A2AB2wNEAXoDJAE1A04B
|
||||
mAMkAfoDLgH5A00BkgMLAQ4DBgEIAyABLgNNAZIDXQHcA0QB9QNaAekDTgGWAygBPAMgAS0DSwGNA1wB
|
||||
7ANZAcP/ABEABAIDMQFMA2IB4QMAAf8DWwHNAxoBJAMCAQMDEwEaA0YBfwNbAd4DIQH7AxAB/gM6AfgD
|
||||
WQG7AzsBYwNcAdkDAAH/A2IB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcECQEMAzoBYQNdAdQDRwH0AzEB
|
||||
+QNbAcoDMgFPAw8BFAMNAREDTQGSAy4B+QMuAfkDTQGSAxEBFgMtAUQDWgG/A1QB7wMiAfwDYAHgA0AB
|
||||
cQMXAR8DBAEFAxgBIQNKAYsDXAHsA1kBw/8AEQAEAgMxAUwDYgHhAwAB/wNbAc0DGgEkAxYBHQNVAa8D
|
||||
AAH/AwAB/wMAAf8DAAH/A1UBrwMWAR0DGgEkA1sBzQMAAf8DYgHhAzEBTAQCGAADWQHDA1sB5AM7AWUD
|
||||
BwEJA0kBhgMhAfsDAAH/AwAB/wNZAcEDHQEpCAADCwEOA00BkgMuAfkDLgH5A00BkgM5BF4B4gMAAf8D
|
||||
AAH/A1oB7QNKAYsDGAEgCAEDGAEhA0oBiwNcAewDWQHD/wARAAQCAzEBTANiAeEDAAH/A1wB2QM7AWMD
|
||||
WQG7Az8B9wMiAfwDRwH0A1wB2QNGAX4DEwEaAwIBAwMaASQDWwHNAwAB/wNiAeEDMQFMBAIYAANZAcMD
|
||||
XgHrA1ABmgNVAbEDTgHzAyEB+wNfAeUDSwGPAxsBJQMDAQQIAAMLAQ4DTQGSAy4B+QMhAfsDVgGzA0wB
|
||||
jgNeAesDEAH+A1EB8ANXAbkDLgFHAwYBCAQABAEDGAEhA0oBiwNcAewDWQHD/wARAAQCAzEBTANiAeED
|
||||
AAH/AzEB+QNcAecDRAH1A1UB8QNbAdMDUQGkAzgBWwMTARkEAgQAAxoBJANbAc0DAAH/A2IB4QMxAUwE
|
||||
AhgAA1kBwwMiAfwDUQHwA0QB9QMhAf0DXgHXA0YBfgMaASQDAgEDDAADCwEOA00BkgMuAfkDEAH+A04B
|
||||
8wNXAe4DPwH3A14B4wNOAZgDJwE5AwgBCgQBBAAEAQMYASEDSgGLA1wB7ANZAcP/ABEABAIDMQFMA2IB
|
||||
4QMAAf8DAAH/AyAB/QNiAeEDUgGjAzsBYwMhAS8DCgENBAIIAAMaASQDWwHNAwAB/wNiAeEDMQFMBAIY
|
||||
AANZAcMDAAH/AwAB/wMAAf8DXwHoA0oBiwMWAR0DBAEFEAADCwEOA00BkgMuAfkDAAH/AwAB/wM8AfYD
|
||||
XAHLA0QBeQMeASoDBgEHDAAEAQMYASEDSgGLA1wB7ANZAcP/ABEABAIDMQFMA2IB4QMAAf8DMQH5A2AB
|
||||
2wNFAXwDIQEwAwwBEAMDAQQQAAMaASMDXAHIAyEB/QNiAeEDMQFMBAIYAANZAcMDAAH/AyMB/ANeAesD
|
||||
TgGXAyMBMwQCFAADCwEOA00BkgMuAfkDEAH+A1MB8gNYAboDNwFaAxEBFgMCAQMUAAMXAR8DSQGGA14B
|
||||
6wNZAcP/ABEABAIDLQFFA14B0gNTAfIDXQHJAzIBTwMQARUDAgEDGAADEwEaA1ABnwNbAeQDWwHQAy0B
|
||||
RQQCGAADVQG0A1gB7gNfAdoDRAF4AxgBIAMDAQQYAAMKAQ0DSQGGA18B6ANaAekDUAGfAyQBNAMJAQsE
|
||||
ARgAAwsBDgM7AWUDWwHTA1YBsv8AFQADAwEEAycBOgM/AW0DFAEbKAADDwETAzEBTgMdASkDAgEDHAAD
|
||||
DgESAzEBTQMjATMDBAEFJAADBgEHAygBPAMoATwDBgEHJAAEAQMHAQkDCwEOAwIBA/8ABQADAgEDAw8B
|
||||
FANJAYgDXwHlA18B6ANfAegDXwHoA18B6ANfAegDXwHoA18B6ANfAegDXwHoA18B6ANfAegDXwHoA18B
|
||||
6ANfAegDXwHoA18B6ANfAegDXwHoA1sB5ANGAX4DBQEGBAEoAAMCAQMDDQERAx8BLAMtAUYDVwG5A18B
|
||||
6ANfAegDXwHoA18B6ANfAegDXwHoA2AB4wNZAb4DMgFPAw8BEwMCAQMwAAMTARkDRgF+A18B6ANfAegD
|
||||
WQHBAzkBXgMmATgDDwEUBAJcAAM5AV8DXgHiA1wB5wNfAegDXwHoA18B6ANfAegDXQHcAzwBZgMGAQgD
|
||||
BgEIAzwBZgNdAdwDXwHoA18B6ANfAegDXwHoA10B3ANQAZ0DJQE2IAADDAEQAzwBZgNdAc8DIAH9AyUB
|
||||
+gNUAe8DWgHtA1oB7QNaAe0DWgHtA1oB7QNaAe0DWgHtA1oB7QNaAe0DWgHtA1oB7QNaAe0DWgHtA1oB
|
||||
7QNUAe8DJQH6AyIB/ANWAbUDKwFCAwgBCiQABAIDGAEhA0ABcANaAb8DXQHfA1wB7QNUAe8DXAHsA2AB
|
||||
5gNfAeUDWgHqA1oB7QNRAfADPQH2A10B0QNDAXcDHgErAwYBBywAAz0BaQNbAd4DAQH/AzEB+QNdAewD
|
||||
WwHkA14B1wNEAXsDHgEqAwYBCFgAAz8BbAMhAf0DOgH4A1QB7wNaAe0DVwHuAyUB+gM8AfYDTwGbAx4B
|
||||
KwMgAS0DUAGdAzwB9gMlAfoDVwHuA1oB7QNUAe8DPwH3A1MB8gM7AWUgAAMTARkDUAGcAz8B9wM9AfYD
|
||||
XQHMA0sBjQNGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYAD
|
||||
RgGAA0sBjwNcAdkDIAH9A1UB8QNOAZQDEgEYJAADBQEGAzEBTgNbAdADUwHyA14B4gNVAa4DSgGKA0YB
|
||||
fwNDAXcDQwF2A0UBfANGAYADTwGbA14B3QNfAegDXwHaA04BlgMoATwDCQEMKAADRwGDAzoB+AMiAfwD
|
||||
WwHTA1MBpgNcAdkDMQH5A2AB4ANQAZoDLQFEAwsBDlQAAz8BbAMiAfwDWwHTA0wBjgNGAYADSgGKA10B
|
||||
3AMhAf0DXgHdAzoBYAM6AWIDXQHfAyAB/QNdAdwDSgGKA0YBgANMAY4DWwHTAyIB/AM/AWwgAAMUARsD
|
||||
UgGlAx8B/QNbAdADPwFsAxgBIQMOARIDDgESAw4BEgMOARIDDgESAw4BEgMOARIDDgESAw4BEgMOARID
|
||||
DgESAw4BEgMOARIDDgESAyABLgNXAbkDIAH9Ax8B/QNSAaUDFAEbJAADBQEGAzEBTQNaAccDXAHIA0AB
|
||||
bwMlATcDEwEaAw4BEgMNAREDDAEQAw4BEgMOARIDHQEoAzoBYANLAY8DWwHYA2AB5gNWAbYDMQFNAwYB
|
||||
CCQAA0kBhgMhAfsDMQH5A1UBrgMqAUADPwFtA10B0QNEAfUDVwHuA1gBtwM2AVcDFgEdAwwBEAQCSAAD
|
||||
PwFsAzEB+QNVAa4DIAEtAw4BEgMbASUDWQG+AwAB/wNaAe0DPwFtAz8BbQNaAe0DAAH/A1kBvgMbASUD
|
||||
DgESAyABLQNVAa4DMQH5Az8BbCAAAxQBGwNSAaUDHwH9A1YBtgMoATwDCAEKOAADFgEeA1YBswMgAf0D
|
||||
HwH9A1IBpQMUARskAAQBAw8BFAMjATMDIQEwAwsBDgMDAQQEARQABAIDBwEJAx4BKgNLAYwDXQHfAz8B
|
||||
9wNTAakDKAE7JAADSQGGAyEB+wMxAfkDUwGnAxYBHgMMARADKgFAA1gBugNPAfMDSQH0A2AB2wNXAbwD
|
||||
QgF0AxMBGQMCAQNEAAM/AWwDMQH5A1MBpwMVARwEAAMPARQDVwG5AwAB/wNaAe0DPwFtAz8BbQNaAe0D
|
||||
AAH/A1cBuQMPARQEAAMVARwDUwGnAzEB+QM/AWwgAAMUARsDUgGlAx8B/QNVAbQDJgE4AwcBCTgAAxYB
|
||||
HgNWAbMDIAH9Ax8B/QNSAaUDFAEbYAADFQEcA1MBpwMxAfkDIQH7A0kBhiQAA0kBhgMhAfsDMQH5A1MB
|
||||
pwMVARwIAAMPARMDQwF2A1wB2QMhAf0DAAH/AwAB/wNVAa8DFgEdRAADPwFsAzEB+QNTAacDFQEcBAAD
|
||||
DwEUA1cBuQMAAf8DWgHtAz8BbQM/AW0DWgHtAwAB/wNXAbkDDwEUBAADFQEcA1MBpwMxAfkDPwFsIAAD
|
||||
FAEbA1IBpQMfAf0DVQG0AyYBOAMHAQk4AAMWAR4DVgGzAyAB/QMfAf0DUgGlAxQBG2AAAwIBAwMeASoD
|
||||
VQG0Az8B9wNSAaADGwElAwUBBhwAA0kBhgMhAfsDMQH5A1MBpwMVARwIAAQCAwkBCwMYASADRAF6A2AB
|
||||
2wM9AfcDPwH3A1kBuwMqAUADDgESAwUBBgQCNAADPwFsAzEB+QNTAacDFQEcBAADDwEUA1cBuQMAAf8D
|
||||
WgHtAz8BbQM/AW0DWgHtAwAB/wNXAbkDDwEUBAADFQEcA1MBpwMxAfkDPwFsIAADFAEbA1IBpQMfAf0D
|
||||
VQG0AyYBOAMHAQk4AAMWAR4DVgGzAyAB/QMfAf0DUgGlAxQBG2QAAw8BEwNAAW8DXQHUA1UB7wNMAZED
|
||||
EgEYHAADSQGGAyEB+wMxAfkDUwGnAxUBHBAABAIDDQERAzYBVwNYAbcDXAHsA1YB8QNdAdEDRAF5AzMB
|
||||
UAMbASYDBgEHMAADPwFsAzEB+QNTAacDFQEcBAADDwEUA1cBuQMAAf8DWgHtAz8BbQM/AW0DWgHtAwAB
|
||||
/wNXAbkDDwEUBAADFQEcA1MBpwMxAfkDPwFsIAADFAEbA1IBpQMfAf0DVQG0AyYBOAMHAQk4AAMWAR4D
|
||||
VgGzAyAB/QMfAf0DUgGlAxQBG2QAAwIBAwMPARMDUQGeAx8B/QNSAaUDFAEbHAADSQGGAyEB+wMxAfkD
|
||||
UwGnAxUBHBgAAwsBDgMtAUQDSwGPA1sBxQNiAeEDYgHhA1sBzQNMAZADKAE7AwkBDCwAAz8BbAMxAfkD
|
||||
UwGnAxUBHAQAAw8BFANXAbkDAAH/A1oB7QM/AW0DPwFtA1oB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacD
|
||||
MQH5Az8BbCAAAxQBGwNSAaUDHwH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMgAf0DHwH9A1IBpQMUARts
|
||||
AANNAZMDHwH9A1IBpQMUARscAANJAYYDIQH7AzEB+QNTAacDFQEcHAADBgEIAxkBIgMvAUkDQAFxA10B
|
||||
zANOAfMDWgHpA1YBtgMtAUQsAAM/AWwDMQH5A1MBpwMVARwEAAMPARQDVwG5AwAB/wNaAe0DPwFtAz8B
|
||||
bQNaAe0DAAH/A1cBuQMPARQEAAMVARwDUwGnAzEB+QM/AWwgAAMUARsDUgGlAx8B/QNVAbQDJgE4AwcB
|
||||
CTgAAxYBHgNWAbMDIAH9Ax8B/QNSAaUDFAEbbAADTQGTAx8B/QNSAaUDFAEbHAADSQGGAyEB+wMxAfkD
|
||||
UwGnAxUBHCAABAIDBAEFAwsBDgMwAUwDWQHBAz0B9gMvAfkDQQFyAwYBCCgAAz8BbAMxAfkDUwGnAxUB
|
||||
HAQAAw8BFANXAbkDAAH/A1oB7QM/AW0DPwFtA1oB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacDMQH5Az8B
|
||||
bCAAAxQBGwNSAaUDHwH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMgAf0DHwH9A1IBpQMUARtsAANNAZMD
|
||||
HwH9A1IBpQMUARscAANJAYYDIQH7AzEB+QNTAacDFQEcMAADFQEcA1MBpwMxAfkDWwHTAzoBYSgAAz8B
|
||||
bAMxAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1oB7QM/AW0DPwFtA1oB7QMAAf8DVwG5Aw8BFAQAAxUB
|
||||
HANTAacDMQH5Az8BbCAAAxQBGwNSAaUDHwH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMgAf0DHwH9A1IB
|
||||
pQMUARsQAAQBAwQBBQMLAQ4DDwETAw8BEwMPARMDDwETAw8BEwMNAREDCQEMAwMBBAQBLAADTQGTAx8B
|
||||
/QNSAaUDFAEbHAADSQGGAyEB+wMxAfkDUwGnAxUBHCAABAEDAgEDAwsBDgMwAUwDWQHBAz0B9gMvAfkD
|
||||
QQFyAwYBCCgAAz8BbAMxAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1oB7QM/AW0DPwFtA1oB7QMAAf8D
|
||||
VwG5Aw8BFAQAAxUBHANTAacDMQH5Az8BbCAAAxQBGwNSAaUDHwH9A1UBtAMmATgDBwEJOAADFgEeA1YB
|
||||
swMgAf0DHwH9A1IBpQMUARsQAAMGAQgDJAE1Az4BawNGAX0DRgF+A0YBfgNGAX4DRgF+A0QBewM9AWkD
|
||||
JAE0AwkBDCwAA00BkwMfAf0DUgGlAxQBGxwAA0kBhgMhAfsDMQH5A1MBpwMVARwcAAMGAQgDEgEXAyMB
|
||||
MwM/AW4DWwHNAz0B9gNaAeoDVgG2Ay0BRCwAAz8BbAMxAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1oB
|
||||
7QM/AW0DPwFtA1oB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacDMQH5Az8BbCAAAxQBGwNSAaUDHwH9A1UB
|
||||
tAMmATgDBwEJOAADFgEeA1YBswMgAf0DHwH9A1IBpQMUARsQAAMQARUDRgF/A1wB2QNaAeoDYAHmA2IB
|
||||
4QNgAeADXgHiA1wB5wNiAeEDUAGdAyEBMCQAAwIBAwMPARMDUQGeAx8B/QNSAaUDFAEbHAADSQGGAyEB
|
||||
+wMxAfkDUwGnAxUBHBgAAwsBDgMtAUQDRgGBA1MBqQNdAd8DXwHoA18B2gNOAZYDKAE8AwkBDCwAAz8B
|
||||
bAMxAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1oB7QM/AW0DPwFtA1oB7QMAAf8DVwG5Aw8BFAQAAxUB
|
||||
HANTAacDMQH5Az8BbCAAAxQBGwNSAaUDHwH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMgAf0DHwH9A1IB
|
||||
pQMUARsQAAMTARoDTgGYA0MB9QMAAf8DYAHgA1YBtgNZAb4DXgHXAz8B9wMiAfwDWgHHAysBQiQAAw8B
|
||||
EwNAAW8DXQHUA1UB7wNNAZIDEgEYHAADSQGGAyEB+wMxAfkDUwGnAxUBHBAABAIDDQERAzYBVwNYAbcD
|
||||
WgHqA10B7ANfAdUDSwGPAzoBYAMeASsDBgEHMAADPwFsAzEB+QNTAacDFQEcBAADDwEUA1cBuQMAAf8D
|
||||
WgHtAz8BbQM/AW0DWgHtAwAB/wNXAbkDDwEUBAADFQEcA1MBpwMxAfkDPwFsIAADFAEbA1IBpQMfAf0D
|
||||
VQG0AyYBOAMHAQk4AAMWAR4DVgGzAyAB/QMfAf0DUgGlAxQBGxAAAxQBGwNQAZoDPAH2AwAB/wNRAaQD
|
||||
JAE0A0QBeANeAd0DPwH3A1sB3gM7AWMDDgESIAADAgEDAx4BKgNVAbQDPwH3A1EBoQMbASYDBQEGHAAD
|
||||
SQGGAyEB+wMxAfkDUwGnAxUBHAwABAEDEwEZA0QBegNgAdsDPQH3Az8B9wNZAbsDKwFCAxMBGQMIAQoD
|
||||
AgEDNAADPwFsAzEB+QNTAacDFQEcBAADDwEUA1cBuQMAAf8DWgHtAz8BbQM/AW0DWgHtAwAB/wNXAbkD
|
||||
DwEUBAADFQEcA1MBpwMxAfkDPwFsIAADFAEbA1IBpQMfAf0DVQG0AyYBOAMHAQk4AAMWAR4DVgGzAyAB
|
||||
/QMfAf0DUgGlAxQBGxAAAxQBGwNQAZoDPAH2AwAB/wNOAZUDMQFMA2IB4QMAAf8DWwHNAxoBJCgAAxUB
|
||||
HANTAacDMQH5AyEB+wNJAYYkAANJAYYDIQH7AzEB+QNTAacDFQEcDAADCwEOA00BkgMuAfkDAAH/AwAB
|
||||
/wNVAa8DFgEdRAADPwFsAzEB+QNTAacDFQEcBAADDwEUA1cBuQMAAf8DWgHtAz8BbQM/AW0DWgHtAwAB
|
||||
/wNXAbkDDwEUBAADFQEcA1MBpwMxAfkDPwFsIAADFAEbA1IBpQMfAf0DVgG2AygBPAMIAQo4AAMWAR4D
|
||||
VgGzAyAB/QMfAf0DUgGlAxQBGxAAAxQBGwNQAZoDPAH2AwAB/wNEAfUDVgHvAyMB/AMSAf4DXQHMAx0B
|
||||
KQQCGAAEAgMGAQcDDwETAzIBTwNZAcADQwH1A10B0QM6AWAkAANJAYYDIQH7AzEB+QNTAacDFgEeAwwB
|
||||
EAMqAUADVwG5A1oB6QNVAe8DXQHoA10BzwNGAX0DEwEaAwIBA0QAAz8BbAMxAfkDUwGnAxUBHAQAAw8B
|
||||
FANXAbkDAAH/A1oB7QM/AW0DPwFtA1oB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacDMQH5Az8BbCAAAxQB
|
||||
GwNSAaUDHwH9A1sB0AM/AWwDGAEhAw4BEgMOARIDDgESAw4BEgMOARIDDgESAw4BEgMOARIDDgESAw4B
|
||||
EgMOARIDDgESAw4BEgMOARIDIAEuA1cBuQMgAf0DHwH9A1IBpQMUARsQAAMUARsDUAGaAzwB9gMAAf8D
|
||||
AAH/AyQB+gNDAfUDIAH9A2AB4ANAAXEDHQEoAw4BEgMNAREDCQEMAwgBCgMLBA4BEgMcAScDOAFbA0QB
|
||||
eQNaAccDYgHhA1YBtgM0AVQDDAEPJAADSQGGAyEB+wMxAfkDVQGuAyoBQAM/AW0DXQHRA0QB9QNXAe4D
|
||||
WQG7A0QBeQMqAUADEQEWBAJIAAM/AWwDMQH5A1UBrgMgAS0DDgESAxsBJQNZAb4DAAH/A1oB7QM/AW0D
|
||||
PwFtA1oB7QMAAf8DWQG+AxsBJQMOARIDIAEtA1UBrgMxAfkDPwFsIAADEwEaA1EBpAMhAfwDPAH2A10B
|
||||
zANLAY0DRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YB
|
||||
gANLAY8DXAHZAyAB/QNHAfQDTgGYAxMBGRAAAxIBGANLAYwDWgHtAwAB/wMiAf0DXAHZA1UBsQNdAd8D
|
||||
RAH1A2AB4ANPAZsDRgGAA0QBegM5AV4DMwFQAz0BaANGAX4DUAGaA18B2gNbAeQDXwHaA08BmwMpAT4D
|
||||
CgENKAADSQGGAyEB+wMiAfwDWwHTA1MBpgNcAdkDMQH5A2AB4ANQAZoDLQFFAxABFQMGAQcEAUwAAz8B
|
||||
bAMiAfwDWwHTA0wBjgNGAYADSgGKA10B3AMgAf0DXQHfAzoBYgM6AWIDXQHfAyAB/QNdAdwDSgGKA0YB
|
||||
gANMAY4DWwHTAyIB/AM/AWwgAAMSARcDSgGLA1wB6gMQAf4DJQH6A1QB7wNaAe0DWgHtA1oB7QNaAe0D
|
||||
WgHtA1oB7QNaAe0DWgHtA1oB7QNaAe0DWgHtA1oB7QNaAe0DWgHtA1QB7wMlAfoDIAH9A1cBwgM0AVQD
|
||||
CwEOEAADCAEKAy4BSANVAbEDXgHiA2AB2wNPAZsDLQFEA0MBdwNdAcwDYgHhA1oB6gNaAe0DWgHpA1sB
|
||||
0wNcAcgDXwHaA14B6wNQAfIDMQH5A14B0gNEAXgDIQEvAwcBCSwAA0IBdQNaAeoDAQH/AzEB+QNRAfAD
|
||||
XQHsA1wB2QNEAXsDHgEqAwYBCFgAAz8BbAMBAf8DMQH5A1QB7wNaAe0DVwHuAyUB+gM8AfYDUAGdAyAB
|
||||
LQMgAS0DUAGdAzwB9gMlAfoDVwHuA1oB7QNUAe8DMQH5AxAB/gM/AWwgAAMFAQYDGgEjA00BkwNhAeYD
|
||||
XAHtAz8B9gM/AfcDPwH3Az8B9wM/AfcDPwH3Az8B9wM/AfcDPwH3Az8B9wM/AfcDPwH3Az8B9wM/AfcD
|
||||
PwH3Az8B9gNcAe0DXwHlA0cBgwMKAQ0EAhAABAEDCAEKAx8BLAMuAUgDLQFEAxsBJQMHAQkDDwETAyMB
|
||||
MgMuAUcDVwG5A18B6ANaAekDWAHuA1YB8QNdAewDWgHpA18B6ANbAdADNAFTAw8BEwMCAQMwAAMWAR4D
|
||||
RwGDA1wB7QNWAfEDXwHVA0wBjgMrAUIDDwEUBAJcAAM6AWIDWgHpA1wB7QM/AfYDPwH3Az8B9gNdAewD
|
||||
XQHcAzwBZgMGAQgDBgEIAzwBZgNdAdwDXAHtAz8B9gM/AfcDPwH2A1wB7QNhAeYDOgFiLAAEAQMjATMD
|
||||
TgGXA1QBqwNUAasDVAGrA1QBqwNUAasDVAGrA1QBqwNUAasDVAGrA1QBqwNUAasDVAGrA1QBqwNUAasD
|
||||
TgGXAyMBMwQBTAADCQELAzkBXQNHAYIDJwE6AwQBBUgABAIDIgExAzoBYQMPARRwAAMDAQQDKAE7A04B
|
||||
mANUAasDUQGeAyEBLxQAAwMBBAMlATcDUAGfA1QBqwNOAZgDKAE7AwMBBBgAAUIBTQE+BwABPgMAASgD
|
||||
AAF8AwABMAMAAQEBAAEBBgABAxYAA/8BAAH8AQMB8AE/AQMB8AEPAcAIAAH8AQEB8AE/AQMB8AEHAcAI
|
||||
AAH8AQABMAE/AQAB8AEDAYAIAAH8AQABEAE/AQABcAEAAYAIAAH8AgABPwEAATABAAGACAAB/AIAAT8B
|
||||
AAEwAQABgAgAAfwCAAE/DAAB/AEIAQABPwEICwAB/AEMAQABPwEMAQABIAkAAfwBDwEAAT8BDAEAATAJ
|
||||
AAH8AQ8BgAE/AQ4BAAE4CQAB/AEPAfABPwEPAcABPwkAAfwBDwGAAT8BDgEAATgJAAH8AQ8BAAE/AQwB
|
||||
AAEwCQAB/AEMAQABPwEMAQABIAkAAfwBCAEAAT8BCAsAAfwCAAE/DAAB/AIAAT8BAAEwCgAB/AIAAT8B
|
||||
AAEwAQABgAgAAfwBAAEQAT8BAAFwAQABgAgAAfwBAAEwAT8BAAHwAQMBgAgAAfwBAAHwAT8BAQHwAQcB
|
||||
wAgAAfwBAwHwAT8BAwHwAQ8BwAgAAf4BHwH4AX8BDwH4AX8BwAgAAeACAAEHAf4BAAEBAf8B4AEPAv8B
|
||||
4AEAAQEB8AHgAgABBwH8AgAB/wHgAQcC/wHgAQABAQHwAeACAAEHAfwCAAF/AeABAwL/AeABAAEBAfAB
|
||||
4AIAAQcB/AIAAT8B4AEAAX8B/wHgAQABAQHwAeABfwH+AQcB/AEHAcABPwHgAQABPwH/AeEBAAEhAfAB
|
||||
4AF/Af4BBwL/AfgBPwHgAcABPwH/AeEBAAEhAfAB4AF/Af4BBwL/AfgBDwHgAcABAwH/AeEBAAEhAfAB
|
||||
4AF/Af4BBwL/AfwBDwHgAfABAQH/AeEBAAEhAfAB4AF/Af4BBwL/AfwBDwHgAfwBAAH/AeEBAAEhAfAB
|
||||
4AF/Af4BBwP/AQ8B4AH+AQAB/wHhAQABIQHwAeABfwH+AQcD/wEPAeAB/wEAAX8B4QEAASEB8AHgAX8B
|
||||
/gEHA/8BDwHgAf8B8AF/AeEBAAEhAfAB4AF/Af4BBwGAAQcB/wEPAeAB/wEAAX8B4QEAASEB8AHgAX8B
|
||||
/gEHAYABBwH/AQ8B4AH+AQAB/wHhAQABIQHwAeABfwH+AQcBgAEHAfwBDwHgAfwBAAH/AeEBAAEhAfAB
|
||||
4AF/Af4BBwGAAQcB/AEPAeAB8AEBAf8B4QEAASEB8AHgAX8B/gEHAYABBwH4AQ8C4AEDAf8B4QEAASEB
|
||||
8AHgAX8B/gEHAYABHwH4AT8C4AE/Af8B4QEAASEB8AHgAX8B/gEHAYABDwHAAT8B4AEAAT8B/wHhAQAB
|
||||
IQHwAeACAAEHAYACAAE/AeABAAF/Af8B4AEAAQEB8AHgAgABBwGAAgABfwHgAQAC/wHgAQABAQHwAeAC
|
||||
AAEHAYACAAH/AeABBwL/AeABAAEBAfAB4AIAAQcBgAEAAQEB/wHgAQ8C/wHgAQABAQHwAfwCAAE/Af8B
|
||||
+AE/Af8B8AP/AfABPgEDAfAL
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA8iMAAAJNU0Z0AUkBTAIBAQcB
|
||||
AAGQAQABkAEAAR8BAAEYAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0+
|
||||
AAMEAQUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/A1UB
|
||||
sWQAA1gB7wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/Ay0BRbcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9cAANEAXgDAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/swAB/wMAAf8DAAH/AwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/BwAB/wMAAf8DAAH/AwAB/wMAAf9XAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf+vAAH/AwAB/wNRAaQnAAH/AwAB/wMAAf8DAAH/MwAB/wMAAf8IAANOAZcDAAH/AwAB/wMAAf8D
|
||||
AAH/Ay4BSE8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB/+AAAxUBHQMAAf8DAAH/AwAB/y8AAf8DAAH/EwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf/kAAMmATgDAAH/AwAB/wMAAf8r
|
||||
AAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8DAAH/QwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/6wAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAANCAfYDAAH/AwAB/wMAAf8DAAH/AwQBBTsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/+8AAf8DAAH/AwAB/ycAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf/vAAH/AwAB/wMAAf8nAAH/AwAB/ygAAwcBCQMAAf8DAAH/AwAB/wMAAf8DYAHjLwAB/wMAAf8D
|
||||
AAH/SwAB/wMAAf8DAAH/7AADIAEtAwAB/wMAAf8nAAH/AwAB/zMAAf8DAAH/AwAB/wMAAf8DAAH/KwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/8wAB/wMAAf8nAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf9LAAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/PAADPwFsAwAB/wMAAf8nAAH/AwAB/wMAAf9L
|
||||
AAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB/0sAAf8D
|
||||
AAH/AwAB/5sAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/NAADCAEKAwAB/wMAAf8nAAH/AwAB
|
||||
/zAAA10BzgMAAf8DAAH/AwAB/wMAAf8EAScAAf8DAAH/AwAB/0sAAf8DAAH/AwAB/5QAAwUBBgMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/zMAAf8DAAH/AwAB/ycAAf8DAAH/LwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8vAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8nAAH/AwAB/ycAAf8DAAH/AwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8PAAH/AwAB/wMAAf8DFQEcLwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAAM9AWkDAAH/AwAB/wMAAf8DAAH/A0MBdjsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/5QAAwUBBgMAAf8DAAH/CwAB/wMAAf8DAAH/AxMBGjMAAf8DAAH/AwAB/ysAAf8DAAH/GwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf9DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wMbASYzAAH/AwAB/wMAAf8vAAH/AwAB/xMAAf8DAAH/AwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/SwAB
|
||||
/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMdASgkAANZAe4DAAH/AwAB
|
||||
/wMAAf8EAS8AAf8DAAH/CAADGAEhAwAB/wMAAf8DAAH/AwAB/wNcActPAAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/A2AB4wMAAf8DAAH/AwAB/wMAAf8DUAGfFwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf83AAH/AwAB/wcAAf8DAAH/AwAB/wMAAf8DAAH/VwAB/wMAAf8DAAH/AwAB/wMqAUAD
|
||||
KgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUAD
|
||||
AAH/AwAB/wMAAf8DAAH/mwAB/wMAAf8DAAH/Ax0BKQQAAwIBAwMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DBwEJWAAD
|
||||
WQHDAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/5wAAxIBFwMAAf8UAANKAYkDAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/AyEB+2cAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNbAcXIAANGAYADWgG/Ay4BSFQAA1oBv3QAA0YBgANaAb8DWgG/A1oBvwNaAb8DWgG/A1oB
|
||||
vwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DLgFIpwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADPQFpAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/EwAB/wMAAf8DAAH/LwAB/wMAAf8DAAH/KAADGQEiAwAB/wMAAf8jAAH/AwAB/wMAAf8oAAM/AW0D
|
||||
AAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADAwEEAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DAAH/AwAB/yQAA1YBtgMAAf8DAAH/AwAB
|
||||
/wMAAf8kAAM1AfkDAAH/AwAB/xwAA1cB8QMAAf8DAAH/AwAB/wMAAf8DPAH4IwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/IAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8gAAM1AfkDAAH/AwAB/xwAA1cB
|
||||
8QMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/x8AAf8DAAH/AwAB/zcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxIB/jMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNZAbsYAANWAbUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUQGeGAADNQH5AwAB/wMAAf8c
|
||||
AANXAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A1ABnRcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB
|
||||
/wMAAf8rAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAzUB+QMAAf8D
|
||||
AAH/HAADVwHxAwAB/wMAAf8DEQEWBAEDAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/zcAAf8D
|
||||
AAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswcAAf8D
|
||||
AAH/AwAB/wMAAf8jAAH/AwAB/wMAAf8DAAH/BwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAANWAbUDAAH/AwAB/wMzAVAHAAH/AwAB/wMAAf8DAAH/AwAB/xAAAzUB
|
||||
+QMAAf8DAAH/HAADVwHxAwAB/wMAAf8DEQEWCwAB/wMAAf8DAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wNWAbML
|
||||
AAH/AwAB/wMAAf8DEgH+GwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/Az0B
|
||||
aAgAA2AB2wMAAf8DAAH/AwAB/wMAAf8MAANWAbUDAAH/AwAB/wMzAVAIAANgAeMDAAH/AwAB/wMAAf8D
|
||||
AAH/DAADNQH5AwAB/wMAAf8cAANXAfEDAAH/AwAB/wMRARYMAAMzAVIDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/A1YBsw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/DAAD
|
||||
VAGrAwAB/wMAAf8DPQFoDAADJQE3AwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAzIB
|
||||
TwMAAf8DAAH/AwAB/wMAAf8IAAM1AfkDAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxIB/gMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xAAAwwBDwMAAf8D
|
||||
QgH2DAADVAGrAwAB/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8D
|
||||
AAH/AwAB/wMAAf8EAAM1AfkDAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFhgAA1oB6QMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/0cAAf8DAAH/AwAB/wMSAf4DAAH/AwAB/wMAAf8DAAH/LAADVAGrAwAB/wMAAf8DPQFoGwAB/wMAAf8D
|
||||
AAH/AwAB/wNdAc4DAAH/AwAB/wMzAVAbAAH/AwAB/wMAAf8DAAH/AyYB+gMAAf8DAAH/HAADVwHxAwAB
|
||||
/wMAAf8DEQEWIwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8wAANUAasDAAH/AwAB/wM9AWgf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMwFQHwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/HAADVwHxAwAB
|
||||
/wMAAf8DEQEWJwAB/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/08AAf8DAAH/AwAB/wMAAf80AANUAasDAAH/AwAB/wM9AWgjAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMzAVAjAAH/AwAB/wMAAf8DAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFisAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxIB/jAAA1QBqwMAAf8DAAH/Az0BaB8AAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMzAVAf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8cAANXAfEDAAH/AwAB/wMRARYkAANcAdkDAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf9HAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/ywAA1QBqwMAAf8DAAH/Az0BaBsAAf8DAAH/AwAB/wMAAf8DVwHxAwAB
|
||||
/wMAAf8DMwFQGwAB/wMAAf8DAAH/AwAB/wMSAf4DAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFiMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8D
|
||||
AAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xcAAf8DWAG4DAADVAGrAwAB
|
||||
/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8DAAH/AwAB/wMAAf8E
|
||||
AAM1AfkDAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFhgAAzABSgMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YB
|
||||
sw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DEgH+DwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
PQFoEwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAwkBDAMAAf8DAAH/AwAB/wMAAf8I
|
||||
AAM1AfkDAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB/wMAAf8DAAH/AyQB/QMAAf8D
|
||||
AAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/JwAB/wMAAf8D
|
||||
VgGzCwAB/wMAAf8DAAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8MAANUAasDAAH/AwAB
|
||||
/wM9AWgIAAM6AWADAAH/AwAB/wMAAf8DAAH/DAADVgG1AwAB/wMAAf8DMwFQCAADSwGMAwAB/wMAAf8D
|
||||
AAH/AwAB/wwAAzUB+QMAAf8DAAH/HAADVwHxAwAB/wMAAf8DEQEWDAADBwEJAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8HAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wNWAbMHAAH/AwAB/wMAAf8DAAH/IwAB/wMAAf8DAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wwAA1QBqwMAAf8DAAH/Az0BaAcAAf8DAAH/AwAB/wMAAf8DAAH/EAADVgG1AwAB/wMAAf8DMwFQBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAAM1AfkDAAH/AwAB/xwAA1cB8QMAAf8DAAH/AxEBFgsAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A08BmQsAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB/wMAAf8rAAH/AwAB/wMAAf8DEgH+AwAB
|
||||
/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8DAAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB
|
||||
/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAzUB+QMAAf8DAAH/HAADVwHxAwAB/wMAAf8DEQEWBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DTQH0GAADVgG1AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A10B7BgAAzUB+QMAAf8DAAH/HAADVwHxAwAB/wMAAf8DYQHrAwAB/wMAAf8DAAH/AwAB
|
||||
/wNNAfQXAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DQwF3HAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8DMAFMHAADNQH5AwAB/wMAAf8c
|
||||
AANXAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8fAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8DKgFAAyoB
|
||||
QAMqAUADAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8DKgFAAyoBQAMqAUADAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8bAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwYBCCAAA1YBtgMAAf8DAAH/AwAB/wMAAf8DAgEDIAAD
|
||||
NQH5AwAB/wMAAf8cAANXAfEDAAH/AwAB/wMAAf8DAAH/AwAB/yMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xQAA0wBkAMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/y8AAf8DAAH/AwAB/ygAAzYBWAMAAf8DAAH/IwAB
|
||||
/wMAAf8DAAH/Aw0BESQAA1UBrQMAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8sAANaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DFQEcGAAD
|
||||
TwGZA1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvxgAA04BlzQAA0sBjTAAAwwBDygAA1ABmjAAAygB
|
||||
PEAAAzgBWwNaAb8DWgG/A1oBvwMwAUwYAANEAXoDWgG/A1oBvwNaAb8DIAEtHAABQgFNAT4HAAE+AwAB
|
||||
KAMAAXwDAAEwAwABAQEAAQEGAAEDFgAD/wEAAf8B4AEHAf8B+AE/Av8B4AIAAXgEAAH/AcABAQH/AfgB
|
||||
HwL/AcACAAF4BAAB/wGDAeAB/wH5AQcC/wHAAgABOAQAAf8BjwH4AX8B+QGBAv8BxwH/Af4BOAQAAv8B
|
||||
/AE/AfkB4AL/AccB/wH+ATgEAAL/Af4BHwH5AfgBPwH/AccB/wH+ATgEAAP/AR8B+QH8AQ8B/wHHAf8B
|
||||
/gE4BAAD/wGPAfkB/wEHAf8BxwH/Af4BOAQAA/8BjwH5Af8BgQH/AccB/wH+ATgEAAP/AY8B+QH/AeAB
|
||||
/wHHAf8B/gE4BAAD/wHPAfkB/wH4AX8BxwH/Af4BOAQAA/8BzwH5Af8B/AF/AccB/wH+ATgEAAP/Ac8B
|
||||
+QH/AfgBfwHHAf8B/gE4BAAB8AEPAf8BjwH5Af8B4AF/AccB/wH+ATgEAAHgAQcB/wGPAfkB/wHBAf8B
|
||||
xwH/Af4BOAQAAeABBwH/AY8B+QH/AQcB/wHHAf8B/gE4BAAB4wGHAf8BHwH5AfwBDwH/AccB/wH+ATgE
|
||||
AAHjAQ8B/wEfAfkB+AE/Af8BxwH/Af4BOAQAAeIBHwH+AT8B+QHgAv8BxwH/Af4BOAQAAeABDwH4AT8B
|
||||
+QGBAv8BxwH/Af4BOAQAAeABAwHgAf8B+QEHAv8BwAIAATgEAAHwAYABAQH/AfgBDwL/AcACAAF4BAAB
|
||||
8wHgAQcB/wH4AT8C/wHgAgABeAQAAf8B/gE/Af8B/gP/AfgBAAEBAfgEAAHwAQcBwAEPAR8B/AF/AeMB
|
||||
/AF/AeMB/wHwAR4BAwLwAQcBwAEOAQ8B+AE/AeMB+AEfAeMB/wHgAQwBAQLwAX8B/gEOAQcB+AEfAeMB
|
||||
+AEPAeMB/wHgAQwBAQLwAT8B/AEOAQEB+AEHAeMB+AEDAeMB/wHjAYwBcQLwAR8B+AEOAQAB+AEDAeMB
|
||||
+AEBAeMB/wHjAYwBcQHwAfEBDwHwAY4BEAF4AUEB4wH4AWAB4wH/AeMBjAFxAfAB8QGHAeEBjgEYATgB
|
||||
YAHjAfgBcAEjAf8B4wGMAXEB8AHxAsMBjgEcARgBcAFjAfgBfAEDAf8B4wGMAXEB8AHzAeEBhwGOAR8B
|
||||
CAF8ASMB+AF+AQMB/wHjAYwBcQHwAf8B8AEPAf4BHwGAAX4BAwH4AX8BgwH/AeMBjAFxAfAB/wH4AR8B
|
||||
/gEfAcABfwEDAfgBfwHDAf8B4wGMAXEB8AH/AfwBPwH+AR8B4AF/AYMB+AF/AeMB/wHjAYwBcQHwAf8B
|
||||
+AEfAf4BHwHAAX8BAwH4AX8BwwH/AeMBjAFxAfAB/wHwAQ8B/gEfAYABfgEDAfgBfwGDAf8B4wGMAXEB
|
||||
8AHzAeEBhwHOAR8BCAF8ASMB+AF+AQMB/wHjAYwBcQHwAfECwwGOAR4BGAFwAWMB+AF8AQMB/wHjAYwB
|
||||
cQHwAfEBhwHhAY4BGAE4AWAB4wH4AXABIwH/AeMBjAFxAfAB8QEPAfABjgEQAXgBQQHjAfgBYAFjAf8B
|
||||
4wGMAXEC8AEfAfgBDgEAAfgBAwHjAfgBQQHjAf8B4wGMAXEC8AE/AfwBDgEBAfgBBwHjAfgBAwHjAf8B
|
||||
4wGMAXEC8AF/Af4BDgEDAfgBDwHjAfgBDwHjAf8B4AEMAQEC8AEHAeABDgEHAfgBHwHjAfgBHwHjAf8B
|
||||
4AEMAQEC8AEHAcABDwEfAfwBfwHjAfwBPwHjAf8B8AEeAQMB8AH4AQcB4AEfAb8B/gH/AfcB/gH/AfcB
|
||||
/wH4AT8BBwHwCw==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>165, 17</value>
|
||||
</metadata>
|
||||
<metadata name="spinePreviewFullScreenForm.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>307, 18</value>
|
||||
</metadata>
|
||||
<metadata name="wallpaperForm.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>618, 18</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -176,13 +176,13 @@
|
||||
contextMenuStrip_Skin.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip_Skin.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_ReloadSkins });
|
||||
contextMenuStrip_Skin.Name = "contextMenuStrip1";
|
||||
contextMenuStrip_Skin.Size = new Size(225, 34);
|
||||
contextMenuStrip_Skin.Size = new Size(241, 67);
|
||||
//
|
||||
// toolStripMenuItem_ReloadSkins
|
||||
//
|
||||
toolStripMenuItem_ReloadSkins.Name = "toolStripMenuItem_ReloadSkins";
|
||||
toolStripMenuItem_ReloadSkins.Size = new Size(224, 30);
|
||||
toolStripMenuItem_ReloadSkins.Text = "重新加载所选皮肤";
|
||||
toolStripMenuItem_ReloadSkins.Size = new Size(240, 30);
|
||||
toolStripMenuItem_ReloadSkins.Text = "重新加载皮肤";
|
||||
toolStripMenuItem_ReloadSkins.Click += toolStripMenuItem_ReloadSkins_Click;
|
||||
//
|
||||
// tabPage_Slot
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
using SpineViewer.Natives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
public partial class PetForm: Form
|
||||
{
|
||||
public PetForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
//var style = Win32.GetWindowLong(hWnd, Win32.GWL_STYLE) | Win32.WS_POPUP;
|
||||
//var exStyle = Win32.GetWindowLong(hWnd, Win32.GWL_EXSTYLE) | Win32.WS_EX_LAYERED | Win32.WS_EX_TOOLWINDOW | Win32.WS_EX_TOPMOST;
|
||||
//Win32.SetWindowLong(hWnd, Win32.GWL_STYLE, style);
|
||||
//Win32.SetWindowLong(hWnd, Win32.GWL_EXSTYLE, exStyle);
|
||||
//Win32.SetLayeredWindowAttributes(hWnd, crKey, 255, Win32.LWA_COLORKEY | Win32.LWA_ALPHA);
|
||||
//Win32.SetWindowPos(hWnd, Win32.HWND_TOPMOST, 0, 0, 0, 0, Win32.SWP_NOMOVE | Win32.SWP_NOSIZE);
|
||||
var cp = base.CreateParams;
|
||||
cp.ExStyle = Win32.WS_EX_LAYERED | Win32.WS_EX_TOPMOST;
|
||||
cp.Style = Win32.WS_POPUP;
|
||||
//cp.ExStyle |= Win32.WS_EX_LAYERED | Win32.WS_EX_TOOLWINDOW | Win32.WS_EX_TOPMOST;
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
SpineViewer/Forms/SpinePreviewFullScreenForm.Designer.cs
generated
Normal file
51
SpineViewer/Forms/SpinePreviewFullScreenForm.Designer.cs
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace SpineViewer.Forms
|
||||
{
|
||||
partial class SpinePreviewFullScreenForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
SuspendLayout();
|
||||
//
|
||||
// SpinePreviewFullScreenForm
|
||||
//
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
ClientSize = new Size(512, 512);
|
||||
ControlBox = false;
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "SpinePreviewFullScreenForm";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
TopMost = true;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
24
SpineViewer/Forms/SpinePreviewFullScreenForm.cs
Normal file
24
SpineViewer/Forms/SpinePreviewFullScreenForm.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Forms
|
||||
{
|
||||
[ToolboxItem(true)]
|
||||
[Designer(typeof(ComponentDesigner), typeof(IDesigner))]
|
||||
[DesignTimeVisible(true)]
|
||||
public partial class SpinePreviewFullScreenForm: Form
|
||||
{
|
||||
public SpinePreviewFullScreenForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
74
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
74
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
@@ -59,6 +59,8 @@
|
||||
toolStripMenuItem_Diagnostics = new ToolStripMenuItem();
|
||||
toolStripSeparator3 = new ToolStripSeparator();
|
||||
toolStripMenuItem_About = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Experiment = new ToolStripMenuItem();
|
||||
toolStripMenuItem_DesktopProjection = new ToolStripMenuItem();
|
||||
rtbLog = new RichTextBox();
|
||||
splitContainer_MainForm = new SplitContainer();
|
||||
splitContainer_Functional = new SplitContainer();
|
||||
@@ -74,6 +76,7 @@
|
||||
spinePreviewPanel = new SpineViewer.Controls.SpinePreviewPanel();
|
||||
panel_MainForm = new Panel();
|
||||
toolTip = new ToolTip(components);
|
||||
toolStripMenuItem_Debug = new ToolStripMenuItem();
|
||||
menuStrip.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_MainForm).BeginInit();
|
||||
splitContainer_MainForm.Panel1.SuspendLayout();
|
||||
@@ -102,7 +105,7 @@
|
||||
//
|
||||
menuStrip.BackColor = SystemColors.Control;
|
||||
menuStrip.ImageScalingSize = new Size(24, 24);
|
||||
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help });
|
||||
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help, toolStripMenuItem_Experiment });
|
||||
menuStrip.Location = new Point(0, 0);
|
||||
menuStrip.Name = "menuStrip";
|
||||
menuStrip.Size = new Size(1778, 32);
|
||||
@@ -271,7 +274,7 @@
|
||||
//
|
||||
// toolStripMenuItem_Help
|
||||
//
|
||||
toolStripMenuItem_Help.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Diagnostics, toolStripSeparator3, toolStripMenuItem_About });
|
||||
toolStripMenuItem_Help.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Diagnostics, toolStripSeparator3, toolStripMenuItem_About, toolStripMenuItem_Debug });
|
||||
toolStripMenuItem_Help.Name = "toolStripMenuItem_Help";
|
||||
toolStripMenuItem_Help.Size = new Size(88, 28);
|
||||
toolStripMenuItem_Help.Text = "帮助(&H)";
|
||||
@@ -279,22 +282,36 @@
|
||||
// toolStripMenuItem_Diagnostics
|
||||
//
|
||||
toolStripMenuItem_Diagnostics.Name = "toolStripMenuItem_Diagnostics";
|
||||
toolStripMenuItem_Diagnostics.Size = new Size(208, 34);
|
||||
toolStripMenuItem_Diagnostics.Size = new Size(270, 34);
|
||||
toolStripMenuItem_Diagnostics.Text = "诊断信息(&D)";
|
||||
toolStripMenuItem_Diagnostics.Click += toolStripMenuItem_Diagnostics_Click;
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
toolStripSeparator3.Size = new Size(205, 6);
|
||||
toolStripSeparator3.Size = new Size(267, 6);
|
||||
//
|
||||
// toolStripMenuItem_About
|
||||
//
|
||||
toolStripMenuItem_About.Name = "toolStripMenuItem_About";
|
||||
toolStripMenuItem_About.Size = new Size(208, 34);
|
||||
toolStripMenuItem_About.Size = new Size(270, 34);
|
||||
toolStripMenuItem_About.Text = "关于(&A)";
|
||||
toolStripMenuItem_About.Click += toolStripMenuItem_About_Click;
|
||||
//
|
||||
// toolStripMenuItem_Experiment
|
||||
//
|
||||
toolStripMenuItem_Experiment.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_DesktopProjection });
|
||||
toolStripMenuItem_Experiment.Name = "toolStripMenuItem_Experiment";
|
||||
toolStripMenuItem_Experiment.Size = new Size(138, 28);
|
||||
toolStripMenuItem_Experiment.Text = "实验性功能(&E)";
|
||||
//
|
||||
// toolStripMenuItem_DesktopProjection
|
||||
//
|
||||
toolStripMenuItem_DesktopProjection.Name = "toolStripMenuItem_DesktopProjection";
|
||||
toolStripMenuItem_DesktopProjection.Size = new Size(182, 34);
|
||||
toolStripMenuItem_DesktopProjection.Text = "桌面投影";
|
||||
toolStripMenuItem_DesktopProjection.Click += toolStripMenuItem_DesktopProjection_Click;
|
||||
//
|
||||
// rtbLog
|
||||
//
|
||||
rtbLog.BackColor = SystemColors.Window;
|
||||
@@ -305,7 +322,7 @@
|
||||
rtbLog.Margin = new Padding(3, 2, 3, 2);
|
||||
rtbLog.Name = "rtbLog";
|
||||
rtbLog.ReadOnly = true;
|
||||
rtbLog.Size = new Size(1758, 142);
|
||||
rtbLog.Size = new Size(1758, 154);
|
||||
rtbLog.TabIndex = 0;
|
||||
rtbLog.Text = "";
|
||||
rtbLog.WordWrap = false;
|
||||
@@ -329,7 +346,7 @@
|
||||
splitContainer_MainForm.Panel2.Controls.Add(rtbLog);
|
||||
splitContainer_MainForm.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_MainForm.Size = new Size(1758, 1097);
|
||||
splitContainer_MainForm.SplitterDistance = 947;
|
||||
splitContainer_MainForm.SplitterDistance = 935;
|
||||
splitContainer_MainForm.SplitterWidth = 8;
|
||||
splitContainer_MainForm.TabIndex = 3;
|
||||
splitContainer_MainForm.TabStop = false;
|
||||
@@ -353,7 +370,7 @@
|
||||
//
|
||||
splitContainer_Functional.Panel2.Controls.Add(groupBox_Preview);
|
||||
splitContainer_Functional.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Functional.Size = new Size(1758, 947);
|
||||
splitContainer_Functional.Size = new Size(1758, 935);
|
||||
splitContainer_Functional.SplitterDistance = 788;
|
||||
splitContainer_Functional.SplitterWidth = 8;
|
||||
splitContainer_Functional.TabIndex = 2;
|
||||
@@ -377,7 +394,7 @@
|
||||
//
|
||||
splitContainer_Information.Panel2.Controls.Add(splitContainer_Config);
|
||||
splitContainer_Information.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Information.Size = new Size(788, 947);
|
||||
splitContainer_Information.Size = new Size(788, 935);
|
||||
splitContainer_Information.SplitterDistance = 351;
|
||||
splitContainer_Information.SplitterWidth = 8;
|
||||
splitContainer_Information.TabIndex = 1;
|
||||
@@ -391,7 +408,7 @@
|
||||
groupBox_SkelList.Dock = DockStyle.Fill;
|
||||
groupBox_SkelList.Location = new Point(0, 0);
|
||||
groupBox_SkelList.Name = "groupBox_SkelList";
|
||||
groupBox_SkelList.Size = new Size(351, 947);
|
||||
groupBox_SkelList.Size = new Size(351, 935);
|
||||
groupBox_SkelList.TabIndex = 0;
|
||||
groupBox_SkelList.TabStop = false;
|
||||
groupBox_SkelList.Text = "模型列表";
|
||||
@@ -401,16 +418,16 @@
|
||||
spineListView.Dock = DockStyle.Fill;
|
||||
spineListView.Location = new Point(3, 26);
|
||||
spineListView.Name = "spineListView";
|
||||
spineListView.Size = new Size(345, 918);
|
||||
spineListView.Size = new Size(345, 906);
|
||||
spineListView.SpinePropertyGrid = spineViewPropertyGrid;
|
||||
spineListView.TabIndex = 0;
|
||||
//
|
||||
// spinePropertyGrid
|
||||
// spineViewPropertyGrid
|
||||
//
|
||||
spineViewPropertyGrid.Dock = DockStyle.Fill;
|
||||
spineViewPropertyGrid.Location = new Point(3, 26);
|
||||
spineViewPropertyGrid.Name = "spinePropertyGrid";
|
||||
spineViewPropertyGrid.Size = new Size(423, 586);
|
||||
spineViewPropertyGrid.Name = "spineViewPropertyGrid";
|
||||
spineViewPropertyGrid.Size = new Size(423, 580);
|
||||
spineViewPropertyGrid.TabIndex = 0;
|
||||
//
|
||||
// splitContainer_Config
|
||||
@@ -427,8 +444,8 @@
|
||||
// splitContainer_Config.Panel2
|
||||
//
|
||||
splitContainer_Config.Panel2.Controls.Add(groupBox_SkelConfig);
|
||||
splitContainer_Config.Size = new Size(429, 947);
|
||||
splitContainer_Config.SplitterDistance = 324;
|
||||
splitContainer_Config.Size = new Size(429, 935);
|
||||
splitContainer_Config.SplitterDistance = 318;
|
||||
splitContainer_Config.SplitterWidth = 8;
|
||||
splitContainer_Config.TabIndex = 0;
|
||||
//
|
||||
@@ -439,7 +456,7 @@
|
||||
groupBox_PreviewConfig.Location = new Point(0, 0);
|
||||
groupBox_PreviewConfig.Margin = new Padding(0);
|
||||
groupBox_PreviewConfig.Name = "groupBox_PreviewConfig";
|
||||
groupBox_PreviewConfig.Size = new Size(429, 324);
|
||||
groupBox_PreviewConfig.Size = new Size(429, 318);
|
||||
groupBox_PreviewConfig.TabIndex = 1;
|
||||
groupBox_PreviewConfig.TabStop = false;
|
||||
groupBox_PreviewConfig.Text = "画面参数";
|
||||
@@ -450,10 +467,9 @@
|
||||
propertyGrid_Previewer.HelpVisible = false;
|
||||
propertyGrid_Previewer.Location = new Point(3, 26);
|
||||
propertyGrid_Previewer.Name = "propertyGrid_Previewer";
|
||||
propertyGrid_Previewer.Size = new Size(423, 295);
|
||||
propertyGrid_Previewer.Size = new Size(423, 289);
|
||||
propertyGrid_Previewer.TabIndex = 1;
|
||||
propertyGrid_Previewer.ToolbarVisible = false;
|
||||
propertyGrid_Previewer.PropertyValueChanged += propertyGrid_PropertyValueChanged;
|
||||
//
|
||||
// groupBox_SkelConfig
|
||||
//
|
||||
@@ -462,7 +478,7 @@
|
||||
groupBox_SkelConfig.Location = new Point(0, 0);
|
||||
groupBox_SkelConfig.Margin = new Padding(0);
|
||||
groupBox_SkelConfig.Name = "groupBox_SkelConfig";
|
||||
groupBox_SkelConfig.Size = new Size(429, 615);
|
||||
groupBox_SkelConfig.Size = new Size(429, 609);
|
||||
groupBox_SkelConfig.TabIndex = 0;
|
||||
groupBox_SkelConfig.TabStop = false;
|
||||
groupBox_SkelConfig.Text = "模型参数";
|
||||
@@ -473,18 +489,18 @@
|
||||
groupBox_Preview.Dock = DockStyle.Fill;
|
||||
groupBox_Preview.Location = new Point(0, 0);
|
||||
groupBox_Preview.Name = "groupBox_Preview";
|
||||
groupBox_Preview.Size = new Size(962, 947);
|
||||
groupBox_Preview.Size = new Size(962, 935);
|
||||
groupBox_Preview.TabIndex = 1;
|
||||
groupBox_Preview.TabStop = false;
|
||||
groupBox_Preview.Text = "预览画面";
|
||||
//
|
||||
// spinePreviewer
|
||||
// spinePreviewPanel
|
||||
//
|
||||
spinePreviewPanel.Dock = DockStyle.Fill;
|
||||
spinePreviewPanel.Location = new Point(3, 26);
|
||||
spinePreviewPanel.Name = "spinePreviewer";
|
||||
spinePreviewPanel.Name = "spinePreviewPanel";
|
||||
spinePreviewPanel.PropertyGrid = propertyGrid_Previewer;
|
||||
spinePreviewPanel.Size = new Size(956, 918);
|
||||
spinePreviewPanel.Size = new Size(956, 906);
|
||||
spinePreviewPanel.SpineListView = spineListView;
|
||||
spinePreviewPanel.TabIndex = 0;
|
||||
//
|
||||
@@ -502,6 +518,13 @@
|
||||
//
|
||||
toolTip.ShowAlways = true;
|
||||
//
|
||||
// toolStripMenuItem_Debug
|
||||
//
|
||||
toolStripMenuItem_Debug.Name = "toolStripMenuItem_Debug";
|
||||
toolStripMenuItem_Debug.Size = new Size(270, 34);
|
||||
toolStripMenuItem_Debug.Text = "调试";
|
||||
toolStripMenuItem_Debug.Visible = false;
|
||||
//
|
||||
// SpineViewerForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(144F, 144F);
|
||||
@@ -590,5 +613,8 @@
|
||||
private ToolStripSeparator toolStripSeparator5;
|
||||
private ToolStripSeparator toolStripSeparator6;
|
||||
private SplitContainer splitContainer_Config;
|
||||
private ToolStripMenuItem toolStripMenuItem_Experiment;
|
||||
private ToolStripMenuItem toolStripMenuItem_DesktopProjection;
|
||||
private ToolStripMenuItem toolStripMenuItem_Debug;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace SpineViewer
|
||||
MessagePopup.Warn("Fragment shader 加载失败,预乘Alpha通道属性失效");
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
toolStripMenuItem_Debug.Visible = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -336,12 +339,6 @@ namespace SpineViewer
|
||||
|
||||
private void splitContainer_MouseUp(object sender, MouseEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void propertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
|
||||
{
|
||||
// 用来解决对面板某些值修改之后, 其他被联动修改的值不会实时刷新的问题
|
||||
(sender as PropertyGrid)?.Refresh();
|
||||
}
|
||||
|
||||
private void Export_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = (BackgroundWorker)sender;
|
||||
@@ -395,7 +392,7 @@ namespace SpineViewer
|
||||
}
|
||||
var root = srcCvter.Read(skelPath);
|
||||
root = srcCvter.ToVersion(root, args.TargetVersion);
|
||||
if (args.JsonTarget) tgtCvter.WriteJson(root, newPath);
|
||||
if (args.JsonTarget) tgtCvter.WriteJson(root, newPath);
|
||||
else tgtCvter.WriteBinary(root, newPath);
|
||||
success++;
|
||||
}
|
||||
@@ -419,48 +416,30 @@ namespace SpineViewer
|
||||
}
|
||||
}
|
||||
|
||||
//private System.Windows.Forms.Timer timer = new();
|
||||
//private PetForm pet = new PetForm();
|
||||
//private IntPtr screenDC;
|
||||
//private IntPtr memDC;
|
||||
//private void _Test()
|
||||
//{
|
||||
// screenDC = Win32.GetDC(IntPtr.Zero);
|
||||
// memDC = Win32.CreateCompatibleDC(screenDC);
|
||||
// pet.Show();
|
||||
// timer.Tick += Timer_Tick;
|
||||
// timer.Enabled = true;
|
||||
// timer.Interval = 50;
|
||||
// timer.Start();
|
||||
//}
|
||||
private void toolStripMenuItem_DesktopProjection_Click(object sender, EventArgs e)
|
||||
{
|
||||
toolStripMenuItem_DesktopProjection.Checked = !toolStripMenuItem_DesktopProjection.Checked;
|
||||
spinePreviewPanel.EnableDesktopProjection = toolStripMenuItem_DesktopProjection.Checked;
|
||||
}
|
||||
|
||||
//private void Timer_Tick(object? sender, EventArgs e)
|
||||
//{
|
||||
// using var tex = new SFML.Graphics.RenderTexture((uint)pet.Width, (uint)pet.Height);
|
||||
// var v = spinePreviewer.GetView();
|
||||
// tex.SetView(v);
|
||||
// tex.Clear(new SFML.Graphics.Color(0, 0, 0, 0));
|
||||
// lock (spineListView.Spines)
|
||||
// {
|
||||
// foreach (var sp in spineListView.Spines)
|
||||
// tex.Draw(sp);
|
||||
// }
|
||||
// tex.Display();
|
||||
// using var frame = new SFMLImageVideoFrame(tex.Texture.CopyToImage());
|
||||
// using var bitmap = frame.CopyToBitmap();
|
||||
private void toolStripMenuItem_Debug_Click(object sender, EventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||
//var root = cvt.ReadBinary(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3 - 副本.skel");
|
||||
//cvt.WriteJson(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||
|
||||
// var newBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
|
||||
// var oldBitmap = Win32.SelectObject(memDC, newBitmap);
|
||||
//root = cvt.ReadJson(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||
//cvt.WriteBinary(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||
|
||||
// Win32.SIZE size = new Win32.SIZE { cx = pet.Width, cy = pet.Height };
|
||||
// Win32.POINT srcPos = new Win32.POINT { x = 0, y = 0 };
|
||||
// Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION { BlendOp = 0, BlendFlags = 0, SourceConstantAlpha = 255, AlphaFormat = Win32.AC_SRC_ALPHA };
|
||||
|
||||
// Win32.UpdateLayeredWindow(pet.Handle, screenDC, IntPtr.Zero, ref size, memDC, ref srcPos, 0, ref blend, Win32.ULW_ALPHA);
|
||||
|
||||
// Win32.SelectObject(memDC, oldBitmap);
|
||||
// Win32.DeleteObject(newBitmap);
|
||||
//}
|
||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||
//var root = cvt.ReadJson(@"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.json");
|
||||
//cvt.WriteBinary(root, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||
//_Test();
|
||||
#endif
|
||||
}
|
||||
|
||||
//private void spinePreviewer_KeyDown(object sender, KeyEventArgs e)
|
||||
//{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace SpineViewer
|
||||
{
|
||||
partial class PetForm
|
||||
partial class WallpaperForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -30,18 +30,19 @@
|
||||
{
|
||||
SuspendLayout();
|
||||
//
|
||||
// PetForm
|
||||
// WallpaperForm
|
||||
//
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
ClientSize = new Size(490, 456);
|
||||
ClientSize = new Size(512, 512);
|
||||
ControlBox = false;
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "PetForm";
|
||||
Name = "WallpaperForm";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
Text = "PetForm";
|
||||
WindowState = FormWindowState.Minimized;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
73
SpineViewer/Forms/WallpaperForm.cs
Normal file
73
SpineViewer/Forms/WallpaperForm.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using SpineViewer.Natives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
[ToolboxItem(true)]
|
||||
[Designer(typeof(ComponentDesigner), typeof(IDesigner))]
|
||||
[DesignTimeVisible(true)]
|
||||
public partial class WallpaperForm: Form
|
||||
{
|
||||
public WallpaperForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
var cp = base.CreateParams;
|
||||
cp.ExStyle = Win32.WS_EX_TOOLWINDOW | Win32.WS_EX_LAYERED;
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
// 设置成嵌入桌面
|
||||
var progman = Win32.FindWindow("Progman", null);
|
||||
if (progman != IntPtr.Zero)
|
||||
{
|
||||
// 确保 WorkerW 被创建
|
||||
Win32.SendMessageTimeout(progman, Win32.WM_SPAWN_WORKER, IntPtr.Zero, IntPtr.Zero, Win32.SMTO_NORMAL, 1000, out _);
|
||||
var workerW = Win32.GetWorkerW();
|
||||
if (workerW != IntPtr.Zero)
|
||||
{
|
||||
Win32.SetLayeredWindowAttributes(Handle, 0, 255, Win32.LWA_ALPHA);
|
||||
Win32.SetParent(Handle, workerW); // 嵌入之前必须保证有 WS_EX_LAYERED 标志
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public byte LayeredWindowAlpha
|
||||
{
|
||||
get
|
||||
{
|
||||
uint crKey = 0;
|
||||
byte bAlpha = 255;
|
||||
uint dwFlags = Win32.LWA_ALPHA;
|
||||
Win32.GetLayeredWindowAttributes(Handle, ref crKey, ref bAlpha, ref dwFlags);
|
||||
return bAlpha;
|
||||
}
|
||||
set
|
||||
{
|
||||
Win32.SetLayeredWindowAttributes(Handle, 0, value, Win32.LWA_ALPHA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
SpineViewer/Forms/WallpaperForm.resx
Normal file
120
SpineViewer/Forms/WallpaperForm.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -17,6 +17,8 @@ namespace SpineViewer.Natives
|
||||
public const int GWL_STYLE = -16;
|
||||
public const int WS_SIZEBOX = 0x40000;
|
||||
public const int WS_BORDER = 0x800000;
|
||||
public const int WS_VISIBLE = 0x10000000;
|
||||
public const int WS_CHILD = 0x40000000;
|
||||
public const int WS_POPUP = unchecked((int)0x80000000);
|
||||
|
||||
public const int GWL_EXSTYLE = -20;
|
||||
@@ -25,8 +27,10 @@ namespace SpineViewer.Natives
|
||||
public const int WS_EX_TOOLWINDOW = 0x80;
|
||||
public const int WS_EX_WINDOWEDGE = 0x100;
|
||||
public const int WS_EX_CLIENTEDGE = 0x200;
|
||||
public const int WS_EX_APPWINDOW = 0x40000;
|
||||
public const int WS_EX_LAYERED = 0x80000;
|
||||
public const int WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE;
|
||||
public const int WS_EX_NOACTIVATE = 0x8000000;
|
||||
|
||||
public const uint LWA_COLORKEY = 0x1;
|
||||
public const uint LWA_ALPHA = 0x2;
|
||||
@@ -44,7 +48,6 @@ namespace SpineViewer.Natives
|
||||
public const uint SWP_NOMOVE = 0x0002;
|
||||
public const uint SWP_NOZORDER = 0x0004;
|
||||
public const uint SWP_FRAMECHANGED = 0x0020;
|
||||
public const uint SWP_REFRESHLONG = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED;
|
||||
|
||||
public const int WM_SPAWN_WORKER = 0x052C; // 一个未公开的神秘消息
|
||||
|
||||
@@ -170,7 +173,7 @@ namespace SpineViewer.Natives
|
||||
if (progman == nint.Zero)
|
||||
return nint.Zero;
|
||||
nint hWnd = FindWindowEx(progman, 0, "WorkerW", null);
|
||||
Debug.WriteLine($"{hWnd:x8}");
|
||||
Debug.WriteLine($"HWND(Progman.WorkerW): {hWnd:x8}");
|
||||
return hWnd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -199,7 +199,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
// XXX: 3.7 及以下不支持 AddSkin
|
||||
foreach (var (k, v) in sk.Attachments)
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -122,68 +122,42 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override float scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
get => Math.Abs(skeleton.ScaleX);
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var pos = position;
|
||||
var fX = flipX;
|
||||
var fY = flipY;
|
||||
var animations = animationState.Tracks.Where(te => te is not null).Select(te => te.Animation.Name).ToArray();
|
||||
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = value;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = value;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) };
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
position = pos;
|
||||
flipX = fX;
|
||||
flipY = fY;
|
||||
reloadSkins();
|
||||
for (int i = 0; i < animations.Length; i++) setAnimation(i, animations[i]);
|
||||
skeleton.ScaleX = Math.Sign(skeleton.ScaleX) * value;
|
||||
skeleton.ScaleY = Math.Sign(skeleton.ScaleY) * value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override PointF position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
protected override PointF position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool flipX
|
||||
{
|
||||
get => skeleton.FlipX;
|
||||
set => skeleton.FlipX = value;
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool flipY
|
||||
{
|
||||
get => skeleton.FlipY;
|
||||
set => skeleton.FlipY = value;
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string getSlotAttachment(string slot) => skeleton.FindSlot(slot)?.Attachment?.Name ?? EMPTY_ATTACHMENT;
|
||||
@@ -198,7 +172,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
// XXX: 3.7 及以下不支持 AddSkin
|
||||
foreach (var (k, v) in sk.Attachments)
|
||||
@@ -242,8 +217,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
var maxDuration = 0f;
|
||||
var tmpSkeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) };
|
||||
var tmpAnimationState = new AnimationState(animationStateData);
|
||||
tmpSkeleton.FlipX = skeleton.FlipX;
|
||||
tmpSkeleton.FlipY = skeleton.FlipY;
|
||||
tmpSkeleton.ScaleX = skeleton.ScaleX;
|
||||
tmpSkeleton.ScaleY = skeleton.ScaleY;
|
||||
tmpSkeleton.X = skeleton.X;
|
||||
tmpSkeleton.Y = skeleton.Y;
|
||||
foreach (var (name, _) in skinLoadStatus.Where(e => e.Value))
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -169,7 +169,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
// XXX: 3.7 及以下不支持 AddSkin
|
||||
foreach (var (k, v) in sk.Attachments)
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -176,7 +176,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
skeleton.Skin.AddSkin(sk);
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -172,7 +172,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
skeleton.Skin.AddSkin(sk);
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -172,7 +172,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
skeleton.Skin.AddSkin(sk);
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).Where(v => v != "default").ToImmutableArray();
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
@@ -172,7 +172,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
if (skeletonData.FindSkin(name) is Skin sk)
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
skeleton.Skin.AddSkin(sk);
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
|
||||
@@ -93,8 +93,8 @@ namespace SpineViewer.Spine
|
||||
tex.Display();
|
||||
Preview = tex.Texture.CopyToBitmap();
|
||||
|
||||
// 初始化皮肤加载情况
|
||||
foreach (var n in SkinNames) skinLoadStatus[n] = false;
|
||||
// 初始化皮肤加载情况, 不需要记录 default
|
||||
foreach (var n in SkinNames.Where(v => v != "default")) skinLoadStatus[n] = false;
|
||||
|
||||
// 默认初始化10个动画空位
|
||||
for (int i = 0; i < 10; i++) setAnimation(i, AnimationNames.First());
|
||||
@@ -359,7 +359,7 @@ namespace SpineViewer.Spine
|
||||
/// <summary>
|
||||
/// 查询皮肤加载状态, 皮肤不存在时返回 false
|
||||
/// </summary>
|
||||
public bool GetSkinStatus(string name) { lock (_lock) return skinLoadStatus.TryGetValue(name, out var status) && status; }
|
||||
public bool GetSkinStatus(string name) { lock (_lock) return name == "default" || skinLoadStatus.TryGetValue(name, out var status) && status; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置皮肤加载状态, 忽略不存在的皮肤
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace SpineViewer.Spine.SpineView
|
||||
private class SkinPropertyDescriptor(string name, Attribute[]? attributes) : PropertyDescriptor(name, attributes)
|
||||
{
|
||||
public override Type ComponentType => typeof(SpineSkinProperty);
|
||||
public override bool IsReadOnly => false;
|
||||
public override bool IsReadOnly => Name == "default";
|
||||
public override Type PropertyType => typeof(bool);
|
||||
public override bool CanResetValue(object component) => false;
|
||||
public override void ResetValue(object component) { }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.12.5</Version>
|
||||
<Version>0.12.6</Version>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace SpineViewer.Utils
|
||||
}
|
||||
}
|
||||
|
||||
private StandardValuesCollection standardValues;
|
||||
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
|
||||
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context)
|
||||
@@ -89,29 +91,77 @@ namespace SpineViewer.Utils
|
||||
|
||||
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context)
|
||||
{
|
||||
// 查找属性上的 StandardValuesAttribute
|
||||
var attribute = context?.PropertyDescriptor?.Attributes.OfType<StandardValuesAttribute>().FirstOrDefault();
|
||||
StandardValuesCollection result;
|
||||
if (attribute != null)
|
||||
result = new StandardValuesCollection(attribute.StandardValues);
|
||||
else
|
||||
result = new StandardValuesCollection(Array.Empty<string>());
|
||||
return result;
|
||||
if (standardValues is null)
|
||||
{
|
||||
// 查找属性上的 StandardValuesAttribute
|
||||
var attribute = context?.PropertyDescriptor?.Attributes.OfType<StandardValuesAttribute>().FirstOrDefault();
|
||||
if (attribute != null)
|
||||
standardValues = new StandardValuesCollection(attribute.StandardValues);
|
||||
else
|
||||
standardValues = new StandardValuesCollection(Array.Empty<string>());
|
||||
}
|
||||
return standardValues;
|
||||
}
|
||||
}
|
||||
|
||||
public class ResolutionConverter : SizeConverter
|
||||
{
|
||||
private static readonly StandardValuesCollection standardValues = new(new Size[] {
|
||||
new(4096, 4096),
|
||||
new(2048, 2048),
|
||||
new(1024, 1024),
|
||||
new(512, 512),
|
||||
new(3840, 2160),
|
||||
new(2560, 1440),
|
||||
new(1920, 1080),
|
||||
new(1280, 720),
|
||||
new(2160, 3840),
|
||||
new(1440, 2560),
|
||||
new(1080, 1920),
|
||||
new(720, 1280),
|
||||
});
|
||||
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => false;
|
||||
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) => standardValues;
|
||||
}
|
||||
|
||||
public class SFMLColorConverter : ExpandableObjectConverter
|
||||
{
|
||||
private class SFMLColorPropertyDescriptor : SimplePropertyDescriptor
|
||||
private static SFML.Graphics.Color ParseHexColor(string hex, bool includeAlpha)
|
||||
{
|
||||
public SFMLColorPropertyDescriptor(Type componentType, string name, Type propertyType) : base(componentType, name, propertyType) { }
|
||||
|
||||
public override object? GetValue(object? component) => component?.GetType().GetField(Name)?.GetValue(component) ?? default;
|
||||
|
||||
public override void SetValue(object? component, object? value) => component?.GetType().GetField(Name)?.SetValue(component, value);
|
||||
byte r = byte.Parse(hex.Substring(1, 2), NumberStyles.HexNumber);
|
||||
byte g = byte.Parse(hex.Substring(3, 2), NumberStyles.HexNumber);
|
||||
byte b = byte.Parse(hex.Substring(5, 2), NumberStyles.HexNumber);
|
||||
byte a = includeAlpha ? byte.Parse(hex.Substring(7, 2), NumberStyles.HexNumber) : (byte)255;
|
||||
return new SFML.Graphics.Color(r, g, b, a);
|
||||
}
|
||||
|
||||
private static PropertyDescriptorCollection pdCollection = null;
|
||||
private static SFML.Graphics.Color ParseShortHexColor(string hex, bool includeAlpha)
|
||||
{
|
||||
byte r = Convert.ToByte($"{hex[1]}{hex[1]}", 16);
|
||||
byte g = Convert.ToByte($"{hex[2]}{hex[2]}", 16);
|
||||
byte b = Convert.ToByte($"{hex[3]}{hex[3]}", 16);
|
||||
byte a = includeAlpha ? Convert.ToByte($"{hex[4]}{hex[4]}", 16) : (byte)255;
|
||||
return new SFML.Graphics.Color(r, g, b, a);
|
||||
}
|
||||
|
||||
private static readonly StandardValuesCollection standardValues;
|
||||
|
||||
static SFMLColorConverter()
|
||||
{
|
||||
// 初始化所有 KnownColor
|
||||
var knownColors = Enum.GetValues(typeof(KnownColor))
|
||||
.Cast<KnownColor>()
|
||||
.Select(knownColor =>
|
||||
{
|
||||
var color = Color.FromKnownColor(knownColor);
|
||||
return new SFML.Graphics.Color(color.R, color.G, color.B, color.A);
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
standardValues = new StandardValuesCollection(knownColors);
|
||||
}
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
|
||||
{
|
||||
@@ -123,24 +173,48 @@ namespace SpineViewer.Utils
|
||||
if (value is string s)
|
||||
{
|
||||
s = s.Trim();
|
||||
if (s.StartsWith("#") && s.Length == 9)
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
// 处理 #RRGGBBAA 和 #RRGGBB 格式
|
||||
if (s.StartsWith("#"))
|
||||
{
|
||||
// 解析 R, G, B, A 分量,注意16进制解析
|
||||
byte r = byte.Parse(s.Substring(1, 2), NumberStyles.HexNumber);
|
||||
byte g = byte.Parse(s.Substring(3, 2), NumberStyles.HexNumber);
|
||||
byte b = byte.Parse(s.Substring(5, 2), NumberStyles.HexNumber);
|
||||
byte a = byte.Parse(s.Substring(7, 2), NumberStyles.HexNumber);
|
||||
if (s.Length == 9) // #RRGGBBAA
|
||||
return ParseHexColor(s, includeAlpha: true);
|
||||
if (s.Length == 7) // #RRGGBB
|
||||
return ParseHexColor(s, includeAlpha: false);
|
||||
if (s.Length == 5) // #RGBA
|
||||
return ParseShortHexColor(s, includeAlpha: true);
|
||||
if (s.Length == 4) // #RGB
|
||||
return ParseShortHexColor(s, includeAlpha: false);
|
||||
|
||||
throw new FormatException("无法解析颜色,请使用 #RRGGBBAA、#RRGGBB、#RGBA 或 #RGB 格式");
|
||||
}
|
||||
|
||||
// 处理 R,G,B,A 和 R,G,B 格式
|
||||
var parts = s.Split(',');
|
||||
if (parts.Length == 3 || parts.Length == 4)
|
||||
{
|
||||
byte r = byte.Parse(parts[0].Trim());
|
||||
byte g = byte.Parse(parts[1].Trim());
|
||||
byte b = byte.Parse(parts[2].Trim());
|
||||
byte a = parts.Length == 4 ? byte.Parse(parts[3].Trim()) : (byte)255;
|
||||
return new SFML.Graphics.Color(r, g, b, a);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new FormatException("无法解析颜色,确保格式为 #RRGGBBAA", ex);
|
||||
}
|
||||
|
||||
// 尝试解析为 KnownColor
|
||||
var color = Color.FromName(s);
|
||||
if (color.IsKnownColor || color.IsNamedColor)
|
||||
return new SFML.Graphics.Color(color.R, color.G, color.B, color.A);
|
||||
|
||||
throw new FormatException("无法解析颜色,请使用已知的颜色名称");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new FormatException("无法解析颜色,请检查格式", ex);
|
||||
}
|
||||
throw new FormatException("格式错误,正确格式为 #RRGGBBAA");
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
||||
@@ -156,6 +230,21 @@ namespace SpineViewer.Utils
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => false;
|
||||
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) => standardValues;
|
||||
|
||||
private class SFMLColorPropertyDescriptor : SimplePropertyDescriptor
|
||||
{
|
||||
public SFMLColorPropertyDescriptor(Type componentType, string name, Type propertyType) : base(componentType, name, propertyType) { }
|
||||
|
||||
public override object? GetValue(object? component) => component?.GetType().GetField(Name)?.GetValue(component) ?? default;
|
||||
|
||||
public override void SetValue(object? component, object? value) => component?.GetType().GetField(Name)?.SetValue(component, value);
|
||||
}
|
||||
|
||||
private static PropertyDescriptorCollection pdCollection = null;
|
||||
|
||||
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext? context, object value, Attribute[]? attributes)
|
||||
{
|
||||
pdCollection ??= new(
|
||||
|
||||
Reference in New Issue
Block a user