diff --git a/Bonsai.Scripting.Expressions.Design/Bonsai.Scripting.Expressions.Design.csproj b/Bonsai.Scripting.Expressions.Design/Bonsai.Scripting.Expressions.Design.csproj
new file mode 100644
index 000000000..f4c97d6a6
--- /dev/null
+++ b/Bonsai.Scripting.Expressions.Design/Bonsai.Scripting.Expressions.Design.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Bonsai - Expression Scripting Design Library
+ Bonsai Design Library containing editor classes for expression scripting in Bonsai.
+ Bonsai Rx Scripting Expressions Design
+ net5.0-windows10.0.19041
+ 3.0.0
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Bonsai.Scripting/ExpressionScriptEditor.cs b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditor.cs
similarity index 94%
rename from Bonsai.Scripting/ExpressionScriptEditor.cs
rename to Bonsai.Scripting.Expressions.Design/ExpressionScriptEditor.cs
index 41bca6cf5..ae8625fe2 100644
--- a/Bonsai.Scripting/ExpressionScriptEditor.cs
+++ b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditor.cs
@@ -1,33 +1,33 @@
-using System;
-using System.Drawing.Design;
-using System.ComponentModel;
-using System.Windows.Forms.Design;
-using System.Windows.Forms;
-
-namespace Bonsai.Scripting
-{
- public class ExpressionScriptEditor : UITypeEditor
- {
- public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
- {
- return UITypeEditorEditStyle.Modal;
- }
-
- public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
- {
- var editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
- if (editorService != null)
- {
- var script = value as string;
- var editorDialog = new ExpressionScriptEditorDialog();
- editorDialog.Script = script;
- if (editorService.ShowDialog(editorDialog) == DialogResult.OK)
- {
- return editorDialog.Script;
- }
- }
-
- return base.EditValue(context, provider, value);
- }
- }
-}
+using System;
+using System.Drawing.Design;
+using System.ComponentModel;
+using System.Windows.Forms.Design;
+using System.Windows.Forms;
+
+namespace Bonsai.Scripting.Expressions.Design
+{
+ public class ExpressionScriptEditor : UITypeEditor
+ {
+ public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
+ {
+ return UITypeEditorEditStyle.Modal;
+ }
+
+ public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
+ {
+ var editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
+ if (editorService != null)
+ {
+ var script = value as string;
+ var editorDialog = new ExpressionScriptEditorDialog();
+ editorDialog.Script = script;
+ if (editorService.ShowDialog(editorDialog) == DialogResult.OK)
+ {
+ return editorDialog.Script;
+ }
+ }
+
+ return base.EditValue(context, provider, value);
+ }
+ }
+}
diff --git a/Bonsai.Scripting/ExpressionScriptEditorDialog.Designer.cs b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.Designer.cs
similarity index 97%
rename from Bonsai.Scripting/ExpressionScriptEditorDialog.Designer.cs
rename to Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.Designer.cs
index 0070a70c6..47fc25992 100644
--- a/Bonsai.Scripting/ExpressionScriptEditorDialog.Designer.cs
+++ b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.Designer.cs
@@ -1,96 +1,96 @@
-namespace Bonsai.Scripting
-{
- partial class ExpressionScriptEditorDialog
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows Form Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.scintilla = new ScintillaNET.Scintilla();
- this.okButton = new System.Windows.Forms.Button();
- this.cancelButton = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // scintilla
- //
- this.scintilla.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
- | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.scintilla.Location = new System.Drawing.Point(12, 12);
- this.scintilla.Name = "scintilla";
- this.scintilla.Size = new System.Drawing.Size(600, 229);
- this.scintilla.TabIndex = 3;
- this.scintilla.TabWidth = 2;
- this.scintilla.UseTabs = false;
- this.scintilla.WrapMode = ScintillaNET.WrapMode.Word;
- this.scintilla.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scintilla_KeyDown);
- this.scintilla.TextChanged += new System.EventHandler(this.scintilla_TextChanged);
- //
- // okButton
- //
- this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
- this.okButton.Location = new System.Drawing.Point(456, 247);
- this.okButton.Name = "okButton";
- this.okButton.Size = new System.Drawing.Size(75, 23);
- this.okButton.TabIndex = 1;
- this.okButton.Text = "OK";
- this.okButton.UseVisualStyleBackColor = true;
- //
- // cancelButton
- //
- this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.cancelButton.Location = new System.Drawing.Point(537, 247);
- this.cancelButton.Name = "cancelButton";
- this.cancelButton.Size = new System.Drawing.Size(75, 23);
- this.cancelButton.TabIndex = 2;
- this.cancelButton.Text = "Cancel";
- this.cancelButton.UseVisualStyleBackColor = true;
- //
- // ExpressionScriptEditorDialog
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(624, 282);
- this.Controls.Add(this.cancelButton);
- this.Controls.Add(this.okButton);
- this.Controls.Add(this.scintilla);
- this.KeyPreview = true;
- this.MinimumSize = new System.Drawing.Size(640, 320);
- this.Name = "ExpressionScriptEditorDialog";
- this.ShowIcon = false;
- this.Text = "Expression Script";
- this.ResumeLayout(false);
-
- }
-
- #endregion
-
- private ScintillaNET.Scintilla scintilla;
- private System.Windows.Forms.Button okButton;
- private System.Windows.Forms.Button cancelButton;
- }
+namespace Bonsai.Scripting.Expressions.Design
+{
+ partial class ExpressionScriptEditorDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.scintilla = new ScintillaNET.Scintilla();
+ this.okButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // scintilla
+ //
+ this.scintilla.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.scintilla.Location = new System.Drawing.Point(12, 12);
+ this.scintilla.Name = "scintilla";
+ this.scintilla.Size = new System.Drawing.Size(600, 229);
+ this.scintilla.TabIndex = 3;
+ this.scintilla.TabWidth = 2;
+ this.scintilla.UseTabs = false;
+ this.scintilla.WrapMode = ScintillaNET.WrapMode.Word;
+ this.scintilla.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scintilla_KeyDown);
+ this.scintilla.TextChanged += new System.EventHandler(this.scintilla_TextChanged);
+ //
+ // okButton
+ //
+ this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.okButton.Location = new System.Drawing.Point(456, 247);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(75, 23);
+ this.okButton.TabIndex = 1;
+ this.okButton.Text = "OK";
+ this.okButton.UseVisualStyleBackColor = true;
+ //
+ // cancelButton
+ //
+ this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point(537, 247);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(75, 23);
+ this.cancelButton.TabIndex = 2;
+ this.cancelButton.Text = "Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ //
+ // ExpressionScriptEditorDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(624, 282);
+ this.Controls.Add(this.cancelButton);
+ this.Controls.Add(this.okButton);
+ this.Controls.Add(this.scintilla);
+ this.KeyPreview = true;
+ this.MinimumSize = new System.Drawing.Size(640, 320);
+ this.Name = "ExpressionScriptEditorDialog";
+ this.ShowIcon = false;
+ this.Text = "Expression Script";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private ScintillaNET.Scintilla scintilla;
+ private System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.Button cancelButton;
+ }
}
\ No newline at end of file
diff --git a/Bonsai.Scripting/ExpressionScriptEditorDialog.cs b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.cs
similarity index 96%
rename from Bonsai.Scripting/ExpressionScriptEditorDialog.cs
rename to Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.cs
index 4d65a093c..ae8b1570d 100644
--- a/Bonsai.Scripting/ExpressionScriptEditorDialog.cs
+++ b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.cs
@@ -1,72 +1,72 @@
-using ScintillaNET;
-using System;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace Bonsai.Scripting
-{
- public partial class ExpressionScriptEditorDialog : Form
- {
- public ExpressionScriptEditorDialog()
- {
- InitializeComponent();
- scintilla.StyleResetDefault();
- scintilla.Styles[Style.Default].Font = "Consolas";
- scintilla.Styles[Style.Default].Size = 10;
- scintilla.StyleClearAll();
-
- scintilla.CaretLineBackColor = ColorTranslator.FromHtml("#feefff");
- scintilla.Styles[Style.Cpp.Default].ForeColor = Color.Black;
- scintilla.Styles[Style.Cpp.Number].ForeColor = Color.Black;
- scintilla.Styles[Style.Cpp.Character].ForeColor = ColorTranslator.FromHtml("#a31515");
- scintilla.Styles[Style.Cpp.String].ForeColor = ColorTranslator.FromHtml("#a31515");
- scintilla.Styles[Style.Cpp.StringEol].ForeColor = ColorTranslator.FromHtml("#a31515");
- scintilla.Styles[Style.Cpp.Word].ForeColor = ColorTranslator.FromHtml("#0000ff");
- scintilla.Styles[Style.Cpp.Word2].ForeColor = ColorTranslator.FromHtml("#2b91af");
- scintilla.Lexer = Lexer.Cpp;
-
- var types = "Object Boolean Char String SByte Byte Int16 UInt16 Int32 UInt32 Int64 UInt64 Single Double Decimal DateTime DateTimeOffset TimeSpan Guid Math Convert";
- scintilla.SetKeywords(0, "it iif new outerIt as true false null");
- scintilla.SetKeywords(1, string.Join(" ", types, types.ToLowerInvariant()));
- }
-
- public string Script { get; set; }
-
- protected override void OnLoad(EventArgs e)
- {
- scintilla.Text = Script;
- scintilla.EmptyUndoBuffer();
- if (Owner != null)
- {
- Icon = Owner.Icon;
- ShowIcon = true;
- }
-
- base.OnLoad(e);
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Escape && !e.Handled)
- {
- Close();
- e.Handled = true;
- }
-
- base.OnKeyDown(e);
- }
-
- private void scintilla_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.Control)
- {
- okButton.PerformClick();
- }
- }
-
- private void scintilla_TextChanged(object sender, EventArgs e)
- {
- Script = scintilla.Text;
- }
- }
-}
+using ScintillaNET;
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace Bonsai.Scripting.Expressions.Design
+{
+ public partial class ExpressionScriptEditorDialog : Form
+ {
+ public ExpressionScriptEditorDialog()
+ {
+ InitializeComponent();
+ scintilla.StyleResetDefault();
+ scintilla.Styles[Style.Default].Font = "Consolas";
+ scintilla.Styles[Style.Default].Size = 10;
+ scintilla.StyleClearAll();
+
+ scintilla.CaretLineBackColor = ColorTranslator.FromHtml("#feefff");
+ scintilla.Styles[Style.Cpp.Default].ForeColor = Color.Black;
+ scintilla.Styles[Style.Cpp.Number].ForeColor = Color.Black;
+ scintilla.Styles[Style.Cpp.Character].ForeColor = ColorTranslator.FromHtml("#a31515");
+ scintilla.Styles[Style.Cpp.String].ForeColor = ColorTranslator.FromHtml("#a31515");
+ scintilla.Styles[Style.Cpp.StringEol].ForeColor = ColorTranslator.FromHtml("#a31515");
+ scintilla.Styles[Style.Cpp.Word].ForeColor = ColorTranslator.FromHtml("#0000ff");
+ scintilla.Styles[Style.Cpp.Word2].ForeColor = ColorTranslator.FromHtml("#2b91af");
+ scintilla.Lexer = Lexer.Cpp;
+
+ var types = "Object Boolean Char String SByte Byte Int16 UInt16 Int32 UInt32 Int64 UInt64 Single Double Decimal DateTime DateTimeOffset TimeSpan Guid Math Convert";
+ scintilla.SetKeywords(0, "it iif new outerIt as true false null");
+ scintilla.SetKeywords(1, string.Join(" ", types, types.ToLowerInvariant()));
+ }
+
+ public string Script { get; set; }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ scintilla.Text = Script;
+ scintilla.EmptyUndoBuffer();
+ if (Owner != null)
+ {
+ Icon = Owner.Icon;
+ ShowIcon = true;
+ }
+
+ base.OnLoad(e);
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Escape && !e.Handled)
+ {
+ Close();
+ e.Handled = true;
+ }
+
+ base.OnKeyDown(e);
+ }
+
+ private void scintilla_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.Control)
+ {
+ okButton.PerformClick();
+ }
+ }
+
+ private void scintilla_TextChanged(object sender, EventArgs e)
+ {
+ Script = scintilla.Text;
+ }
+ }
+}
diff --git a/Bonsai.Scripting/ExpressionScriptEditorDialog.resx b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.resx
similarity index 97%
rename from Bonsai.Scripting/ExpressionScriptEditorDialog.resx
rename to Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.resx
index 29dcb1b3a..1af7de150 100644
--- a/Bonsai.Scripting/ExpressionScriptEditorDialog.resx
+++ b/Bonsai.Scripting.Expressions.Design/ExpressionScriptEditorDialog.resx
@@ -1,120 +1,120 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
\ No newline at end of file
diff --git a/Bonsai.Scripting.Expressions/Bonsai.Scripting.Expressions.csproj b/Bonsai.Scripting.Expressions/Bonsai.Scripting.Expressions.csproj
new file mode 100644
index 000000000..fd45ae96f
--- /dev/null
+++ b/Bonsai.Scripting.Expressions/Bonsai.Scripting.Expressions.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Bonsai - Expression Scripting Library
+ Bonsai Scripting Library containing expression scripting infrastructure for Bonsai.
+ Bonsai Rx Scripting Expressions
+ netstandard2.0
+ 3.0.0
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Bonsai.Scripting/ExpressionCondition.cs b/Bonsai.Scripting.Expressions/ExpressionCondition.cs
similarity index 89%
rename from Bonsai.Scripting/ExpressionCondition.cs
rename to Bonsai.Scripting.Expressions/ExpressionCondition.cs
index 44d734861..42657e9f2 100644
--- a/Bonsai.Scripting/ExpressionCondition.cs
+++ b/Bonsai.Scripting.Expressions/ExpressionCondition.cs
@@ -1,67 +1,67 @@
-using Bonsai.Expressions;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reactive.Linq;
-using System.Reflection;
-
-namespace Bonsai.Scripting
-{
- [DefaultProperty("Expression")]
- [WorkflowElementCategory(ElementCategory.Condition)]
- [TypeDescriptionProvider(typeof(ExpressionConditionTypeDescriptionProvider))]
- [Description("An expression script used to determine which values of the input sequence are accepted.")]
- public class ExpressionCondition : SingleArgumentExpressionBuilder, IScriptingElement
- {
- static readonly MethodInfo whereMethod = typeof(Observable).GetMethods()
- .Single(m => m.Name == "Where" &&
- m.GetParameters().Length == 2 &&
- m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>));
-
- public ExpressionCondition()
- {
- Expression = "it";
- }
-
- [Category("Design")]
- [Externalizable(false)]
- [Description("The name of the expression condition.")]
- public string Name { get; set; }
-
- [Category("Design")]
- [Externalizable(false)]
- [Description("A description for the expression condition.")]
- [Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
- public string Description { get; set; }
-
- [Editor("Bonsai.Scripting.ExpressionScriptEditor, Bonsai.Scripting", DesignTypes.UITypeEditor)]
- [Description("The expression that determines which elements to filter.")]
- public string Expression { get; set; }
-
- public override Expression Build(IEnumerable arguments)
- {
- var source = arguments.First();
- var sourceType = source.Type.GetGenericArguments()[0];
- var predicate = global::System.Linq.Dynamic.DynamicExpression.ParseLambda(sourceType, typeof(bool), Expression);
- return System.Linq.Expressions.Expression.Call(whereMethod.MakeGenericMethod(sourceType), source, predicate);
- }
-
- class ExpressionConditionTypeDescriptionProvider : TypeDescriptionProvider
- {
- static readonly TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(typeof(ExpressionCondition));
-
- public ExpressionConditionTypeDescriptionProvider()
- : base(parentProvider)
- {
- }
-
- public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
- {
- return new ScriptingElementTypeDescriptor(instance,
- "An expression that is used to filter individual elements of the input sequence.");
- }
- }
- }
-}
+using Bonsai.Expressions;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reactive.Linq;
+using System.Reflection;
+
+namespace Bonsai.Scripting.Expressions
+{
+ [DefaultProperty("Expression")]
+ [WorkflowElementCategory(ElementCategory.Condition)]
+ [TypeDescriptionProvider(typeof(ExpressionConditionTypeDescriptionProvider))]
+ [Description("An expression script used to determine which values of the input sequence are accepted.")]
+ public class ExpressionCondition : SingleArgumentExpressionBuilder, IScriptingElement
+ {
+ static readonly MethodInfo whereMethod = typeof(Observable).GetMethods()
+ .Single(m => m.Name == "Where" &&
+ m.GetParameters().Length == 2 &&
+ m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>));
+
+ public ExpressionCondition()
+ {
+ Expression = "it";
+ }
+
+ [Category("Design")]
+ [Externalizable(false)]
+ [Description("The name of the expression condition.")]
+ public string Name { get; set; }
+
+ [Category("Design")]
+ [Externalizable(false)]
+ [Description("A description for the expression condition.")]
+ [Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
+ public string Description { get; set; }
+
+ [Editor("Bonsai.Scripting.Expressions.Design.ExpressionScriptEditor, Bonsai.Scripting.Expressions.Design", DesignTypes.UITypeEditor)]
+ [Description("The expression that determines which elements to filter.")]
+ public string Expression { get; set; }
+
+ public override Expression Build(IEnumerable arguments)
+ {
+ var source = arguments.First();
+ var sourceType = source.Type.GetGenericArguments()[0];
+ var predicate = global::System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(sourceType, typeof(bool), Expression);
+ return System.Linq.Expressions.Expression.Call(whereMethod.MakeGenericMethod(sourceType), source, predicate);
+ }
+
+ class ExpressionConditionTypeDescriptionProvider : TypeDescriptionProvider
+ {
+ static readonly TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(typeof(ExpressionCondition));
+
+ public ExpressionConditionTypeDescriptionProvider()
+ : base(parentProvider)
+ {
+ }
+
+ public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
+ {
+ return new ScriptingElementTypeDescriptor(instance,
+ "An expression that is used to filter individual elements of the input sequence.");
+ }
+ }
+ }
+}
diff --git a/Bonsai.Scripting/ExpressionSink.cs b/Bonsai.Scripting.Expressions/ExpressionSink.cs
similarity index 89%
rename from Bonsai.Scripting/ExpressionSink.cs
rename to Bonsai.Scripting.Expressions/ExpressionSink.cs
index 115006bcf..5cf30dfad 100644
--- a/Bonsai.Scripting/ExpressionSink.cs
+++ b/Bonsai.Scripting.Expressions/ExpressionSink.cs
@@ -1,69 +1,69 @@
-using Bonsai.Expressions;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reactive.Linq;
-using System.Reflection;
-
-namespace Bonsai.Scripting
-{
- [DefaultProperty("Expression")]
- [WorkflowElementCategory(ElementCategory.Sink)]
- [TypeDescriptionProvider(typeof(ExpressionSinkTypeDescriptionProvider))]
- [Description("An expression script used to operate on individual values of the input sequence.")]
- public class ExpressionSink : SingleArgumentExpressionBuilder, IScriptingElement
- {
- static readonly MethodInfo doMethod = typeof(Observable).GetMethods()
- .Single(m => m.Name == "Do" &&
- m.GetParameters().Length == 2 &&
- m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Action<>));
-
- [Category("Design")]
- [Externalizable(false)]
- [Description("The name of the expression sink.")]
- public string Name { get; set; }
-
- [Category("Design")]
- [Externalizable(false)]
- [Description("A description for the expression sink.")]
- [Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
- public string Description { get; set; }
-
- [Editor("Bonsai.Scripting.ExpressionScriptEditor, Bonsai.Scripting", DesignTypes.UITypeEditor)]
- [Description("The expression that determines the action to perform on the input elements.")]
- public string Expression { get; set; }
-
- public override Expression Build(IEnumerable arguments)
- {
- var expression = Expression;
- var source = arguments.First();
- if (!string.IsNullOrEmpty(expression))
- {
- var sourceType = source.Type.GetGenericArguments()[0];
- var actionType = System.Linq.Expressions.Expression.GetActionType(sourceType);
- var itParameter = new[] { System.Linq.Expressions.Expression.Parameter(sourceType, string.Empty) };
- var onNext = global::System.Linq.Dynamic.DynamicExpression.ParseLambda(actionType, itParameter, null, Expression);
- return System.Linq.Expressions.Expression.Call(doMethod.MakeGenericMethod(sourceType), source, onNext);
- }
- else return source;
- }
-
- class ExpressionSinkTypeDescriptionProvider : TypeDescriptionProvider
- {
- static readonly TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(typeof(ExpressionSink));
-
- public ExpressionSinkTypeDescriptionProvider()
- : base(parentProvider)
- {
- }
-
- public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
- {
- return new ScriptingElementTypeDescriptor(instance,
- "An expression that is used to perform an action on individual elements of the input sequence.");
- }
- }
- }
-}
+using Bonsai.Expressions;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reactive.Linq;
+using System.Reflection;
+
+namespace Bonsai.Scripting.Expressions
+{
+ [DefaultProperty("Expression")]
+ [WorkflowElementCategory(ElementCategory.Sink)]
+ [TypeDescriptionProvider(typeof(ExpressionSinkTypeDescriptionProvider))]
+ [Description("An expression script used to operate on individual values of the input sequence.")]
+ public class ExpressionSink : SingleArgumentExpressionBuilder, IScriptingElement
+ {
+ static readonly MethodInfo doMethod = typeof(Observable).GetMethods()
+ .Single(m => m.Name == "Do" &&
+ m.GetParameters().Length == 2 &&
+ m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Action<>));
+
+ [Category("Design")]
+ [Externalizable(false)]
+ [Description("The name of the expression sink.")]
+ public string Name { get; set; }
+
+ [Category("Design")]
+ [Externalizable(false)]
+ [Description("A description for the expression sink.")]
+ [Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
+ public string Description { get; set; }
+
+ [Editor("Bonsai.Scripting.Expressions.Design.ExpressionScriptEditor, Bonsai.Scripting.Expressions.Design", DesignTypes.UITypeEditor)]
+ [Description("The expression that determines the action to perform on the input elements.")]
+ public string Expression { get; set; }
+
+ public override Expression Build(IEnumerable arguments)
+ {
+ var expression = Expression;
+ var source = arguments.First();
+ if (!string.IsNullOrEmpty(expression))
+ {
+ var sourceType = source.Type.GetGenericArguments()[0];
+ var actionType = System.Linq.Expressions.Expression.GetActionType(sourceType);
+ var itParameter = new[] { System.Linq.Expressions.Expression.Parameter(sourceType, string.Empty) };
+ var onNext = global::System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(actionType, itParameter, null, Expression);
+ return System.Linq.Expressions.Expression.Call(doMethod.MakeGenericMethod(sourceType), source, onNext);
+ }
+ else return source;
+ }
+
+ class ExpressionSinkTypeDescriptionProvider : TypeDescriptionProvider
+ {
+ static readonly TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(typeof(ExpressionSink));
+
+ public ExpressionSinkTypeDescriptionProvider()
+ : base(parentProvider)
+ {
+ }
+
+ public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
+ {
+ return new ScriptingElementTypeDescriptor(instance,
+ "An expression that is used to perform an action on individual elements of the input sequence.");
+ }
+ }
+ }
+}
diff --git a/Bonsai.Scripting/ExpressionTransform.cs b/Bonsai.Scripting.Expressions/ExpressionTransform.cs
similarity index 89%
rename from Bonsai.Scripting/ExpressionTransform.cs
rename to Bonsai.Scripting.Expressions/ExpressionTransform.cs
index 174b5a4cf..a94110c91 100644
--- a/Bonsai.Scripting/ExpressionTransform.cs
+++ b/Bonsai.Scripting.Expressions/ExpressionTransform.cs
@@ -1,67 +1,67 @@
-using Bonsai.Expressions;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reactive.Linq;
-using System.Reflection;
-
-namespace Bonsai.Scripting
-{
- [DefaultProperty("Expression")]
- [WorkflowElementCategory(ElementCategory.Transform)]
- [TypeDescriptionProvider(typeof(ExpressionTransformTypeDescriptionProvider))]
- [Description("An expression script used to transform individual values of the input sequence.")]
- public class ExpressionTransform : SingleArgumentExpressionBuilder, IScriptingElement
- {
- static readonly MethodInfo selectMethod = typeof(Observable).GetMethods()
- .Single(m => m.Name == "Select" &&
- m.GetParameters().Length == 2 &&
- m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>));
-
- public ExpressionTransform()
- {
- Expression = "it";
- }
-
- [Category("Design")]
- [Externalizable(false)]
- [Description("The name of the expression transform.")]
- public string Name { get; set; }
-
- [Category("Design")]
- [Externalizable(false)]
- [Description("A description for the expression transform.")]
- [Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
- public string Description { get; set; }
-
- [Editor("Bonsai.Scripting.ExpressionScriptEditor, Bonsai.Scripting", DesignTypes.UITypeEditor)]
- [Description("The expression that determines the operation of the transform.")]
- public string Expression { get; set; }
-
- public override Expression Build(IEnumerable arguments)
- {
- var source = arguments.First();
- var sourceType = source.Type.GetGenericArguments()[0];
- var selector = global::System.Linq.Dynamic.DynamicExpression.ParseLambda(sourceType, null, Expression);
- return System.Linq.Expressions.Expression.Call(selectMethod.MakeGenericMethod(sourceType, selector.ReturnType), source, selector);
- }
-
- class ExpressionTransformTypeDescriptionProvider : TypeDescriptionProvider
- {
- static readonly TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(typeof(ExpressionTransform));
-
- public ExpressionTransformTypeDescriptionProvider()
- : base(parentProvider)
- {
- }
-
- public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
- {
- return new ScriptingElementTypeDescriptor(instance,
- "An expression that is used to process and convert individual elements of the input sequence.");
- }
- }
- }
-}
+using Bonsai.Expressions;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reactive.Linq;
+using System.Reflection;
+
+namespace Bonsai.Scripting.Expressions
+{
+ [DefaultProperty("Expression")]
+ [WorkflowElementCategory(ElementCategory.Transform)]
+ [TypeDescriptionProvider(typeof(ExpressionTransformTypeDescriptionProvider))]
+ [Description("An expression script used to transform individual values of the input sequence.")]
+ public class ExpressionTransform : SingleArgumentExpressionBuilder, IScriptingElement
+ {
+ static readonly MethodInfo selectMethod = typeof(Observable).GetMethods()
+ .Single(m => m.Name == "Select" &&
+ m.GetParameters().Length == 2 &&
+ m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>));
+
+ public ExpressionTransform()
+ {
+ Expression = "it";
+ }
+
+ [Category("Design")]
+ [Externalizable(false)]
+ [Description("The name of the expression transform.")]
+ public string Name { get; set; }
+
+ [Category("Design")]
+ [Externalizable(false)]
+ [Description("A description for the expression transform.")]
+ [Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
+ public string Description { get; set; }
+
+ [Editor("Bonsai.Scripting.Expressions.Design.ExpressionScriptEditor, Bonsai.Scripting.Expressions.Design", DesignTypes.UITypeEditor)]
+ [Description("The expression that determines the operation of the transform.")]
+ public string Expression { get; set; }
+
+ public override Expression Build(IEnumerable arguments)
+ {
+ var source = arguments.First();
+ var sourceType = source.Type.GetGenericArguments()[0];
+ var selector = global::System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(sourceType, null, Expression);
+ return System.Linq.Expressions.Expression.Call(selectMethod.MakeGenericMethod(sourceType, selector.ReturnType), source, selector);
+ }
+
+ class ExpressionTransformTypeDescriptionProvider : TypeDescriptionProvider
+ {
+ static readonly TypeDescriptionProvider parentProvider = TypeDescriptor.GetProvider(typeof(ExpressionTransform));
+
+ public ExpressionTransformTypeDescriptionProvider()
+ : base(parentProvider)
+ {
+ }
+
+ public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
+ {
+ return new ScriptingElementTypeDescriptor(instance,
+ "An expression that is used to process and convert individual elements of the input sequence.");
+ }
+ }
+ }
+}
diff --git a/Bonsai.Scripting.Expressions/IScriptingElement.cs b/Bonsai.Scripting.Expressions/IScriptingElement.cs
new file mode 100644
index 000000000..36417da57
--- /dev/null
+++ b/Bonsai.Scripting.Expressions/IScriptingElement.cs
@@ -0,0 +1,7 @@
+namespace Bonsai.Scripting.Expressions
+{
+ interface IScriptingElement : INamedElement
+ {
+ string Description { get; }
+ }
+}
diff --git a/Bonsai.Scripting.Expressions/Properties/AssemblyInfo.cs b/Bonsai.Scripting.Expressions/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..e48fad8a3
--- /dev/null
+++ b/Bonsai.Scripting.Expressions/Properties/AssemblyInfo.cs
@@ -0,0 +1,7 @@
+using Bonsai;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: XmlNamespacePrefix("clr-namespace:Bonsai.Scripting.Expressions", "scr")]
+[assembly: WorkflowNamespaceIcon("Bonsai:ElementIcon.Scripting")]
diff --git a/Bonsai.Scripting/ScriptingElementTypeDescriptor.cs b/Bonsai.Scripting.Expressions/ScriptingElementTypeDescriptor.cs
similarity index 87%
rename from Bonsai.Scripting/ScriptingElementTypeDescriptor.cs
rename to Bonsai.Scripting.Expressions/ScriptingElementTypeDescriptor.cs
index cb8d31826..63d0a4ab5 100644
--- a/Bonsai.Scripting/ScriptingElementTypeDescriptor.cs
+++ b/Bonsai.Scripting.Expressions/ScriptingElementTypeDescriptor.cs
@@ -1,33 +1,33 @@
-using System;
-using System.ComponentModel;
-
-namespace Bonsai.Scripting
-{
- class ScriptingElementTypeDescriptor : CustomTypeDescriptor
- {
- readonly IScriptingElement element;
- readonly string defaultDescription;
-
- public ScriptingElementTypeDescriptor(object instance, string description)
- {
- if (instance == null)
- {
- throw new ArgumentNullException("instance");
- }
-
- element = instance as IScriptingElement;
- defaultDescription = description;
- }
-
- public override AttributeCollection GetAttributes()
- {
- var description = defaultDescription;
- if (element != null && !string.IsNullOrEmpty(element.Description))
- {
- description = element.Description;
- }
-
- return new AttributeCollection(new DescriptionAttribute(description));
- }
- }
-}
+using System;
+using System.ComponentModel;
+
+namespace Bonsai.Scripting.Expressions
+{
+ class ScriptingElementTypeDescriptor : CustomTypeDescriptor
+ {
+ readonly IScriptingElement element;
+ readonly string defaultDescription;
+
+ public ScriptingElementTypeDescriptor(object instance, string description)
+ {
+ if (instance == null)
+ {
+ throw new ArgumentNullException(nameof(instance));
+ }
+
+ element = instance as IScriptingElement;
+ defaultDescription = description;
+ }
+
+ public override AttributeCollection GetAttributes()
+ {
+ var description = defaultDescription;
+ if (element != null && !string.IsNullOrEmpty(element.Description))
+ {
+ description = element.Description;
+ }
+
+ return new AttributeCollection(new DescriptionAttribute(description));
+ }
+ }
+}
diff --git a/Bonsai.Scripting.Python.Design/Bonsai.Scripting.Python.Design.csproj b/Bonsai.Scripting.Python.Design/Bonsai.Scripting.Python.Design.csproj
new file mode 100644
index 000000000..1c4c3ce2a
--- /dev/null
+++ b/Bonsai.Scripting.Python.Design/Bonsai.Scripting.Python.Design.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Bonsai - Python Scripting Design Library
+ Bonsai Design Library containing editor classes for Python scripting in Bonsai.
+ Bonsai Rx Scripting Python Design
+ net5.0-windows10.0.19041
+ 3.0.0
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Bonsai.Scripting/PythonScriptEditor.cs b/Bonsai.Scripting.Python.Design/PythonScriptEditor.cs
similarity index 94%
rename from Bonsai.Scripting/PythonScriptEditor.cs
rename to Bonsai.Scripting.Python.Design/PythonScriptEditor.cs
index 61697a0bf..f2b3835e5 100644
--- a/Bonsai.Scripting/PythonScriptEditor.cs
+++ b/Bonsai.Scripting.Python.Design/PythonScriptEditor.cs
@@ -1,33 +1,33 @@
-using System;
-using System.Drawing.Design;
-using System.ComponentModel;
-using System.Windows.Forms.Design;
-using System.Windows.Forms;
-
-namespace Bonsai.Scripting
-{
- public class PythonScriptEditor : UITypeEditor
- {
- public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
- {
- return UITypeEditorEditStyle.Modal;
- }
-
- public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
- {
- var editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
- if (editorService != null)
- {
- var script = value as string;
- var editorDialog = new PythonScriptEditorDialog();
- editorDialog.Script = script;
- if (editorService.ShowDialog(editorDialog) == DialogResult.OK)
- {
- return editorDialog.Script;
- }
- }
-
- return base.EditValue(context, provider, value);
- }
- }
-}
+using System;
+using System.Drawing.Design;
+using System.ComponentModel;
+using System.Windows.Forms.Design;
+using System.Windows.Forms;
+
+namespace Bonsai.Scripting.Python.Design
+{
+ public class PythonScriptEditor : UITypeEditor
+ {
+ public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
+ {
+ return UITypeEditorEditStyle.Modal;
+ }
+
+ public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
+ {
+ var editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
+ if (editorService != null)
+ {
+ var script = value as string;
+ var editorDialog = new PythonScriptEditorDialog();
+ editorDialog.Script = script;
+ if (editorService.ShowDialog(editorDialog) == DialogResult.OK)
+ {
+ return editorDialog.Script;
+ }
+ }
+
+ return base.EditValue(context, provider, value);
+ }
+ }
+}
diff --git a/Bonsai.Scripting/PythonScriptEditorDialog.Designer.cs b/Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.Designer.cs
similarity index 97%
rename from Bonsai.Scripting/PythonScriptEditorDialog.Designer.cs
rename to Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.Designer.cs
index 7e6d429c7..fb3258e4b 100644
--- a/Bonsai.Scripting/PythonScriptEditorDialog.Designer.cs
+++ b/Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.Designer.cs
@@ -1,96 +1,96 @@
-namespace Bonsai.Scripting
-{
- partial class PythonScriptEditorDialog
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows Form Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.scintilla = new ScintillaNET.Scintilla();
- this.okButton = new System.Windows.Forms.Button();
- this.cancelButton = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // scintilla
- //
- this.scintilla.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
- | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.scintilla.Location = new System.Drawing.Point(12, 12);
- this.scintilla.Name = "scintilla";
- this.scintilla.Size = new System.Drawing.Size(600, 229);
- this.scintilla.TabIndex = 3;
- this.scintilla.TabWidth = 2;
- this.scintilla.UseTabs = false;
- this.scintilla.WrapMode = ScintillaNET.WrapMode.Word;
- this.scintilla.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scintilla_KeyDown);
- this.scintilla.TextChanged += new System.EventHandler(this.scintilla_TextChanged);
- //
- // okButton
- //
- this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
- this.okButton.Location = new System.Drawing.Point(456, 247);
- this.okButton.Name = "okButton";
- this.okButton.Size = new System.Drawing.Size(75, 23);
- this.okButton.TabIndex = 1;
- this.okButton.Text = "OK";
- this.okButton.UseVisualStyleBackColor = true;
- //
- // cancelButton
- //
- this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.cancelButton.Location = new System.Drawing.Point(537, 247);
- this.cancelButton.Name = "cancelButton";
- this.cancelButton.Size = new System.Drawing.Size(75, 23);
- this.cancelButton.TabIndex = 2;
- this.cancelButton.Text = "Cancel";
- this.cancelButton.UseVisualStyleBackColor = true;
- //
- // PythonScriptEditorDialog
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(624, 282);
- this.Controls.Add(this.cancelButton);
- this.Controls.Add(this.okButton);
- this.Controls.Add(this.scintilla);
- this.KeyPreview = true;
- this.MinimumSize = new System.Drawing.Size(640, 320);
- this.Name = "PythonScriptEditorDialog";
- this.ShowIcon = false;
- this.Text = "Python Script";
- this.ResumeLayout(false);
-
- }
-
- #endregion
-
- private ScintillaNET.Scintilla scintilla;
- private System.Windows.Forms.Button okButton;
- private System.Windows.Forms.Button cancelButton;
- }
+namespace Bonsai.Scripting.Python.Design
+{
+ partial class PythonScriptEditorDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.scintilla = new ScintillaNET.Scintilla();
+ this.okButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // scintilla
+ //
+ this.scintilla.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.scintilla.Location = new System.Drawing.Point(12, 12);
+ this.scintilla.Name = "scintilla";
+ this.scintilla.Size = new System.Drawing.Size(600, 229);
+ this.scintilla.TabIndex = 3;
+ this.scintilla.TabWidth = 2;
+ this.scintilla.UseTabs = false;
+ this.scintilla.WrapMode = ScintillaNET.WrapMode.Word;
+ this.scintilla.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scintilla_KeyDown);
+ this.scintilla.TextChanged += new System.EventHandler(this.scintilla_TextChanged);
+ //
+ // okButton
+ //
+ this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.okButton.Location = new System.Drawing.Point(456, 247);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(75, 23);
+ this.okButton.TabIndex = 1;
+ this.okButton.Text = "OK";
+ this.okButton.UseVisualStyleBackColor = true;
+ //
+ // cancelButton
+ //
+ this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point(537, 247);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(75, 23);
+ this.cancelButton.TabIndex = 2;
+ this.cancelButton.Text = "Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ //
+ // PythonScriptEditorDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(624, 282);
+ this.Controls.Add(this.cancelButton);
+ this.Controls.Add(this.okButton);
+ this.Controls.Add(this.scintilla);
+ this.KeyPreview = true;
+ this.MinimumSize = new System.Drawing.Size(640, 320);
+ this.Name = "PythonScriptEditorDialog";
+ this.ShowIcon = false;
+ this.Text = "Python Script";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private ScintillaNET.Scintilla scintilla;
+ private System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.Button cancelButton;
+ }
}
\ No newline at end of file
diff --git a/Bonsai.Scripting/PythonScriptEditorDialog.cs b/Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.cs
similarity index 97%
rename from Bonsai.Scripting/PythonScriptEditorDialog.cs
rename to Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.cs
index 9ca7e5678..ca0a9eaad 100644
--- a/Bonsai.Scripting/PythonScriptEditorDialog.cs
+++ b/Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.cs
@@ -1,79 +1,79 @@
-using ScintillaNET;
-using System;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace Bonsai.Scripting
-{
- public partial class PythonScriptEditorDialog : Form
- {
- public PythonScriptEditorDialog()
- {
- InitializeComponent();
- scintilla.StyleResetDefault();
- scintilla.Styles[Style.Default].Font = "Consolas";
- scintilla.Styles[Style.Default].Size = 10;
- scintilla.StyleClearAll();
-
- scintilla.CaretLineBackColor = ColorTranslator.FromHtml("#feefff");
- scintilla.Styles[Style.Python.Default].ForeColor = Color.Black;
- scintilla.Styles[Style.Python.Character].ForeColor = ColorTranslator.FromHtml("#00aa00");
- scintilla.Styles[Style.Python.ClassName].ForeColor = Color.Black;
- scintilla.Styles[Style.Python.ClassName].Bold = true;
- scintilla.Styles[Style.Python.CommentLine].ForeColor = ColorTranslator.FromHtml("#adadad");
- scintilla.Styles[Style.Python.CommentBlock].ForeColor = ColorTranslator.FromHtml("#adadad");
- scintilla.Styles[Style.Python.DefName].ForeColor = Color.Black;
- scintilla.Styles[Style.Python.DefName].Bold = true;
- scintilla.Styles[Style.Python.Number].ForeColor = ColorTranslator.FromHtml("#800000");
- scintilla.Styles[Style.Python.String].ForeColor = ColorTranslator.FromHtml("#00aa00");
- scintilla.Styles[Style.Python.StringEol].ForeColor = ColorTranslator.FromHtml("#00aa00");
- scintilla.Styles[Style.Python.Triple].ForeColor = ColorTranslator.FromHtml("#adadad");
- scintilla.Styles[Style.Python.TripleDouble].ForeColor = ColorTranslator.FromHtml("#adadad");
- scintilla.Styles[Style.Python.Word].ForeColor = ColorTranslator.FromHtml("#0000ff");
- scintilla.Styles[Style.Python.Word2].ForeColor = ColorTranslator.FromHtml("#900090");
- scintilla.Lexer = Lexer.Python;
-
- scintilla.SetKeywords(0, "and del from not while as elif global or with assert else if pass yield break except import print class exec in raise continue finally is return def for lambda try");
- scintilla.SetKeywords(1, "self None True False abs divmod input open staticmethod all enumerate int ord str any eval isinstance pow sum basestring execfile issubclass print super bin file iter property tuple bool filter len range type bytearray float list raw_input unichr callable format locals reduce unicode chr frozenset long reload vars classmethod getattr map repr xrange cmp globals max reversed zip compile hasattr memoryview round __import__ complex hash min set delattr help next setattr dict hex object slice dir id oct sorted");
- }
-
- public string Script { get; set; }
-
- protected override void OnLoad(EventArgs e)
- {
- scintilla.Text = Script;
- scintilla.EmptyUndoBuffer();
- if (Owner != null)
- {
- Icon = Owner.Icon;
- ShowIcon = true;
- }
-
- base.OnLoad(e);
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Escape && !e.Handled)
- {
- Close();
- e.Handled = true;
- }
-
- base.OnKeyDown(e);
- }
-
- private void scintilla_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.Control)
- {
- okButton.PerformClick();
- }
- }
-
- private void scintilla_TextChanged(object sender, EventArgs e)
- {
- Script = scintilla.Text;
- }
- }
-}
+using ScintillaNET;
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace Bonsai.Scripting.Python.Design
+{
+ public partial class PythonScriptEditorDialog : Form
+ {
+ public PythonScriptEditorDialog()
+ {
+ InitializeComponent();
+ scintilla.StyleResetDefault();
+ scintilla.Styles[Style.Default].Font = "Consolas";
+ scintilla.Styles[Style.Default].Size = 10;
+ scintilla.StyleClearAll();
+
+ scintilla.CaretLineBackColor = ColorTranslator.FromHtml("#feefff");
+ scintilla.Styles[Style.Python.Default].ForeColor = Color.Black;
+ scintilla.Styles[Style.Python.Character].ForeColor = ColorTranslator.FromHtml("#00aa00");
+ scintilla.Styles[Style.Python.ClassName].ForeColor = Color.Black;
+ scintilla.Styles[Style.Python.ClassName].Bold = true;
+ scintilla.Styles[Style.Python.CommentLine].ForeColor = ColorTranslator.FromHtml("#adadad");
+ scintilla.Styles[Style.Python.CommentBlock].ForeColor = ColorTranslator.FromHtml("#adadad");
+ scintilla.Styles[Style.Python.DefName].ForeColor = Color.Black;
+ scintilla.Styles[Style.Python.DefName].Bold = true;
+ scintilla.Styles[Style.Python.Number].ForeColor = ColorTranslator.FromHtml("#800000");
+ scintilla.Styles[Style.Python.String].ForeColor = ColorTranslator.FromHtml("#00aa00");
+ scintilla.Styles[Style.Python.StringEol].ForeColor = ColorTranslator.FromHtml("#00aa00");
+ scintilla.Styles[Style.Python.Triple].ForeColor = ColorTranslator.FromHtml("#adadad");
+ scintilla.Styles[Style.Python.TripleDouble].ForeColor = ColorTranslator.FromHtml("#adadad");
+ scintilla.Styles[Style.Python.Word].ForeColor = ColorTranslator.FromHtml("#0000ff");
+ scintilla.Styles[Style.Python.Word2].ForeColor = ColorTranslator.FromHtml("#900090");
+ scintilla.Lexer = Lexer.Python;
+
+ scintilla.SetKeywords(0, "and del from not while as elif global or with assert else if pass yield break except import print class exec in raise continue finally is return def for lambda try");
+ scintilla.SetKeywords(1, "self None True False abs divmod input open staticmethod all enumerate int ord str any eval isinstance pow sum basestring execfile issubclass print super bin file iter property tuple bool filter len range type bytearray float list raw_input unichr callable format locals reduce unicode chr frozenset long reload vars classmethod getattr map repr xrange cmp globals max reversed zip compile hasattr memoryview round __import__ complex hash min set delattr help next setattr dict hex object slice dir id oct sorted");
+ }
+
+ public string Script { get; set; }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ scintilla.Text = Script;
+ scintilla.EmptyUndoBuffer();
+ if (Owner != null)
+ {
+ Icon = Owner.Icon;
+ ShowIcon = true;
+ }
+
+ base.OnLoad(e);
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Escape && !e.Handled)
+ {
+ Close();
+ e.Handled = true;
+ }
+
+ base.OnKeyDown(e);
+ }
+
+ private void scintilla_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.Control)
+ {
+ okButton.PerformClick();
+ }
+ }
+
+ private void scintilla_TextChanged(object sender, EventArgs e)
+ {
+ Script = scintilla.Text;
+ }
+ }
+}
diff --git a/Bonsai.Scripting/PythonScriptEditorDialog.resx b/Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.resx
similarity index 97%
rename from Bonsai.Scripting/PythonScriptEditorDialog.resx
rename to Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.resx
index 29dcb1b3a..1af7de150 100644
--- a/Bonsai.Scripting/PythonScriptEditorDialog.resx
+++ b/Bonsai.Scripting.Python.Design/PythonScriptEditorDialog.resx
@@ -1,120 +1,120 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
\ No newline at end of file
diff --git a/Bonsai.Scripting.Python/Bonsai.Scripting.Python.csproj b/Bonsai.Scripting.Python/Bonsai.Scripting.Python.csproj
new file mode 100644
index 000000000..f5e7b78a6
--- /dev/null
+++ b/Bonsai.Scripting.Python/Bonsai.Scripting.Python.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Bonsai - Python Scripting Library
+ Bonsai Scripting Library containing Python scripting infrastructure for Bonsai.
+ Bonsai Rx Scripting Python
+ netstandard2.0
+ 3.0.0
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Bonsai.Scripting/IScriptingElement.cs b/Bonsai.Scripting.Python/IScriptingElement.cs
similarity index 72%
rename from Bonsai.Scripting/IScriptingElement.cs
rename to Bonsai.Scripting.Python/IScriptingElement.cs
index 4ee3c1e2f..b6b81833f 100644
--- a/Bonsai.Scripting/IScriptingElement.cs
+++ b/Bonsai.Scripting.Python/IScriptingElement.cs
@@ -1,7 +1,7 @@
-namespace Bonsai.Scripting
-{
- interface IScriptingElement : INamedElement
- {
- string Description { get; }
- }
-}
+namespace Bonsai.Scripting.Python
+{
+ interface IScriptingElement : INamedElement
+ {
+ string Description { get; }
+ }
+}
diff --git a/Bonsai.Scripting/Properties/AssemblyInfo.cs b/Bonsai.Scripting.Python/Properties/AssemblyInfo.cs
similarity index 77%
rename from Bonsai.Scripting/Properties/AssemblyInfo.cs
rename to Bonsai.Scripting.Python/Properties/AssemblyInfo.cs
index cdfc79ed5..2afc5f689 100644
--- a/Bonsai.Scripting/Properties/AssemblyInfo.cs
+++ b/Bonsai.Scripting.Python/Properties/AssemblyInfo.cs
@@ -1,7 +1,7 @@
-using Bonsai;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: XmlNamespacePrefix("clr-namespace:Bonsai.Scripting", "scr")]
-[assembly: WorkflowNamespaceIcon("Bonsai:ElementIcon.Scripting")]
+using Bonsai;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: XmlNamespacePrefix("clr-namespace:Bonsai.Scripting.Python", "py")]
+[assembly: WorkflowNamespaceIcon("Bonsai:ElementIcon.Scripting")]
diff --git a/Bonsai.Scripting/PythonCondition.cs b/Bonsai.Scripting.Python/PythonCondition.cs
similarity index 90%
rename from Bonsai.Scripting/PythonCondition.cs
rename to Bonsai.Scripting.Python/PythonCondition.cs
index 800906f18..c1f9723d8 100644
--- a/Bonsai.Scripting/PythonCondition.cs
+++ b/Bonsai.Scripting.Python/PythonCondition.cs
@@ -1,54 +1,54 @@
-using System;
-using System.Linq;
-using System.ComponentModel;
-using System.Reactive.Linq;
-
-namespace Bonsai.Scripting
-{
- [Obsolete]
- [DefaultProperty("Script")]
- [WorkflowElementCategory(ElementCategory.Condition)]
- [Description("A Python script used to determine which elements of the input sequence are accepted.")]
- public class PythonCondition : Combinator
- {
- public PythonCondition()
- {
- Script = "def process(value):\n return True";
- }
-
- [Editor("Bonsai.Scripting.PythonScriptEditor, Bonsai.Scripting", DesignTypes.UITypeEditor)]
- [Description("The script that determines the criteria for the condition.")]
- public string Script { get; set; }
-
- public override IObservable Process(IObservable source)
- {
- return Observable.Defer(() =>
- {
- var engine = PythonEngine.Create();
- var scope = engine.CreateScope();
- engine.Execute(Script, scope);
-
- object condition;
- PythonProcessor processor;
- if (PythonHelper.TryGetClass(scope, "Condition", out condition))
- {
- processor = new PythonProcessor(engine.Operations, condition);
- }
- else processor = new PythonProcessor(scope);
-
- if (processor.Load != null)
- {
- processor.Load();
- }
-
- var result = source.Where(processor.Process);
- if (processor.Unload != null)
- {
- result = result.Finally(processor.Unload);
- }
-
- return result;
- });
- }
- }
-}
+using System;
+using System.Linq;
+using System.ComponentModel;
+using System.Reactive.Linq;
+
+namespace Bonsai.Scripting.Python
+{
+ [Obsolete]
+ [DefaultProperty("Script")]
+ [WorkflowElementCategory(ElementCategory.Condition)]
+ [Description("A Python script used to determine which elements of the input sequence are accepted.")]
+ public class PythonCondition : Combinator
+ {
+ public PythonCondition()
+ {
+ Script = "def process(value):\n return True";
+ }
+
+ [Editor("Bonsai.Scripting.Python.Design.PythonScriptEditor, Bonsai.Scripting.Python.Design", DesignTypes.UITypeEditor)]
+ [Description("The script that determines the criteria for the condition.")]
+ public string Script { get; set; }
+
+ public override IObservable Process(IObservable source)
+ {
+ return Observable.Defer(() =>
+ {
+ var engine = PythonEngine.Create();
+ var scope = engine.CreateScope();
+ engine.Execute(Script, scope);
+
+ object condition;
+ PythonProcessor processor;
+ if (PythonHelper.TryGetClass(scope, "Condition", out condition))
+ {
+ processor = new PythonProcessor(engine.Operations, condition);
+ }
+ else processor = new PythonProcessor(scope);
+
+ if (processor.Load != null)
+ {
+ processor.Load();
+ }
+
+ var result = source.Where(processor.Process);
+ if (processor.Unload != null)
+ {
+ result = result.Finally(processor.Unload);
+ }
+
+ return result;
+ });
+ }
+ }
+}
diff --git a/Bonsai.Scripting/PythonEngine.cs b/Bonsai.Scripting.Python/PythonEngine.cs
similarity index 79%
rename from Bonsai.Scripting/PythonEngine.cs
rename to Bonsai.Scripting.Python/PythonEngine.cs
index dfd9f886a..71038b25e 100644
--- a/Bonsai.Scripting/PythonEngine.cs
+++ b/Bonsai.Scripting.Python/PythonEngine.cs
@@ -1,15 +1,14 @@
-using IronPython.Hosting;
-using Microsoft.Scripting.Hosting;
+using Microsoft.Scripting.Hosting;
using System.IO;
using System.Reflection;
-namespace Bonsai.Scripting
+namespace Bonsai.Scripting.Python
{
static class PythonEngine
{
internal static ScriptEngine Create()
{
- var engine = Python.CreateEngine();
+ var engine = global::IronPython.Hosting.Python.CreateEngine();
var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var libPath = Directory.GetDirectories(Path.Combine(basePath, "../../../"), "IronPython.StdLib.*");
if (libPath.Length == 1)
diff --git a/Bonsai.Scripting/PythonHelper.cs b/Bonsai.Scripting.Python/PythonHelper.cs
similarity index 96%
rename from Bonsai.Scripting/PythonHelper.cs
rename to Bonsai.Scripting.Python/PythonHelper.cs
index 1d2448cdb..78f0fd143 100644
--- a/Bonsai.Scripting/PythonHelper.cs
+++ b/Bonsai.Scripting.Python/PythonHelper.cs
@@ -1,70 +1,70 @@
-using IronPython.Runtime;
-using IronPython.Runtime.Types;
-using Microsoft.Scripting.Hosting;
-using System;
-
-namespace Bonsai.Scripting
-{
- static class PythonHelper
- {
- internal const string ReturnsDecorator = "import clr\ndef returns(type):\n def decorator(func):\n func.__returntype__ = clr.GetClrType(type)\n return func\n return decorator\n\n";
- internal const string ReturnTypeAttribute = "__returntype__";
- internal const string LoadFunction = "load";
- internal const string UnloadFunction = "unload";
- internal const string ProcessFunction = "process";
- internal const string GenerateFunction = "generate";
-
- internal static bool TryGetClass(ScriptScope scope, string className, out object pythonClass)
- {
- object variable;
- if (scope.TryGetVariable