(str);
27 | for (var index = data.Nodes.Count - 1; index >= 0; index--)
28 | {
29 | var copiednode = data.Nodes[index];
30 | var typename = copiednode.Name;
31 | Node newNode = null;
32 | foreach (var node in LoadedExternalNodes)
33 | {
34 | if (node.ToString() != typename) continue;
35 | newNode = node.Clone();
36 | vc.AddNode(newNode, copiednode.X, copiednode.Y);
37 | newNode.DeSerializeData(copiednode.InputData, copiednode.OutputData);
38 | newNode.Id = copiednode.Id;
39 | break;
40 | }
41 | if (newNode != null) continue;
42 | var type = Type.GetType(typename);
43 | if (type != null)
44 | {
45 | var instance = Activator.CreateInstance(type, vc, false);
46 | vc.AddNode(instance as Node, copiednode.X, copiednode.Y);
47 | var node = instance as Node;
48 | if (node != null) node.Id = copiednode.Id;
49 | }
50 | }
51 | foreach (var eConn in data.ExecutionConnectors)
52 | {
53 | var start = vc.GetNode(eConn.StartNode_ID);
54 | var end = vc.GetNode(eConn.EndNode_ID);
55 | NodesManager.CreateExecutionConnector(vc, start.OutExecPorts[eConn.StartPort_Index],
56 | end.InExecPorts[eConn.EndPort_Index]);
57 | }
58 | foreach (var oConn in data.ObjectConnectors)
59 | {
60 | var start = vc.GetNode(oConn.StartNode_ID);
61 | var end = vc.GetNode(oConn.EndNode_ID);
62 | NodesManager.CreateObjectConnector(vc, start.OutputPorts[oConn.StartPort_Index],
63 | end.InputPorts[oConn.EndPort_Index]);
64 | }
65 | foreach (var divider in data.SpaghettiDividers)
66 | {
67 | var node = vc.GetNode(divider.EndNode_ID);
68 | var port = node.InputPorts[divider.Port_Index];
69 | var conn = port.ConnectedConnectors[0];
70 | var spaghettiDivider = new SpaghettiDivider(vc, conn, false)
71 | {
72 | X = divider.X,
73 | Y = divider.Y
74 | };
75 | vc.AddNode(spaghettiDivider, spaghettiDivider.X, spaghettiDivider.Y);
76 | }
77 | }
78 | catch (Exception)
79 | {
80 | return false;
81 | }
82 | foreach (var node in vc.Nodes)
83 | node.Refresh();
84 | vc.NeedsRefresh = true;
85 |
86 | return true;
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/Nodes/Nodes/Nodes.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B4DCEC74-E9BA-4D95-928F-3B81F8BF3275}
8 | Library
9 | Properties
10 | Nodes
11 | Nodes
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ..\..\VisualSR\bin\Debug\VisualSR.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/VisualSR/Core/RVariable.cs:
--------------------------------------------------------------------------------
1 | /*Copyright 2018 ALAA BEN FATMA
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
8 | using System.ComponentModel;
9 | using System.Windows.Media;
10 | using VisualSR.Properties;
11 |
12 | namespace VisualSR.Core
13 | {
14 | public enum RTypes
15 | {
16 | //Character refers to strings too, will be using the same properties.
17 | Character,
18 |
19 | //Numeric refers to Doubles,Integers,Decimals,Bytes and even complex values.
20 | Numeric,
21 |
22 | //Logical refers to either TRUE or FALSE values. With that being said, you can call it a boolean type.
23 | Logical,
24 |
25 | /*While matrices are confined to two dimensions, arrays can be of any number of dimensions.
26 | *Factors are the r-objects which are created using a vector. It stores the vector along with the distinct values of the elements in the vector as labels.
27 | *A list is an R-object which can contain many different types of elements inside it like vectors, functions and even another list inside it.
28 | *A matrix is a two-dimensional rectangular data set. It can be created using a vector input to the matrix function.
29 | */
30 | ArrayOrFactorOrListOrMatrix,
31 |
32 |
33 | //Data frames are tabular data objects. Unlike a matrix in data frame each column can contain different modes of data.
34 | DataFrame,
35 |
36 |
37 | //This one can contain any value you put into it.
38 | Generic
39 | }
40 |
41 | public class RVariable : INotifyPropertyChanged
42 | {
43 | private ObjectPort _pp;
44 | private string _value;
45 |
46 | public RTypes Type;
47 |
48 | ///
49 | /// Virtual type that works as a data container for R-data-like types.
50 | ///
51 | ///
52 | public RVariable(RTypes type)
53 | {
54 | Type = type;
55 | }
56 |
57 | public ObjectPort ParentPort
58 | {
59 | get { return _pp; }
60 | set
61 | {
62 | _pp = value;
63 | switch (Type)
64 | {
65 | case RTypes.ArrayOrFactorOrListOrMatrix:
66 | ParentPort.StrokeBrush = Brushes.DodgerBlue;
67 | break;
68 | case RTypes.Character:
69 | ParentPort.StrokeBrush = Brushes.Magenta;
70 |
71 | break;
72 | case RTypes.Logical:
73 | ParentPort.StrokeBrush = Brushes.Red;
74 |
75 | break;
76 | case RTypes.Numeric:
77 | ParentPort.StrokeBrush = Brushes.LawnGreen;
78 | break;
79 | case RTypes.DataFrame:
80 | ParentPort.StrokeBrush = Brushes.Orange;
81 | break;
82 | default:
83 | ParentPort.StrokeBrush = Brushes.LightGray;
84 | break;
85 | }
86 | }
87 | }
88 |
89 | ///
90 | /// Contains the data that will be parsed.
91 | ///
92 | public string Value
93 | {
94 | get { return _value; }
95 | set
96 | {
97 | _value = value;
98 | OnPropertyChanged("Value");
99 | ParentPort.OnDataChanged();
100 | }
101 | }
102 |
103 | public event PropertyChangedEventHandler PropertyChanged;
104 |
105 | [NotifyPropertyChangedInvocator]
106 | protected virtual void OnPropertyChanged(string propertyName = null)
107 | {
108 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/Nodes/Nodes/Nodes/Characters/Grep.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using VisualSR.Controls;
3 | using VisualSR.Core;
4 | using VisualSR.Tools;
5 |
6 | namespace Nodes.Nodes.Characters
7 | {
8 | [Export(typeof(Node))]
9 | public class Grep : Node
10 |
11 | {
12 | private readonly UnrealControlsCollection.CheckBox _cb =
13 | new UnrealControlsCollection.CheckBox {IsChecked = true};
14 |
15 | private readonly UnrealControlsCollection.CheckBox _cbc =
16 | new UnrealControlsCollection.CheckBox {IsChecked = false};
17 |
18 | private readonly UnrealControlsCollection.TextBox _p = new UnrealControlsCollection.TextBox();
19 | private readonly UnrealControlsCollection.TextBox _t = new UnrealControlsCollection.TextBox();
20 | private readonly VirtualControl Host;
21 |
22 | [ImportingConstructor]
23 | public Grep([Import("host")] VirtualControl host, [Import("bool")] bool spontaneousAddition = false) : base(
24 | host, NodeTypes.Basic, spontaneousAddition)
25 | {
26 | Title = "Grep";
27 | Host = host;
28 |
29 | Category = "Characters";
30 | AddObjectPort(this, "Text", PortTypes.Input, RTypes.Character, false, _t);
31 | AddObjectPort(this, "Pattern", PortTypes.Input, RTypes.Generic, false, _p);
32 | AddObjectPort(this, "Case sensitive", PortTypes.Input, RTypes.Logical, false, _cbc);
33 | AddObjectPort(this, "Normal Text", PortTypes.Input, RTypes.Logical, false, _cb);
34 | AddObjectPort(this, "Extracted value", PortTypes.Output, RTypes.Character, true);
35 | MouseRightButtonDown += (sender, args) => GenerateCode();
36 | _t.TextChanged += (sender, args) =>
37 | {
38 | InputPorts[0].Data.Value = _t.Text;
39 | GenerateCode();
40 | };
41 | _p.TextChanged += (sender, args) =>
42 | {
43 | InputPorts[1].Data.Value = _p.Text;
44 | GenerateCode();
45 | };
46 | _cbc.Checked += (sender, args) =>
47 | {
48 | InputPorts[2].Data.Value = _cbc.IsChecked.ToString().ToUpper();
49 | GenerateCode();
50 | };
51 | _cb.Checked += (sender, args) =>
52 | {
53 | InputPorts[3].Data.Value = _cb.IsChecked.ToString().ToUpper();
54 | GenerateCode();
55 | };
56 | foreach (var port in InputPorts)
57 | port.DataChanged += (sender, args) => { GenerateCode(); };
58 | InputPorts[1].LinkChanged += (sender, args) =>
59 | {
60 | if (!InputPorts[1].Linked)
61 | InputPorts[1].Data.Value = _p.Text;
62 | };
63 | InputPorts[0].LinkChanged += (sender, args) =>
64 | {
65 | if (!InputPorts[0].Linked)
66 | InputPorts[0].Data.Value = _t.Text;
67 | };
68 | InputPorts[3].LinkChanged += (sender, args) =>
69 | {
70 | if (!InputPorts[3].Linked)
71 | InputPorts[3].Data.Value = _cb.IsChecked.ToString().ToUpper();
72 | };
73 | InputPorts[2].LinkChanged += (sender, args) =>
74 | {
75 | if (!InputPorts[2].Linked)
76 | InputPorts[2].Data.Value = _cbc.IsChecked.ToString().ToUpper();
77 | };
78 | InputPorts[0].DataChanged += (s, e) =>
79 | {
80 | if (_t.Text != InputPorts[0].Data.Value)
81 | _t.Text = InputPorts[0].Data.Value;
82 | };
83 | InputPorts[1].DataChanged += (s, e) =>
84 | {
85 | if (_p.Text != InputPorts[1].Data.Value)
86 | _p.Text = InputPorts[1].Data.Value;
87 | };
88 | InputPorts[3].DataChanged += (s, e) =>
89 | {
90 | if (_cb.IsChecked.ToString().ToUpper() != InputPorts[3].Data.Value)
91 | _cb.IsChecked = MagicLaboratory.ConvertFromString(InputPorts[3].Data.Value);
92 | };
93 | InputPorts[2].DataChanged += (s, e) =>
94 | {
95 | if (_cb.IsChecked.ToString().ToUpper() != InputPorts[2].Data.Value)
96 | _cbc.IsChecked = MagicLaboratory.ConvertFromString(InputPorts[2].Data.Value);
97 | };
98 | }
99 |
100 |
101 | public override string GenerateCode()
102 | {
103 | OutputPorts[0].Data.Value =
104 | $"grep({_t},{_p},ignore.case={_cbc.IsChecked.ToString().ToUpper()},fixed={_cb.IsChecked.ToString().ToUpper()})";
105 | return OutputPorts[0].Data.Value;
106 | }
107 |
108 | public override Node Clone()
109 | {
110 | var node = new Substr(Host);
111 |
112 | return node;
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Visual Scripting Environment for R and Data Science
2 | 
3 |
4 | ### Technical article -> https://www.codeproject.com/Articles/1239656/VisualSR
5 |
6 | ### 📉 Status
7 | 
8 | 
9 | 
10 |
11 | ### 🔧 Pre-requirments
12 |
13 | - .NET Framework 4.5
14 | - rscript has to be reachable from the command-line : https://www.r-project.org/
15 |
16 |
17 | ### 🏗️ Build
18 |
19 | Each project in this repo (VisualSR, Nodes and demo) can be built using one of these two different approaches.
20 |
21 | - Automatically : Using an IDE, such as Visual Studio or SharpDevelop.
22 | - Semi-manually : You can use MSBuild
23 |
24 |
25 | MSBuild.exe VisualSR\VisualSR.sln
26 | MSBuild.exe Nodes\Nodes.sln
27 | MSBuild.exe demo\demo.sln
28 |
29 |
30 |
31 |
32 | ### 📚 Usage
33 | This repo contains 3 different projects. Each one of them contains a .csproj file that can load the whole project.
34 |
35 | - VisualSR : This is the core of the project. It contains all the tools, custom controls and utilities. A class library (.dll) will be generated once the project is built.
36 | - Nodes : This is a project within which I have created many samples of how to create custom nodes. A class library (.dll) will be generated once the project is built.
37 | - DEMO : This GUI will provide the user with a UX which can help demonstrate the capabilities of this project.
38 |
39 |
40 | ### 💕 Contributions
41 | The project is far from being perfect. Please do not hesitate to open issues, debug the code if needed or make pull requests!
42 |
43 | #### Please note that the rest is not a documentation, it is nothing but an *eye-catcher*. Refer to this article [CODEPROJECT](https://www.codeproject.com/Articles/1239656/VisualSR) for more details.
44 |
45 |
46 |
47 |
48 | ### NODES
49 |
50 | 
51 |
52 |
53 | ### CONNECTORS
54 |
55 | #### Diagram
56 |
57 | 
58 |
59 |
60 | ### Applications
61 |
62 | 
63 |
64 |
65 | ### Making connections
66 |
67 | 
68 |
69 | ### Possibilities
70 |
71 | 
72 |
73 |
74 | ### Deleting connections
75 |
76 | 
77 |
78 |
79 |
80 | ### Middle Man Algorithm
81 |
82 | 
83 |
84 |
85 |
86 | ### SAMPLES
87 |
88 | #### Math
89 |
90 | 
91 | 
92 |
93 |
94 |
95 | #### For loop
96 |
97 | 
98 | 
99 |
100 |
101 | #### Graph
102 |
103 | 
104 | 
105 |
106 |
107 | ## More stuff you will find
108 |
109 | #### A performance gauge
110 |
111 | 
112 |
113 |
114 | #### Commenting zones
115 |
116 | 
117 |
118 |
119 | #### Variables list
120 |
121 | 
122 |
123 |
124 | #### Altered Nodes Tree
125 |
126 | 
127 |
128 |
129 |
130 | #### Search for nodes
131 |
132 | 
133 |
134 |
135 |
136 | # DEMO
137 | 
138 |
139 |
--------------------------------------------------------------------------------
/VisualSR/Controls/Search.cs:
--------------------------------------------------------------------------------
1 | /*Copyright 2018 ALAA BEN FATMA
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 | using System.Windows;
11 | using System.Windows.Controls;
12 | using System.Windows.Input;
13 | using System.Windows.Media;
14 | using System.Windows.Shapes;
15 | using VisualSR.Core;
16 | using VisualSR.Properties;
17 | using VisualSR.Tools;
18 |
19 | namespace VisualSR.Controls
20 | {
21 | public class Search : Window, INotifyPropertyChanged
22 | {
23 | private readonly VirtualControl _host;
24 | private TextBlock clear;
25 | private TextBlock go;
26 | private ListView lv;
27 |
28 | private TextBox tb;
29 |
30 | public Search(VirtualControl host)
31 | {
32 | WindowStyle = WindowStyle.ToolWindow;
33 | _host = host;
34 | Style = FindResource("Search") as Style;
35 | Loaded += (s, e) =>
36 | {
37 | clear = Template.FindName("Clear", this) as TextBlock;
38 | go = Template.FindName("FindButton", this) as TextBlock;
39 | tb = Template.FindName("NodeName", this) as TextBox;
40 | lv = Template.FindName("FoundNodes", this) as ListView;
41 | clear.MouseLeftButtonUp += (ss, ee) => tb.Clear();
42 | go.MouseLeftButtonUp += Go_MouseLeftButtonUp;
43 | Topmost = true;
44 | };
45 | }
46 |
47 | public event PropertyChangedEventHandler PropertyChanged;
48 |
49 | private void Go_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
50 | {
51 | lv.Items.Clear();
52 | foreach (var node in _host.Nodes)
53 | if (node.Search(tb.Text) != null)
54 | {
55 | var tv = new TreeView {Background = new SolidColorBrush(Color.FromArgb(35, 35, 35, 35))};
56 | tv.Items.Add(node.Search(tb.Text));
57 | lv.Items.Add(tv);
58 | }
59 | }
60 |
61 | [NotifyPropertyChangedInvocator]
62 | protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
63 | {
64 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
65 | }
66 | }
67 |
68 | public class FoundItem : TreeViewItem
69 | {
70 | private readonly Path ctrl = new Path {Width = 15, Height = 15, Margin = new Thickness(0, -2, 0, 0)};
71 |
72 | private readonly TextBlock hint =
73 | new TextBlock {Foreground = Brushes.WhiteSmoke, Background = Brushes.Transparent};
74 |
75 | private string _hint;
76 |
77 | private Brush brush;
78 |
79 | public ItemTypes Type;
80 |
81 | public FoundItem(Brush b = null)
82 | {
83 | IsExpanded = true;
84 | Loaded += (s, e) =>
85 | {
86 | MouseDoubleClick += FoundItem_MouseDoubleClick;
87 |
88 |
89 | var sp = new StackPanel {Orientation = Orientation.Horizontal, MaxHeight = 20};
90 | sp.Children.Add(ctrl);
91 | sp.Children.Add(hint);
92 | Header = sp;
93 | if (Type == ItemTypes.Port)
94 | {
95 | ctrl.Style = FindResource("ObjectPin") as Style;
96 | ctrl.Stroke = b;
97 | }
98 | else
99 | {
100 | ctrl.Style = FindResource("ExecPin") as Style;
101 | }
102 | };
103 | }
104 |
105 | public string Hint
106 | {
107 | get { return _hint; }
108 | set
109 | {
110 | _hint = value;
111 | if (hint != null) hint.Text = value;
112 | }
113 | }
114 |
115 | public Brush Brush
116 | {
117 | get { return brush; }
118 | set
119 | {
120 | brush = value;
121 | ctrl.Stroke = value;
122 | ctrl.Fill = value;
123 | }
124 | }
125 |
126 | public Node foundNode { get; set; }
127 |
128 | private void FoundItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
129 | {
130 | foundNode.Host.GoForNode(foundNode);
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/VisualSR/Core/Wire.cs:
--------------------------------------------------------------------------------
1 | /*Copyright 2018 ALAA BEN FATMA
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
8 | using System;
9 | using System.ComponentModel;
10 | using System.Windows;
11 | using System.Windows.Controls;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Animation;
14 | using System.Windows.Shapes;
15 | using VisualSR.Properties;
16 | using VisualSR.Tools;
17 |
18 | namespace VisualSR.Core
19 | {
20 | public class Wire : Control, INotifyPropertyChanged
21 | {
22 | private readonly PointAnimationUsingPath beatsAnimation = new PointAnimationUsingPath();
23 |
24 | private readonly Storyboard heart = new Storyboard();
25 | private Point _epoint;
26 | private Point _mpoint1;
27 | private Point _mpoint2;
28 | private Point _spoint;
29 |
30 | public Wire()
31 | {
32 | Style = (Style) FindResource("VirtualWire");
33 | Background = Brushes.WhiteSmoke;
34 | Focusable = false;
35 | Loaded += (s, e) =>
36 | {
37 | IsVisibleChanged += (ss, ee) =>
38 | {
39 | if (Visibility != Visibility.Visible)
40 | stopAnimation();
41 | };
42 | };
43 |
44 |
45 | beatsAnimation.Completed += BeatsAnimation_Completed;
46 | heart.Children.Add(beatsAnimation);
47 | }
48 |
49 | public Connector ParentConnector { get; set; }
50 |
51 | public Point StartPoint
52 | {
53 | get { return _spoint; }
54 | set
55 | {
56 | _spoint = value;
57 | OnPropertyChanged("StartPoint");
58 | MiddlePoint1 = _spoint;
59 | }
60 | }
61 |
62 | public Point MiddlePoint1
63 | {
64 | get { return _mpoint1; }
65 | set
66 | {
67 | _mpoint1 = new Point(value.X + 70, value.Y);
68 | OnPropertyChanged("MiddlePoint1");
69 | }
70 | }
71 |
72 | public Point MiddlePoint2
73 | {
74 | get { return _mpoint2; }
75 | set
76 | {
77 | OnPropertyChanged("MiddlePoint2");
78 | _mpoint2 = new Point(value.X - 70, value.Y);
79 | }
80 | }
81 |
82 | public Point EndPoint
83 | {
84 | get { return _epoint; }
85 | set
86 | {
87 | _epoint = value;
88 |
89 | MiddlePoint2 = _epoint;
90 | OnPropertyChanged("EndPoint");
91 | }
92 | }
93 |
94 |
95 | public event PropertyChangedEventHandler PropertyChanged;
96 |
97 | public void HeartBeatsAnimation(bool forever = true)
98 | {
99 | try
100 | {
101 | var path = Template.FindName("Wire", this) as Path;
102 | beatsAnimation.PathGeometry = path.Data.GetFlattenedPathGeometry();
103 | beatsAnimation.Duration = TimeSpan.FromSeconds(1);
104 | (Template.FindName("BeatContainer", this) as Path).Visibility = Visibility.Visible;
105 | beatsAnimation.RepeatBehavior = forever ? RepeatBehavior.Forever : new RepeatBehavior(1);
106 | (Template.FindName("Beat", this) as EllipseGeometry).BeginAnimation(EllipseGeometry.CenterProperty,
107 | beatsAnimation);
108 | }
109 | catch (Exception)
110 | {
111 | //Ignored
112 | }
113 | }
114 |
115 | private void BeatsAnimation_Completed(object sender, EventArgs e)
116 | {
117 | stopAnimation();
118 | }
119 |
120 | private void stopAnimation()
121 | {
122 | (Template.FindName("Beat", this) as EllipseGeometry).BeginAnimation(EllipseGeometry.CenterProperty, null);
123 | (Template.FindName("BeatContainer", this) as Path).Visibility = Visibility.Collapsed;
124 | }
125 |
126 | public void ParentNodeOnPropertyChanged(Port s, Port e)
127 | {
128 | var sp = PointsCalculator.PortOrigin(s);
129 | var ep = PointsCalculator.PortOrigin(e);
130 | StartPoint = sp;
131 | EndPoint = ep;
132 | }
133 |
134 | [NotifyPropertyChangedInvocator]
135 | protected virtual void OnPropertyChanged(string propertyName = null)
136 | {
137 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
138 | }
139 | }
140 | }
--------------------------------------------------------------------------------
/demo/demo/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/VisualSR/Core/Brain.cs:
--------------------------------------------------------------------------------
1 | /*Copyright 2018 ALAA BEN FATMA
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
8 | /*
9 | * Brain is an UNDO/REDO framework
10 | * It is still under exp
11 | */
12 | //using System;
13 | //using System.Collections.Generic;
14 | //using System.Windows.Forms;
15 | //using VisualSR.Tools;
16 |
17 | //namespace VisualSR.Core
18 | //{
19 |
20 | // public class VirtualStack : Stack
21 | // {
22 | // public Stack RedoList = new Stack();
23 | // public event EventHandler CollectionChanged;
24 | // public new Record Pop()
25 | // {
26 | // if (Count == 0) return null;
27 | // var x = base.Pop();
28 | // RedoList.Push(x);
29 | // OnCollectionChanged();
30 | // return x as Record;
31 | // }
32 |
33 | // public void Push(T item, bool redoing)
34 | // {
35 | // Push(item);
36 | // if (!redoing)
37 | // RedoList.Clear();
38 | // OnCollectionChanged();
39 | // }
40 |
41 | // protected virtual void OnCollectionChanged()
42 | // {
43 | // CollectionChanged?.Invoke(this, EventArgs.Empty);
44 | // }
45 | // }
46 |
47 | // public enum PossibleEvents
48 | // {
49 | // //VirtualControl related events
50 | // MoveNodes,
51 | // DeleteNode,
52 | // AddNode,
53 | // MakeAConnection,
54 | // DeleteAConnection,
55 | // AddAPin,
56 | // //VariablesList
57 | // AddAVariable,
58 | // DeleteAVarible,
59 | // RenameAVarible,
60 | // ChangeTypeOfAVariable,
61 | // //ContentsBrowser
62 | // MakeNewItem,
63 | // RenameItem,
64 | // DeleteItem,
65 | // //FunctionsList : not supported yet
66 | // }
67 |
68 | // public class UndoAddNode : Record
69 | // {
70 |
71 | // public UndoAddNode(VirtualControl host,Node Node) : base(() =>
72 | // {
73 | // Node.Delete(true);
74 | // }, () =>
75 | // {
76 | // var props = new NodeProperties(Node);
77 | // var capture = new CaptureData {Data = props};
78 | // var data = capture.Data as NodeProperties;
79 | // var typename = data.Name;
80 | // Node newNode = null;
81 | // foreach (var node in Hub.LoadedExternalNodes)
82 | // {
83 | // if (node.ToString() != typename) continue;
84 | // newNode = node.Clone();
85 | // host.AddNode(newNode, data.X, data.Y,true);
86 | // newNode.DeSerializeData(data.InputData, data.OutputData);
87 | // newNode.Id = data.Id;
88 | // break;
89 | // }
90 | // if (newNode != null) return;
91 | // var type = Type.GetType(typename);
92 | // if (type != null)
93 | // {
94 | // var instance = Activator.CreateInstance(type, host, false);
95 | // host.AddNode(instance as Node, data.X, data.Y,true);
96 | // var node = instance as Node;
97 | // if (node != null) node.Id = data.Id;
98 | // }
99 | // }, "Add Node")
100 | // {
101 | // }
102 | // }
103 | // public class CaptureData
104 | // {
105 | // public object Data;
106 | // }
107 | // public class Record
108 | // {
109 |
110 | // public Action Command;
111 | // public Action Opposite;
112 | // public string Description;
113 | // public Record(Action command,Action opposite, string description)
114 | // {
115 | // Command = command;
116 | // Opposite = opposite;
117 | // Description = description;
118 | // Opposite();
119 | // }
120 |
121 |
122 | // public void Undo()
123 | // {
124 |
125 | // Command();
126 | // }
127 | // }
128 |
129 | // public class Brain
130 | // {
131 | // ///
132 | // /// This stack will contain all the previous states of a specific
133 | // /// control based on some serialized data.
134 | // ///
135 | // public VirtualStack UndoList = new VirtualStack();
136 |
137 | // public void AddToUndo(Record item, bool redoing=false)
138 | // {
139 | // UndoList.Push(item, redoing);
140 | // }
141 |
142 | // public void Undo()
143 | // {
144 | // if (UndoList.Count == 0) return;
145 | // var x = UndoList.Pop();
146 |
147 | // x.Undo();
148 | // }
149 |
150 | // public void Redo()
151 | // {
152 | // if (UndoList.RedoList.Count == 0)
153 | // {
154 | // MessageBox.Show("redo empty.");
155 | // return;
156 | // }
157 | // AddToUndo(UndoList.RedoList.Peek() as Record, true);
158 | // UndoList.RedoList.Pop().Opposite();
159 | // }
160 | // }
161 | //}
162 |
163 |
--------------------------------------------------------------------------------
/VisualSR/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------