From 5fc933ef555c015fae3514b227ec4a14ae8c89d1 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Tue, 13 Sep 2022 08:02:35 +0800 Subject: [PATCH 01/30] auto dpi --- V3_CN.md | 2 +- V3_EN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/V3_CN.md b/V3_CN.md index 784cc3c..b33f41a 100644 --- a/V3_CN.md +++ b/V3_CN.md @@ -4,7 +4,7 @@ `修复已知bug` -`增加高DPI支持` +(2022-09-12)`增加高DPI支持` `添加json格式序列化文件` diff --git a/V3_EN.md b/V3_EN.md index 0b42463..8e6489b 100644 --- a/V3_EN.md +++ b/V3_EN.md @@ -4,7 +4,7 @@ Although there are not many users, thanks to those who have been using `STNodeEd `Fix known bugs` -`Add high DPI support` +(2022-09-12)`Add high DPI support` `Add json format serialization file` From 532d806f32d5c5e40e9798c0e296e76a3cdd34a0 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Thu, 22 Sep 2022 01:08:10 +0800 Subject: [PATCH 02/30] update --- V3_CN.md | 57 ++++++++++++++++++++++---------------------------------- V3_EN.md | 48 +++++++++++++++++++++++------------------------ 2 files changed, 45 insertions(+), 60 deletions(-) diff --git a/V3_CN.md b/V3_CN.md index b33f41a..5a470e9 100644 --- a/V3_CN.md +++ b/V3_CN.md @@ -2,44 +2,31 @@ 虽然用户量不多,但是感谢那些一直在使用`STNodeEditor`的用户,在他们那里作者得到了一些反馈。将做如下调整: -`修复已知bug` - -(2022-09-12)`增加高DPI支持` - -`添加json格式序列化文件` - -`添加缩略图` - -`节点选项悬浮提示信息` - +|内容|状态|完成时间|备注| +|:---|:---|:---|:---| +|增加高DPI支持 |✅ |2022-09-12|-| +|添加json格式序列化文件 |☑️ |-|-| +|添加缩略图 |☑️ |-|-| +|节点选项悬浮提示信息 |☑️ |-|-| +|修复已知bug |☑️ |-|-| 添加控件支持: -`Panel` - -`lable` - -`button` - -`textbox` - -`listview` - -`chekcbox` - -`radiobutton` - -`combobox` - -`groupbox` - -`picturebox` - -`progressbar` - -`trackbar` - -`NumericUpDown` +|内容|状态|完成时间|备注| +|:---|:---|:---|:---| +|Panel |☑️ |-|-| +|lable |☑️ |-|-| +|button |☑️ |-|-| +|textbox |☑️ |-|-| +|listview |☑️ |-|-| +|chekcbox |☑️ |-|-| +|radiobutton |☑️ |-|-| +|combobox |☑️ |-|-| +|groupbox |☑️ |-|-| +|picturebox |☑️ |-|-| +|progressbar |☑️ |-|-| +|trackbar |☑️ |-|-| +|NumericUpDown |☑️ |-|-| 控件将尽可能保持`WinForm`的使用习惯。 diff --git a/V3_EN.md b/V3_EN.md index 8e6489b..d4d39c4 100644 --- a/V3_EN.md +++ b/V3_EN.md @@ -2,6 +2,14 @@ Since the `3.0` version may be partially refactored, it was decided to start a n Although there are not many users, thanks to those who have been using `STNodeEditor`, where the author got some feedback. The following adjustments will be made: +|Items|Status|Complete time|Note| +|:---|:---|:---|:---| +|Add high DPI support |✅ |2022-09-12|-| +|Add json format serialization file |☑️ |-|-| +|Add mini-map |☑️ |-|-| +|Node option hover hint text |☑️ |-|-| +|Add mini-map |☑️ |-|-| + `Fix known bugs` (2022-09-12)`Add high DPI support` @@ -15,31 +23,21 @@ Although there are not many users, thanks to those who have been using `STNodeEd Add Controls: -`Panel` - -`lable` - -`button` - -`textbox` - -`listview` - -`chekcbox` - -`radiobutton` - -`combobox` - -`groupbox` - -`picturebox` - -`progressbar` - -`trackbar` - -`NumericUpDown` +|Items|Status|Complete time|Note| +|:---|:---|:---|:---| +|Panel |☑️ |-|-| +|lable |☑️ |-|-| +|button |☑️ |-|-| +|textbox |☑️ |-|-| +|listview |☑️ |-|-| +|chekcbox |☑️ |-|-| +|radiobutton |☑️ |-|-| +|combobox |☑️ |-|-| +|groupbox |☑️ |-|-| +|picturebox |☑️ |-|-| +|progressbar |☑️ |-|-| +|trackbar |☑️ |-|-| +|NumericUpDown |☑️ |-|-| Controls will maintain the `WinForm` usage habits as much as possible. From f55e6e129b8fe4828c2a4bbdc5b344b9000fbca2 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Thu, 22 Sep 2022 01:14:07 +0800 Subject: [PATCH 03/30] update --- V3_CN.md | 2 +- V3_EN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/V3_CN.md b/V3_CN.md index 5a470e9..464e08b 100644 --- a/V3_CN.md +++ b/V3_CN.md @@ -5,7 +5,7 @@ |内容|状态|完成时间|备注| |:---|:---|:---|:---| |增加高DPI支持 |✅ |2022-09-12|-| -|添加json格式序列化文件 |☑️ |-|-| +|添加json格式序列化文件 |☑️ |-|已经完成`STJson`项目| |添加缩略图 |☑️ |-|-| |节点选项悬浮提示信息 |☑️ |-|-| |修复已知bug |☑️ |-|-| diff --git a/V3_EN.md b/V3_EN.md index d4d39c4..6f35c26 100644 --- a/V3_EN.md +++ b/V3_EN.md @@ -5,7 +5,7 @@ Although there are not many users, thanks to those who have been using `STNodeEd |Items|Status|Complete time|Note| |:---|:---|:---|:---| |Add high DPI support |✅ |2022-09-12|-| -|Add json format serialization file |☑️ |-|-| +|Add json format serialization file |☑️ |-|`STJson`Project was completed| |Add mini-map |☑️ |-|-| |Node option hover hint text |☑️ |-|-| |Add mini-map |☑️ |-|-| From 6b75cea71f0260b38a2951b6ba1991bf8f2383a1 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Thu, 22 Sep 2022 01:17:13 +0800 Subject: [PATCH 04/30] update --- V3_EN.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/V3_EN.md b/V3_EN.md index 6f35c26..f477a78 100644 --- a/V3_EN.md +++ b/V3_EN.md @@ -10,17 +10,6 @@ Although there are not many users, thanks to those who have been using `STNodeEd |Node option hover hint text |☑️ |-|-| |Add mini-map |☑️ |-|-| -`Fix known bugs` - -(2022-09-12)`Add high DPI support` - -`Add json format serialization file` - -`Add mini-map` - -`Node option hover hint text` - - Add Controls: |Items|Status|Complete time|Note| From 359c9a12bde4b275b4cd4bf1ef2d8c629d0397a2 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Thu, 22 Sep 2022 22:34:41 +0800 Subject: [PATCH 05/30] update --- V3_CN.md | 4 ++-- V3_EN.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/V3_CN.md b/V3_CN.md index 464e08b..c2d2e19 100644 --- a/V3_CN.md +++ b/V3_CN.md @@ -4,8 +4,8 @@ |内容|状态|完成时间|备注| |:---|:---|:---|:---| -|增加高DPI支持 |✅ |2022-09-12|-| -|添加json格式序列化文件 |☑️ |-|已经完成`STJson`项目| +|增加高DPI支持 |✅ |2022-09-12|创建了`STGraphics`| +|添加json格式序列化文件 |☑️ |-|已经完成 [STJson(https://github.com/DebugST/STJson) 项目| |添加缩略图 |☑️ |-|-| |节点选项悬浮提示信息 |☑️ |-|-| |修复已知bug |☑️ |-|-| diff --git a/V3_EN.md b/V3_EN.md index f477a78..596c473 100644 --- a/V3_EN.md +++ b/V3_EN.md @@ -4,8 +4,8 @@ Although there are not many users, thanks to those who have been using `STNodeEd |Items|Status|Complete time|Note| |:---|:---|:---|:---| -|Add high DPI support |✅ |2022-09-12|-| -|Add json format serialization file |☑️ |-|`STJson`Project was completed| +|Add high DPI support |✅ |2022-09-12|Create `STGraphics`| +|Add json format serialization file |☑️ |-|[STJson](https://github.com/DebugST/STJson) Project was completed| |Add mini-map |☑️ |-|-| |Node option hover hint text |☑️ |-|-| |Add mini-map |☑️ |-|-| From b0e99fb148df8b4f2cdb0eccd715206cbb300919 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Thu, 22 Sep 2022 22:37:21 +0800 Subject: [PATCH 06/30] update --- V3_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/V3_CN.md b/V3_CN.md index c2d2e19..1cf2f38 100644 --- a/V3_CN.md +++ b/V3_CN.md @@ -5,7 +5,7 @@ |内容|状态|完成时间|备注| |:---|:---|:---|:---| |增加高DPI支持 |✅ |2022-09-12|创建了`STGraphics`| -|添加json格式序列化文件 |☑️ |-|已经完成 [STJson(https://github.com/DebugST/STJson) 项目| +|添加json格式序列化文件 |☑️ |-|已经完成 [STJson](https://github.com/DebugST/STJson) 项目| |添加缩略图 |☑️ |-|-| |节点选项悬浮提示信息 |☑️ |-|-| |修复已知bug |☑️ |-|-| From 77b8f77a12dd801cd1573a9459a79007872d7926 Mon Sep 17 00:00:00 2001 From: DebugST <2212233137@qq.com> Date: Mon, 17 Oct 2022 14:56:00 +0800 Subject: [PATCH 07/30] update progress --- V3_CN.md | 25 +++++++++++++------------ V3_EN.md | 17 +++++++++-------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/V3_CN.md b/V3_CN.md index 1cf2f38..e4d9725 100644 --- a/V3_CN.md +++ b/V3_CN.md @@ -4,11 +4,12 @@ |内容|状态|完成时间|备注| |:---|:---|:---|:---| -|增加高DPI支持 |✅ |2022-09-12|创建了`STGraphics`| -|添加json格式序列化文件 |☑️ |-|已经完成 [STJson](https://github.com/DebugST/STJson) 项目| -|添加缩略图 |☑️ |-|-| -|节点选项悬浮提示信息 |☑️ |-|-| -|修复已知bug |☑️ |-|-| +|增加高DPI支持 |✅ |2022-09-12|创建了 `STGraphics`| +|添加json格式序列化文件 |✅ |2022-09-30|添加新项目 [STJson](https://github.com/DebugST/STJson)| +|添加`STNodeEditorCanvas` |☑️ |开始|-| +|添加缩略图 |☑️ |-|-| +|节点选项悬浮提示信息 |☑️ |-|-| +|修复已知bug |☑️ |-|-| 添加控件支持: @@ -30,19 +31,19 @@ 控件将尽可能保持`WinForm`的使用习惯。 -添加`STNodeEditorLayer.cs` +添加`STNodeEditorCanvas.cs` 替代原本的`STNodeEditor.cs` ```cs -var layer = new STNodeEditorLayer("layer_name"); -layer.Nodes.add(new STNode_1()); -layer.Nodes.add(new STNode_2()); -STNodeEditor_1.Layer = layer; -// STNodeEditor.Layers.Add(layer) 此方式先待定 +var canvas = new STNodeEditorCanvas("layer_name"); +canvas.Nodes.add(new STNode_1()); +canvas.Nodes.add(new STNode_2()); +STNodeEditor_1.Canvas = canvas; +// STNodeEditor.Layers.Add(canvas) 此方式先待定 /* 这样做的目的是想实现类似TabControl的效果,用户可能有多个画布需要加载, - 所以他不得不添加多个STNodeEditor做切换。所以用STNodeEditorLayer代替原本的STNodeEditor + 所以他不得不添加多个STNodeEditor做切换。所以用STNodeEditorCanvas代替原本的STNodeEditor 而STNodeEditor仅仅作为一个画布容器 */ ``` diff --git a/V3_EN.md b/V3_EN.md index 596c473..8348227 100644 --- a/V3_EN.md +++ b/V3_EN.md @@ -5,7 +5,8 @@ Although there are not many users, thanks to those who have been using `STNodeEd |Items|Status|Complete time|Note| |:---|:---|:---|:---| |Add high DPI support |✅ |2022-09-12|Create `STGraphics`| -|Add json format serialization file |☑️ |-|[STJson](https://github.com/DebugST/STJson) Project was completed| +|Add json format serialization file |✅ |2022-09-30|Add new project [STJson](https://github.com/DebugST/STJson)| +|Add `STNodeEditorCanvas` |☑️ |start|-| |Add mini-map |☑️ |-|-| |Node option hover hint text |☑️ |-|-| |Add mini-map |☑️ |-|-| @@ -30,19 +31,19 @@ Add Controls: Controls will maintain the `WinForm` usage habits as much as possible. -Add `STNodeEditorLayer.cs` +Add `STNodeEditorCanvas.cs` To replace `STNodeEditor.cs` ```cs -var layer = new STNodeEditorLayer("layer_name"); -layer.Nodes.add(new STNode_1()); -layer.Nodes.add(new STNode_2()); -STNodeEditor_1.Layer = layer; -// STNodeEditor.Layers.Add(layer) This method is pending. +var canvas = new STNodeEditorCanvas("layer_name"); +canvas.Nodes.add(new STNode_1()); +canvas.Nodes.add(new STNode_2()); +STNodeEditor_1.Canvas = canvas; +// STNodeEditor.Layers.Add(canvas) This method is pending. /* The purpose of this is to achieve a TabControl-like effect, where the user may have multiple canvases to load. - So he had to add multiple STNodeEditors for switching. So use STNodeEditorLayer to replace the original STNodeEditor. + So he had to add multiple STNodeEditors for switching. So use STNodeEditorCanvas to replace the original STNodeEditor. And STNodeEditor only acts as a canvas container. */ ``` From b22e328b173065cebfd01c30ae58011bfd6f8287 Mon Sep 17 00:00:00 2001 From: DebugST <74035651+DebugST@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:18:22 +0800 Subject: [PATCH 08/30] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 11f1ade..6be7d46 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ now: 2022-08-30 The version `3.0` has been start coding,The development progress is updated synchronously. more info refer [V3_EN.md](./V3_EN.md) +2023-04-20 + +老铁们,最近问更新情况的人比较多。确实摆烂了一段时间,什么也不想做。不过现在陆陆续续回到状态了。不过在继续更新之前手里还有一个[STJson](https://github.com/DebugST/STJson)。也正是当前项目需要的。`STJson`项目也摆烂很久了。。不过这两天应该会完工了,提供了全套的`Json`解析操作包括`JsonPath`的支持。。如果有经常使用`Json`的小伙伴可以关注一下。现在已经进入最后的调试和文档教程编写阶段。。等完工后回到`STNodeEditor`的开发,并且`STNodeEditor`的数据保存也将提供`Json`格式。 + # STNodeEditor [![VS2010](https://img.shields.io/badge/Visual%20Studio-2010-blueviolet)](https://visualstudio.microsoft.com/zh-hans/vs/) [![.NET35](https://img.shields.io/badge/DotNet-3.5-blue)](https://www.microsoft.com/zh-cn/download/details.aspx?id=25150) [![NuGet](https://img.shields.io/badge/NuGet-5.9-blue)](https://www.nuget.org/packages/ST.Library.UI/) [![license](https://img.shields.io/badge/License-MIT-green)](https://github.com/DebugST/STNodeEditor/blob/main/LICENSE) From acdfcb33f6304e5c445e027fa9ceaa924c52e6d4 Mon Sep 17 00:00:00 2001 From: kostas Date: Tue, 4 Mar 2025 08:44:42 +0300 Subject: [PATCH 09/30] fix misspell (causing NPE) --- ST.Library.UI/NodeEditor/STNode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ST.Library.UI/NodeEditor/STNode.cs b/ST.Library.UI/NodeEditor/STNode.cs index 07e422a..e3e6397 100644 --- a/ST.Library.UI/NodeEditor/STNode.cs +++ b/ST.Library.UI/NodeEditor/STNode.cs @@ -974,7 +974,7 @@ protected internal virtual void OnMouseClick(MouseEventArgs e) { protected internal virtual void OnMouseWheel(MouseEventArgs e) { Point pt = e.Location; pt.Y -= this._TitleHeight; - if (m_ctrl_hover != null && m_ctrl_active.Enabled && m_ctrl_hover.Visable) { + if (m_ctrl_hover != null && m_ctrl_hover.Enabled && m_ctrl_hover.Visable) { m_ctrl_hover.OnMouseWheel(new MouseEventArgs(e.Button, e.Clicks, e.X - m_ctrl_hover.Left, pt.Y - m_ctrl_hover.Top, e.Delta)); return; } From 52c5065886c70f71a5a9d2b704c245696553a1cf Mon Sep 17 00:00:00 2001 From: xincheng Date: Tue, 13 May 2025 12:06:31 +0800 Subject: [PATCH 10/30] Add WPF Demo --- .gitignore | 368 ++++++++++++- WinNodeEditorTest.sln | 20 +- WpfNodeEdittorDemo/App.xaml | 9 + WpfNodeEdittorDemo/App.xaml.cs | 14 + WpfNodeEdittorDemo/AssemblyInfo.cs | 10 + WpfNodeEdittorDemo/AttrTestNode.cs | 108 ++++ .../Blender/BlenderMixColorNode.cs | 130 +++++ WpfNodeEdittorDemo/Blender/FrmEnumSelect.cs | 75 +++ WpfNodeEdittorDemo/Blender/STNodeCheckBox.cs | 48 ++ .../Blender/STNodeColorButton.cs | 31 ++ WpfNodeEdittorDemo/Blender/STNodeProgress.cs | 66 +++ WpfNodeEdittorDemo/Blender/STNodeSelectBox.cs | 55 ++ WpfNodeEdittorDemo/CalcNode.cs | 70 +++ WpfNodeEdittorDemo/EmptyOptionTestNode.cs | 20 + WpfNodeEdittorDemo/ImageNode/ImageBaseNode.cs | 41 ++ .../ImageNode/ImageChannelNode.cs | 87 +++ .../ImageNode/ImageInputNode.cs | 84 +++ WpfNodeEdittorDemo/MainWindow.xaml | 68 +++ WpfNodeEdittorDemo/MainWindow.xaml.cs | 262 +++++++++ .../NumberNode/NumberAddNode.cs | 73 +++ .../NumberNode/NumberInputNode.cs | 52 ++ WpfNodeEdittorDemo/NumberNode/NumberNode.cs | 25 + WpfNodeEdittorDemo/STNodeEditorHelper.cs | 514 ++++++++++++++++++ WpfNodeEdittorDemo/STNodeHub.cs | 32 ++ WpfNodeEdittorDemo/WpfNodeEdittorDemo.csproj | 22 + 25 files changed, 2278 insertions(+), 6 deletions(-) create mode 100644 WpfNodeEdittorDemo/App.xaml create mode 100644 WpfNodeEdittorDemo/App.xaml.cs create mode 100644 WpfNodeEdittorDemo/AssemblyInfo.cs create mode 100644 WpfNodeEdittorDemo/AttrTestNode.cs create mode 100644 WpfNodeEdittorDemo/Blender/BlenderMixColorNode.cs create mode 100644 WpfNodeEdittorDemo/Blender/FrmEnumSelect.cs create mode 100644 WpfNodeEdittorDemo/Blender/STNodeCheckBox.cs create mode 100644 WpfNodeEdittorDemo/Blender/STNodeColorButton.cs create mode 100644 WpfNodeEdittorDemo/Blender/STNodeProgress.cs create mode 100644 WpfNodeEdittorDemo/Blender/STNodeSelectBox.cs create mode 100644 WpfNodeEdittorDemo/CalcNode.cs create mode 100644 WpfNodeEdittorDemo/EmptyOptionTestNode.cs create mode 100644 WpfNodeEdittorDemo/ImageNode/ImageBaseNode.cs create mode 100644 WpfNodeEdittorDemo/ImageNode/ImageChannelNode.cs create mode 100644 WpfNodeEdittorDemo/ImageNode/ImageInputNode.cs create mode 100644 WpfNodeEdittorDemo/MainWindow.xaml create mode 100644 WpfNodeEdittorDemo/MainWindow.xaml.cs create mode 100644 WpfNodeEdittorDemo/NumberNode/NumberAddNode.cs create mode 100644 WpfNodeEdittorDemo/NumberNode/NumberInputNode.cs create mode 100644 WpfNodeEdittorDemo/NumberNode/NumberNode.cs create mode 100644 WpfNodeEdittorDemo/STNodeEditorHelper.cs create mode 100644 WpfNodeEdittorDemo/STNodeHub.cs create mode 100644 WpfNodeEdittorDemo/WpfNodeEdittorDemo.csproj diff --git a/.gitignore b/.gitignore index 4f95e2b..e37e314 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,364 @@ -.DS_Store -/Bin -bin/ -obj/ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +.idea/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/WinNodeEditorTest.sln b/WinNodeEditorTest.sln index aca14ba..846a9ee 100644 --- a/WinNodeEditorTest.sln +++ b/WinNodeEditorTest.sln @@ -1,10 +1,14 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.35906.104 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Library.UI", "ST.Library.UI\ST.Library.UI.csproj", "{EFFCC270-4999-4077-A543-56CCCCE92147}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinNodeEditorDemo", "WinNodeEditorDemo\WinNodeEditorDemo.csproj", "{4E1829B5-2160-48F5-ABD6-11914A6A25DD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfNodeEdittorDemo", "WpfNodeEdittorDemo\WpfNodeEdittorDemo.csproj", "{B355CF99-7494-472A-8E0E-1543236FFC88}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -35,6 +39,18 @@ Global {4E1829B5-2160-48F5-ABD6-11914A6A25DD}.Release|Mixed Platforms.Build.0 = Release|x86 {4E1829B5-2160-48F5-ABD6-11914A6A25DD}.Release|x86.ActiveCfg = Release|x86 {4E1829B5-2160-48F5-ABD6-11914A6A25DD}.Release|x86.Build.0 = Release|x86 + {B355CF99-7494-472A-8E0E-1543236FFC88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Debug|x86.ActiveCfg = Debug|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Debug|x86.Build.0 = Debug|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Release|Any CPU.Build.0 = Release|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Release|x86.ActiveCfg = Release|Any CPU + {B355CF99-7494-472A-8E0E-1543236FFC88}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/WpfNodeEdittorDemo/App.xaml b/WpfNodeEdittorDemo/App.xaml new file mode 100644 index 0000000..90ef0c3 --- /dev/null +++ b/WpfNodeEdittorDemo/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/WpfNodeEdittorDemo/App.xaml.cs b/WpfNodeEdittorDemo/App.xaml.cs new file mode 100644 index 0000000..d7e575d --- /dev/null +++ b/WpfNodeEdittorDemo/App.xaml.cs @@ -0,0 +1,14 @@ +using System.Configuration; +using System.Data; +using System.Windows; + +namespace WpfNodeEdittorDemo +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } + +} diff --git a/WpfNodeEdittorDemo/AssemblyInfo.cs b/WpfNodeEdittorDemo/AssemblyInfo.cs new file mode 100644 index 0000000..a8dc727 --- /dev/null +++ b/WpfNodeEdittorDemo/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/WpfNodeEdittorDemo/AttrTestNode.cs b/WpfNodeEdittorDemo/AttrTestNode.cs new file mode 100644 index 0000000..b9c7fd2 --- /dev/null +++ b/WpfNodeEdittorDemo/AttrTestNode.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; +using System.Drawing; +using System.Windows.Forms; + +namespace WinNodeEditorDemo +{ + [STNode("/", "Crystal_lz", "2212233137@qq.com", "www.st233.com", "关于此节点的描述信息\r\n此类为\r\nSTNodeAttribute\r\nSTNodePropertyAttribute\r\n效果演示类")] + public class AttrTestNode : STNode + { + //因为属性编辑器默认并不支持Color类型数据 所以这里重写一个描述器并指定 + [STNodeProperty("颜色", "颜色信息", DescriptorType = typeof(DescriptorForColor))] + public Color Color { get; set; } + + [STNodeProperty("整型数组", "整型数组测试")] + public int[] IntArr { get; set; } + + [STNodeProperty("布尔", "布尔类型测试")] + public bool Bool { get; set; } + + [STNodeProperty("字符串", "字符串类型测试")] + public string String { get; set; } + + [STNodeProperty("整型", "整型测试")] + public int Int { get; set; } + + [STNodeProperty("浮点数", "浮点数类型测试")] + public float Float { get; set; } + + [STNodeProperty("枚举值", "枚举类型测试 -> FormBorderStyle")] + public FormBorderStyle STYLE { get; set; } + + public AttrTestNode() { + this.String = "string"; + IntArr = new int[] { 10, 20 }; + base.InputOptions.Add("string", typeof(string), false); + base.OutputOptions.Add("string", typeof(string), false); + this.Title = "AttrTestNode"; + this.TitleColor = Color.FromArgb(200, Color.Goldenrod); + } + /// + /// 此方法为魔术方法(Magic function) + /// 若存在 static void ShowHelpInfo(string) 且此类被STNodeAttribute标记 + /// 则此方法将作为属性编辑器上 查看帮助 功能 + /// + /// 此类所在的模块所在的文件路径 + public static void ShowHelpInfo(string strFileName) { + MessageBox.Show("this is -> ShowHelpInfo(string);\r\n" + strFileName); + } + + protected override void OnOwnerChanged() { + base.OnOwnerChanged(); + if (this.Owner == null) return; + this.Owner.SetTypeColor(typeof(string), Color.Goldenrod); + } + } + /// + /// 因为属性编辑器默认并不支持Color类型数据 所以这里重写一个描述器 + /// + public class DescriptorForColor : STNodePropertyDescriptor + { + private Rectangle m_rect;//此区域用作 属性窗口上绘制颜色预览 + //当此属性在属性窗口中被确定位置时候发生 + protected override void OnSetItemLocation() { + base.OnSetItemLocation(); + Rectangle rect = base.RectangleR; + m_rect = new Rectangle(rect.Right - 25, rect.Top + 5, 19, 12); + } + //将属性值转换为字符串 属性窗口值绘制时将采用此字符串 + protected override string GetStringFromValue() { + Color clr = (Color)this.GetValue(null); + return clr.A + "," + clr.R + "," + clr.G + "," + clr.B; + } + //将属性窗口中输入的字符串转化为Color属性 当属性窗口中用户确认输入时调用 + protected override object GetValueFromString(string strText) { + string[] strClr = strText.Split(','); + return Color.FromArgb( + int.Parse(strClr[0]), //A + int.Parse(strClr[1]), //R + int.Parse(strClr[2]), //G + int.Parse(strClr[3])); //B + } + //绘制属性窗口值区域时候调用 + protected override void OnDrawValueRectangle(DrawingTools dt) { + base.OnDrawValueRectangle(dt);//先采用默认的绘制 并再绘制颜色预览 + dt.SolidBrush.Color = (Color)this.GetValue(null); + dt.Graphics.FillRectangle(dt.SolidBrush, m_rect);//填充颜色 + dt.Graphics.DrawRectangle(Pens.Black, m_rect); //绘制边框 + } + + protected override void OnMouseClick(MouseEventArgs e) { + //如果用户点击在 颜色预览区域 则弹出系统颜色对话框 + if (m_rect.Contains(e.Location)) { + ColorDialog cd = new ColorDialog(); + if (cd.ShowDialog() != DialogResult.OK) return; + this.SetValue(cd.Color, null); + this.Invalidate(); + return; + } + //否则其他区域将采用默认处理方式 弹出字符串输入框 + base.OnMouseClick(e); + } + } +} diff --git a/WpfNodeEdittorDemo/Blender/BlenderMixColorNode.cs b/WpfNodeEdittorDemo/Blender/BlenderMixColorNode.cs new file mode 100644 index 0000000..8de3399 --- /dev/null +++ b/WpfNodeEdittorDemo/Blender/BlenderMixColorNode.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; +using System.Drawing; + +namespace WinNodeEditorDemo.Blender +{ + /// + /// 此类仅仅是演示 并不包含颜色混合功能 + /// + [STNode("/Blender/", "Crystal_lz", "2212233137@qq.com", "st233.com", "this is blender mixrgb node")] + public class BlenderMixColorNode : STNode + { + private ColorMixType _MixType; + [STNodeProperty("MixType","This is MixType")] + public ColorMixType MixType { + get { return _MixType; } + set { + _MixType = value; + m_ctrl_select.Enum = value; //当属性被赋值后 对应控件状态值也应当被修改 + } + } + + private bool _Clamp; + [STNodeProperty("Clamp","This is Clamp")] + public bool Clamp { + get { return _Clamp; } + set { _Clamp = value; m_ctrl_checkbox.Checked = value; } + } + + private int _Fac = 50; + [STNodeProperty("Fac", "This is Fac")] + public int Fac { + get { return _Fac; } + set { + if (value < 0) value = 0; + if (value > 100) value = 100; + _Fac = value; m_ctrl_progess.Value = value; + } + } + + private Color _Color1 = Color.LightGray;//默认的DescriptorType不支持颜色的显示 需要扩展 + [STNodeProperty("Color1", "This is color1", DescriptorType = typeof(WinNodeEditorDemo.DescriptorForColor))] + public Color Color1 { + get { return _Color1; } + set { _Color1 = value; m_ctrl_btn_1.BackColor = value; } + } + + private Color _Color2 = Color.LightGray; + [STNodeProperty("Color2", "This is color2", DescriptorType = typeof(WinNodeEditorDemo.DescriptorForColor))] + public Color Color2 { + get { return _Color2; } + set { _Color2 = value; m_ctrl_btn_2.BackColor = value; } + } + + public enum ColorMixType { + Mix, + Value, + Color, + Hue, + Add, + Subtract + } + + private STNodeSelectEnumBox m_ctrl_select; //自定义控件 + private STNodeProgress m_ctrl_progess; + private STNodeCheckBox m_ctrl_checkbox; + private STNodeColorButton m_ctrl_btn_1; + private STNodeColorButton m_ctrl_btn_2; + + protected override void OnCreate() { + base.OnCreate(); + this.TitleColor = Color.FromArgb(200, Color.DarkKhaki); + this.Title = "MixRGB"; + this.AutoSize = false; + this.Size = new Size(140, 142); + + this.OutputOptions.Add("Color", typeof(Color), true); + + this.InputOptions.Add(STNodeOption.Empty); //空白节点 仅站位 不参与绘制与事件触发 + this.InputOptions.Add(STNodeOption.Empty); + this.InputOptions.Add(STNodeOption.Empty); + this.InputOptions.Add("", typeof(float), true); + this.InputOptions.Add("Color1", typeof(Color), true); + this.InputOptions.Add("Color2", typeof(Color), true); + + m_ctrl_progess = new STNodeProgress(); //创建控件并添加到节点中 + m_ctrl_progess.Text = "Fac"; + m_ctrl_progess.DisplayRectangle = new Rectangle(10, 61, 120, 18); + m_ctrl_progess.ValueChanged += (s, e) => this._Fac = m_ctrl_progess.Value; + this.Controls.Add(m_ctrl_progess); + + m_ctrl_checkbox = new STNodeCheckBox(); + m_ctrl_checkbox.Text = "Clamp"; + m_ctrl_checkbox.DisplayRectangle = new Rectangle(10, 40, 120, 20); + m_ctrl_checkbox.ValueChanged += (s, e) => this._Clamp = m_ctrl_checkbox.Checked; + this.Controls.Add(m_ctrl_checkbox); + + m_ctrl_btn_1 = new STNodeColorButton(); + m_ctrl_btn_1.Text = ""; + m_ctrl_btn_1.BackColor = this._Color1; + m_ctrl_btn_1.DisplayRectangle = new Rectangle(80, 82, 50, 16); + m_ctrl_btn_1.ValueChanged += (s, e) => this._Color1 = m_ctrl_btn_1.BackColor; + this.Controls.Add(m_ctrl_btn_1); + + m_ctrl_btn_2 = new STNodeColorButton(); + m_ctrl_btn_2.Text = ""; + m_ctrl_btn_2.BackColor = this._Color2; + m_ctrl_btn_2.DisplayRectangle = new Rectangle(80, 102, 50, 16); + m_ctrl_btn_2.ValueChanged += (s, e) => this._Color2 = m_ctrl_btn_2.BackColor; + this.Controls.Add(m_ctrl_btn_2); + + m_ctrl_select = new STNodeSelectEnumBox(); + m_ctrl_select.DisplayRectangle = new Rectangle(10, 21, 120, 18); + m_ctrl_select.Enum = this._MixType; + m_ctrl_select.ValueChanged += (s, e) => this._MixType = (ColorMixType)m_ctrl_select.Enum; + this.Controls.Add(m_ctrl_select); + } + + protected override void OnOwnerChanged() { //当控件被添加时候 向编辑器提交自己的数据类型希望显示的颜色 + base.OnOwnerChanged(); + if (this.Owner == null) return; + this.Owner.SetTypeColor(typeof(float), Color.Gray); + this.Owner.SetTypeColor(typeof(Color), Color.Yellow); + } + } +} diff --git a/WpfNodeEdittorDemo/Blender/FrmEnumSelect.cs b/WpfNodeEdittorDemo/Blender/FrmEnumSelect.cs new file mode 100644 index 0000000..3c8e87f --- /dev/null +++ b/WpfNodeEdittorDemo/Blender/FrmEnumSelect.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Drawing; +using System.Windows.Forms; + +namespace WinNodeEditorDemo.Blender +{ + /// + /// 此类仅演示 作为MixRGB节点的下拉选择框弹出菜单 + /// + public class FrmEnumSelect : Form + { + private Point m_pt; + private int m_nWidth; + private float m_scale; + private List m_lst = new List(); + private StringFormat m_sf; + + public Enum Enum { get; set; } + + private bool m_bClosed; + + public FrmEnumSelect(Enum e, Point pt, int nWidth, float scale) { + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + foreach (var v in Enum.GetValues(e.GetType())) m_lst.Add(v); + this.Enum = e; + m_pt = pt; + m_scale = scale; + m_nWidth = nWidth; + m_sf = new StringFormat(); + m_sf.LineAlignment = StringAlignment.Center; + + this.ShowInTaskbar = false; + this.BackColor = Color.FromArgb(255, 34, 34, 34); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + } + + protected override void OnLoad(EventArgs e) { + base.OnLoad(e); + this.Location = m_pt; + this.Width = (int)(m_nWidth * m_scale); + this.Height = (int)(m_lst.Count * 20 * m_scale); + } + + protected override void OnPaint(PaintEventArgs e) { + base.OnPaint(e); + Graphics g = e.Graphics; + g.ScaleTransform(m_scale, m_scale); + Rectangle rect = new Rectangle(0, 0, this.Width, 20); + foreach (var v in m_lst) { + g.DrawString(v.ToString(), this.Font, Brushes.White, rect, m_sf); + rect.Y += rect.Height; + } + } + + protected override void OnMouseClick(MouseEventArgs e) { + base.OnMouseClick(e); + int nIndex = e.Y / (int)(20 * m_scale); + if (nIndex >= 0 && nIndex < m_lst.Count) this.Enum = (Enum)m_lst[nIndex]; + this.DialogResult = System.Windows.Forms.DialogResult.OK; + m_bClosed = true; + } + + protected override void OnMouseLeave(EventArgs e) { + base.OnMouseLeave(e); + if (m_bClosed) return; + //this.DialogResult = System.Windows.Forms.DialogResult.None; + this.Close(); + } + } +} diff --git a/WpfNodeEdittorDemo/Blender/STNodeCheckBox.cs b/WpfNodeEdittorDemo/Blender/STNodeCheckBox.cs new file mode 100644 index 0000000..db3bfeb --- /dev/null +++ b/WpfNodeEdittorDemo/Blender/STNodeCheckBox.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Drawing; +using ST.Library.UI.NodeEditor; + +namespace WinNodeEditorDemo.Blender +{ + /// + /// 此类仅演示 作为MixRGB节点的复选框控件 + /// + public class STNodeCheckBox : STNodeControl + { + private bool _Checked; + + public bool Checked { + get { return _Checked; } + set { + _Checked = value; + this.Invalidate(); + } + } + + public event EventHandler ValueChanged; + protected virtual void OnValueChanged(EventArgs e) { + if (this.ValueChanged != null) this.ValueChanged(this, e); + } + + protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e) { + base.OnMouseClick(e); + this.Checked = !this.Checked; + this.OnValueChanged(new EventArgs()); + } + + protected override void OnPaint(DrawingTools dt) { + //base.OnPaint(dt); + Graphics g = dt.Graphics; + g.FillRectangle(Brushes.Gray, 0, 5, 10, 10); + m_sf.Alignment = StringAlignment.Near; + g.DrawString(this.Text, this.Font, Brushes.LightGray, new Rectangle(15, 0, this.Width - 20, 20), m_sf); + if (this.Checked) { + g.FillRectangle(Brushes.Black, 2, 7, 6, 6); + } + } + } +} diff --git a/WpfNodeEdittorDemo/Blender/STNodeColorButton.cs b/WpfNodeEdittorDemo/Blender/STNodeColorButton.cs new file mode 100644 index 0000000..1d7aa70 --- /dev/null +++ b/WpfNodeEdittorDemo/Blender/STNodeColorButton.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Drawing; +using System.Windows.Forms; +using ST.Library.UI.NodeEditor; + +namespace WinNodeEditorDemo.Blender +{ + /// + /// 此类仅演示 作为MixRGB节点的颜色选择按钮 + /// + public class STNodeColorButton : STNodeControl + { + public event EventHandler ValueChanged; + protected virtual void OnValueChanged(EventArgs e) { + if (this.ValueChanged != null) this.ValueChanged(this, e); + } + + protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e) { + base.OnMouseClick(e); + ColorDialog cd = new ColorDialog(); + if (cd.ShowDialog() != DialogResult.OK) return; + //this._Color = cd.Color; + this.BackColor = cd.Color; + this.OnValueChanged(new EventArgs()); + } + } +} diff --git a/WpfNodeEdittorDemo/Blender/STNodeProgress.cs b/WpfNodeEdittorDemo/Blender/STNodeProgress.cs new file mode 100644 index 0000000..5fa5587 --- /dev/null +++ b/WpfNodeEdittorDemo/Blender/STNodeProgress.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; +using System.Drawing; + +namespace WinNodeEditorDemo.Blender +{ + /// + /// 此类仅演示 作为MixRGB节点的进度条控件 + /// + public class STNodeProgress : STNodeControl + { + private int _Value = 50; + + public int Value { + get { return _Value; } + set { + _Value = value; + this.Invalidate(); + } + } + + private bool m_bMouseDown; + + public event EventHandler ValueChanged; + protected virtual void OnValueChanged(EventArgs e) { + if (this.ValueChanged != null) this.ValueChanged(this, e); + } + + protected override void OnPaint(DrawingTools dt) { + base.OnPaint(dt); + Graphics g = dt.Graphics; + g.FillRectangle(Brushes.Gray, this.ClientRectangle); + g.FillRectangle(Brushes.CornflowerBlue, 0, 0, (int)((float)this._Value / 100 * this.Width), this.Height); + m_sf.Alignment = StringAlignment.Near; + g.DrawString(this.Text, this.Font, Brushes.White, this.ClientRectangle, m_sf); + m_sf.Alignment = StringAlignment.Far; + g.DrawString(((float)this._Value / 100).ToString("F2"), this.Font, Brushes.White, this.ClientRectangle, m_sf); + + } + + protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) { + base.OnMouseDown(e); + m_bMouseDown = true; + } + + protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e) { + base.OnMouseUp(e); + m_bMouseDown = false; + } + + protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e) { + base.OnMouseMove(e); + if (!m_bMouseDown) return; + int v = (int)((float)e.X / this.Width * 100); + if (v < 0) v = 0; + if (v > 100) v = 100; + this._Value = v; + this.OnValueChanged(new EventArgs()); + this.Invalidate(); + } + } +} diff --git a/WpfNodeEdittorDemo/Blender/STNodeSelectBox.cs b/WpfNodeEdittorDemo/Blender/STNodeSelectBox.cs new file mode 100644 index 0000000..9b36e87 --- /dev/null +++ b/WpfNodeEdittorDemo/Blender/STNodeSelectBox.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Drawing; +using ST.Library.UI.NodeEditor; + +namespace WinNodeEditorDemo.Blender +{ + /// + /// 此类仅演示 作为MixRGB节点的下拉框控件 + /// + public class STNodeSelectEnumBox : STNodeControl + { + private Enum _Enum; + public Enum Enum { + get { return _Enum; } + set { + _Enum = value; + this.Invalidate(); + } + } + + public event EventHandler ValueChanged; + protected virtual void OnValueChanged(EventArgs e) { + if (this.ValueChanged != null) this.ValueChanged(this, e); + } + + protected override void OnPaint(DrawingTools dt) { + Graphics g = dt.Graphics; + dt.SolidBrush.Color = Color.FromArgb(80, 0, 0, 0); + g.FillRectangle(dt.SolidBrush, this.ClientRectangle); + m_sf.Alignment = StringAlignment.Near; + g.DrawString(this.Enum.ToString(), this.Font, Brushes.White, this.ClientRectangle, m_sf); + g.FillPolygon(Brushes.Gray, new Point[]{ + new Point(this.Right - 25, 7), + new Point(this.Right - 15, 7), + new Point(this.Right - 20, 12) + }); + } + + protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e) { + base.OnMouseClick(e); + Point pt = new Point(this.Left + this.Owner.Left, this.Top + this.Owner.Top + this.Owner.TitleHeight); + pt = this.Owner.Owner.CanvasToControl(pt); + pt = this.Owner.Owner.PointToScreen(pt); + FrmEnumSelect frm = new FrmEnumSelect(this.Enum, pt, this.Width, this.Owner.Owner.CanvasScale); + var v = frm.ShowDialog(); + if (v != System.Windows.Forms.DialogResult.OK) return; + this.Enum = frm.Enum; + this.OnValueChanged(new EventArgs()); + } + } +} diff --git a/WpfNodeEdittorDemo/CalcNode.cs b/WpfNodeEdittorDemo/CalcNode.cs new file mode 100644 index 0000000..01fe541 --- /dev/null +++ b/WpfNodeEdittorDemo/CalcNode.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; +using System.Drawing; + +namespace WinNodeEditorDemo +{ + /// + /// 此节点仅演示UI自定义以及控件 并不包含功能 + /// + [STNode("/", "DebugST", "2212233137@qq.com", "st233.com", "此节点仅演示UI自定义以及控件,并不包含功能.")] + public class CalcNode : STNode + { + private StringFormat m_f; + + protected override void OnCreate() { + base.OnCreate(); + m_sf = new StringFormat(); + m_sf.LineAlignment = StringAlignment.Center; + this.Title = "Calculator"; + this.AutoSize = false; //注意需要先设置AutoSize=false 才能够进行大小设置 + this.Size = new Size(218, 308); + + var ctrl = new STNodeControl(); + ctrl.Text = ""; //此控件为显示屏幕 + ctrl.Location = new Point(13, 31); + ctrl.Size = new Size(190, 50); + this.Controls.Add(ctrl); + + ctrl.Paint += (s, e) => { + m_sf.Alignment = StringAlignment.Far; + STNodeControl c = s as STNodeControl; + Graphics g = e.DrawingTools.Graphics; + g.DrawString("0", ctrl.Font, Brushes.White, c.ClientRectangle, m_sf); + }; + + string[] strs = { //按钮文本 + "MC", "MR", "MS", "M+", + "M-", "←", "CE", "C", "+", "√", + "7", "8", "9", "/", "%", + "4", "5", "6", "*", "1/x", + "1", "2", "3", "-", "=", + "0", " ", ".", "+" }; + Point p = new Point(13, 86); + for (int i = 0; i < strs.Length; i++) { + if (strs[i] == " ") continue; + ctrl = new STNodeControl(); + ctrl.Text = strs[i]; + ctrl.Size = new Size(34, 27); + ctrl.Left = 13 + (i % 5) * 39; + ctrl.Top = 86 + (i / 5) * 32; + if (ctrl.Text == "=") ctrl.Height = 59; + if (ctrl.Text == "0") ctrl.Width = 73; + this.Controls.Add(ctrl); + if (i == 8) ctrl.Paint += (s, e) => { + m_sf.Alignment = StringAlignment.Center; + STNodeControl c = s as STNodeControl; + Graphics g = e.DrawingTools.Graphics; + g.DrawString("_", ctrl.Font, Brushes.White, c.ClientRectangle, m_sf); + }; + ctrl.MouseClick += (s, e) => System.Windows.Forms.MessageBox.Show(((STNodeControl)s).Text); + } + + this.OutputOptions.Add("Result", typeof(int), false); + } + } +} diff --git a/WpfNodeEdittorDemo/EmptyOptionTestNode.cs b/WpfNodeEdittorDemo/EmptyOptionTestNode.cs new file mode 100644 index 0000000..1c0449e --- /dev/null +++ b/WpfNodeEdittorDemo/EmptyOptionTestNode.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; + +namespace WinNodeEditorDemo +{ + [STNode("/")] + public class EmptyOptionTestNode : STNode + { + protected override void OnCreate() { + base.OnCreate(); + this.Title = "EmptyTest"; + this.InputOptions.Add(STNodeOption.Empty); + this.InputOptions.Add("string", typeof(string), false); + } + } +} diff --git a/WpfNodeEdittorDemo/ImageNode/ImageBaseNode.cs b/WpfNodeEdittorDemo/ImageNode/ImageBaseNode.cs new file mode 100644 index 0000000..54010d1 --- /dev/null +++ b/WpfNodeEdittorDemo/ImageNode/ImageBaseNode.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; +using System.Drawing; + +namespace WinNodeEditorDemo.ImageNode +{ + /// + /// 图片节点基类 用于确定节点风格 标题颜色 以及 数据类型颜色 + /// + public abstract class ImageBaseNode : STNode + { + /// + /// 需要作为显示绘制的图片 + /// + protected Image m_img_draw; + /// + /// 输出节点 + /// + protected STNodeOption m_op_img_out; + + protected override void OnCreate() { + base.OnCreate(); + m_op_img_out = this.OutputOptions.Add("", typeof(Image), false); + this.AutoSize = false; //此节点需要定制UI 所以无需AutoSize + //this.Size = new Size(320,240); + this.Width = 160; //手动设置节点大小 + this.Height = 120; + this.TitleColor = Color.FromArgb(200, Color.DarkCyan); + } + + protected override void OnOwnerChanged() { //向编辑器提交数据类型颜色 + base.OnOwnerChanged(); + if (this.Owner == null) return; + this.Owner.SetTypeColor(typeof(Image), Color.DarkCyan); + } + } +} diff --git a/WpfNodeEdittorDemo/ImageNode/ImageChannelNode.cs b/WpfNodeEdittorDemo/ImageNode/ImageChannelNode.cs new file mode 100644 index 0000000..15fbbea --- /dev/null +++ b/WpfNodeEdittorDemo/ImageNode/ImageChannelNode.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using ST.Library.UI.NodeEditor; +using System.Drawing; +using System.Drawing.Imaging; + +namespace WinNodeEditorDemo.ImageNode +{ + [STNode("/Image")] + public class ImageChannelNode : ImageBaseNode + { + private STNodeOption m_op_img_in; //输入的节点 + private STNodeOption m_op_img_r; //R图 输出节点 + private STNodeOption m_op_img_g; //G图 输出节点 + private STNodeOption m_op_img_b; //B图 输出节点 + + protected override void OnCreate() { + base.OnCreate(); + this.Title = "ImageChannel"; + + m_op_img_in = this.InputOptions.Add("", typeof(Image), true); + m_op_img_r = this.OutputOptions.Add("R", typeof(Image), false); + m_op_img_g = this.OutputOptions.Add("G", typeof(Image), false); + m_op_img_b = this.OutputOptions.Add("B", typeof(Image), false); + //当输入节点有数据输入时候 + m_op_img_in.DataTransfer += new STNodeOptionEventHandler(m_op_img_in_DataTransfer); + } + + void m_op_img_in_DataTransfer(object sender, STNodeOptionEventArgs e) { + //如果当前不是连接状态 或者 接受到的数据为空 + if (e.Status != ConnectionStatus.Connected || e.TargetOption.Data == null) { + m_op_img_out.TransferData(null); //向所有输出节点输出空数据 + m_op_img_r.TransferData(null); + m_op_img_g.TransferData(null); + m_op_img_b.TransferData(null); + m_img_draw = null; //需要绘制显示的图片置为空 + } else { + Bitmap bmp = (Bitmap)e.TargetOption.Data; //否则计算图片的RGB图像 + Bitmap bmp_r = new Bitmap(bmp.Width, bmp.Height); + Bitmap bmp_g = new Bitmap(bmp.Width, bmp.Height); + Bitmap bmp_b = new Bitmap(bmp.Width, bmp.Height); + BitmapData bmpData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + BitmapData bmpData_r = bmp_r.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + BitmapData bmpData_g = bmp_g.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + BitmapData bmpData_b = bmp_b.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + byte[] byColor = new byte[bmpData.Height * bmpData.Stride]; + byte[] byColor_r = new byte[byColor.Length]; + byte[] byColor_g = new byte[byColor.Length]; + byte[] byColor_b = new byte[byColor.Length]; + System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, byColor, 0, byColor.Length); + for (int y = 0; y < bmpData.Height; y++) { + int ny = y * bmpData.Stride; + for (int x = 0; x < bmpData.Width; x++) { + int nx = x << 2; + byColor_b[ny + nx] = byColor[ny + nx]; + byColor_g[ny + nx + 1] = byColor[ny + nx + 1]; + byColor_r[ny + nx + 2] = byColor[ny + nx + 2]; + byColor_r[ny + nx + 3] = byColor_g[ny + nx + 3] = byColor_b[ny + nx + 3] = byColor[ny + nx + 3]; + } + } + bmp.UnlockBits(bmpData); + System.Runtime.InteropServices.Marshal.Copy(byColor_r, 0, bmpData_r.Scan0, byColor_r.Length); + System.Runtime.InteropServices.Marshal.Copy(byColor_g, 0, bmpData_g.Scan0, byColor_g.Length); + System.Runtime.InteropServices.Marshal.Copy(byColor_b, 0, bmpData_b.Scan0, byColor_b.Length); + bmp_r.UnlockBits(bmpData_r); + bmp_g.UnlockBits(bmpData_g); + bmp_b.UnlockBits(bmpData_b); + m_op_img_out.TransferData(bmp); //out选项 输出原图 + m_op_img_r.TransferData(bmp_r); //R选项输出R图 + m_op_img_g.TransferData(bmp_g); + m_op_img_b.TransferData(bmp_b); + m_img_draw = bmp; //需要绘制显示的图片 + } + } + + protected override void OnDrawBody(DrawingTools dt) { + base.OnDrawBody(dt); + Graphics g = dt.Graphics; + Rectangle rect = new Rectangle(this.Left + 10, this.Top + 30, 120, 80); + g.FillRectangle(Brushes.Gray, rect); + if (m_img_draw != null) g.DrawImage(m_img_draw, rect); + } + } +} diff --git a/WpfNodeEdittorDemo/ImageNode/ImageInputNode.cs b/WpfNodeEdittorDemo/ImageNode/ImageInputNode.cs new file mode 100644 index 0000000..be7fb01 --- /dev/null +++ b/WpfNodeEdittorDemo/ImageNode/ImageInputNode.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ST.Library.UI.NodeEditor; +using System.Drawing; +using System.Windows.Forms; +using System.Reflection; + +namespace WinNodeEditorDemo.ImageNode +{ + + [STNode("Image", "Crystal_lz", "2212233137@qq.com", "st233.com", "Image Node")] + public class ImageInputNode : ImageBaseNode + { + private string _FileName;//默认的DescriptorType不支持文件路径的选择 所以需要扩展 + [STNodeProperty("InputImage", "Click to select a image", DescriptorType = typeof(OpenFileDescriptor))] + public string FileName { + get { return _FileName; } + set { + Image img = null; //当文件名被设置时 加载图片并 向输出节点输出 + if (!string.IsNullOrEmpty(value)) { + img = Image.FromFile(value); + } + if (m_img_draw != null) m_img_draw.Dispose(); + m_img_draw = img; + _FileName = value; + m_op_img_out.TransferData(m_img_draw, true); + this.Invalidate(); + } + } + + protected override void OnCreate() { + base.OnCreate(); + this.Title = "ImageInput"; + } + + protected override void OnDrawBody(DrawingTools dt) { + base.OnDrawBody(dt); + Graphics g = dt.Graphics; + Rectangle rect = new Rectangle(this.Left + 10, this.Top + 30, 140, 80); + g.FillRectangle(Brushes.Gray, rect); + if (m_img_draw != null) g.DrawImage(m_img_draw, rect); + } + } + /// + /// 对默认Descriptor进行扩展 使得支持文件路径选择 + /// + public class OpenFileDescriptor : STNodePropertyDescriptor + { + private Rectangle m_rect_open; //需要绘制"打开"按钮的区域 + private StringFormat m_sf; + + public OpenFileDescriptor() { + m_sf = new StringFormat(); + m_sf.Alignment = StringAlignment.Center; + m_sf.LineAlignment = StringAlignment.Center; + } + + protected override void OnSetItemLocation() { //当在STNodePropertyGrid上确定此属性需要显示的区域时候 + base.OnSetItemLocation(); //计算出"打开"按钮需要绘制的区域 + m_rect_open = new Rectangle( + this.RectangleR.Right - 20, + this.RectangleR.Top, + 20, + this.RectangleR.Height); + } + + protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e) { + if (m_rect_open.Contains(e.Location)) { //点击在"打开"区域 则弹出文件选择框 + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "*.jpg|*.jpg|*.png|*.png"; + if (ofd.ShowDialog() != DialogResult.OK) return; + this.SetValue(ofd.FileName); + } else base.OnMouseClick(e); //否则默认处理方式 弹出文本输入框 + } + + protected override void OnDrawValueRectangle(DrawingTools dt) { + base.OnDrawValueRectangle(dt); //在STNodePropertyGrid绘制此属性区域时候将"打开"按钮绘制上去 + dt.Graphics.FillRectangle(Brushes.Gray, m_rect_open); + dt.Graphics.DrawString("+", this.Control.Font, Brushes.White, m_rect_open, m_sf); + } + } +} diff --git a/WpfNodeEdittorDemo/MainWindow.xaml b/WpfNodeEdittorDemo/MainWindow.xaml new file mode 100644 index 0000000..8f3d94c --- /dev/null +++ b/WpfNodeEdittorDemo/MainWindow.xaml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + +