diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a1fd340e..8b7f41929 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
- Python operator method will call C# operator method for supported binary and unary operators ([#1324][p1324]).
- Add GetPythonThreadID and Interrupt methods in PythonEngine
- Ability to implement delegates with `ref` and `out` parameters in Python, by returning the modified parameter values in a tuple. ([#1355][i1355])
+- Add very simple example editor
### Changed
- Drop support for Python 2, 3.4, and 3.5
diff --git a/Editor/Editor.csproj b/Editor/Editor.csproj
new file mode 100644
index 000000000..f935e391e
--- /dev/null
+++ b/Editor/Editor.csproj
@@ -0,0 +1,31 @@
+
+
+
+ net472;netcoreapp3.1
+ x64;x86
+ WinExe
+ 9.0
+ true
+ true
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
\ No newline at end of file
diff --git a/Editor/Forms/MainForm.Designer.cs b/Editor/Forms/MainForm.Designer.cs
new file mode 100644
index 000000000..42794b2f9
--- /dev/null
+++ b/Editor/Forms/MainForm.Designer.cs
@@ -0,0 +1,202 @@
+
+namespace Editor.Forms
+{
+ partial class MainForm
+ {
+ ///
+ /// 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._mainToolStrip = new System.Windows.Forms.ToolStrip();
+ this._loadScriptToolStripButton = new System.Windows.Forms.ToolStripButton();
+ this._runToolStripButton = new System.Windows.Forms.ToolStripButton();
+ this._stopToolStripButton = new System.Windows.Forms.ToolStripButton();
+ this._examplesToolStripDropDownButton = new System.Windows.Forms.ToolStripDropDownButton();
+ this._helloWorldToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this._interruptToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this._messageBoxToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this._mainSplitContainer = new System.Windows.Forms.SplitContainer();
+ this._scriptRichTextBox = new System.Windows.Forms.RichTextBox();
+ this._outputRichTextBox = new System.Windows.Forms.RichTextBox();
+ this._mainToolStrip.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this._mainSplitContainer)).BeginInit();
+ this._mainSplitContainer.Panel1.SuspendLayout();
+ this._mainSplitContainer.Panel2.SuspendLayout();
+ this._mainSplitContainer.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // _mainToolStrip
+ //
+ this._mainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this._loadScriptToolStripButton,
+ this._runToolStripButton,
+ this._stopToolStripButton,
+ this._examplesToolStripDropDownButton});
+ this._mainToolStrip.Location = new System.Drawing.Point(0, 0);
+ this._mainToolStrip.Name = "_mainToolStrip";
+ this._mainToolStrip.Size = new System.Drawing.Size(1008, 25);
+ this._mainToolStrip.TabIndex = 3;
+ this._mainToolStrip.Text = "toolStrip1";
+ //
+ // _loadScriptToolStripButton
+ //
+ this._loadScriptToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this._loadScriptToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this._loadScriptToolStripButton.Name = "_loadScriptToolStripButton";
+ this._loadScriptToolStripButton.Size = new System.Drawing.Size(79, 22);
+ this._loadScriptToolStripButton.Text = "Load Script...";
+ this._loadScriptToolStripButton.Click += new System.EventHandler(this.LoadScriptToolStripButtonClick);
+ //
+ // _runToolStripButton
+ //
+ this._runToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this._runToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this._runToolStripButton.Name = "_runToolStripButton";
+ this._runToolStripButton.Size = new System.Drawing.Size(32, 22);
+ this._runToolStripButton.Text = "Run";
+ this._runToolStripButton.Click += new System.EventHandler(this.RunToolStripButtonClick);
+ //
+ // _stopToolStripButton
+ //
+ this._stopToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this._stopToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this._stopToolStripButton.Name = "_stopToolStripButton";
+ this._stopToolStripButton.Size = new System.Drawing.Size(35, 22);
+ this._stopToolStripButton.Text = "Stop";
+ this._stopToolStripButton.Click += new System.EventHandler(this.StopToolStripButtonClick);
+ //
+ // _examplesToolStripDropDownButton
+ //
+ this._examplesToolStripDropDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this._examplesToolStripDropDownButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this._helloWorldToolStripMenuItem,
+ this._interruptToolStripMenuItem,
+ this._messageBoxToolStripMenuItem});
+ this._examplesToolStripDropDownButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this._examplesToolStripDropDownButton.Name = "_examplesToolStripDropDownButton";
+ this._examplesToolStripDropDownButton.Size = new System.Drawing.Size(70, 22);
+ this._examplesToolStripDropDownButton.Text = "Examples";
+ //
+ // _helloWorldToolStripMenuItem
+ //
+ this._helloWorldToolStripMenuItem.Name = "_helloWorldToolStripMenuItem";
+ this._helloWorldToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
+ this._helloWorldToolStripMenuItem.Text = "Hello World";
+ this._helloWorldToolStripMenuItem.Click += new System.EventHandler(this.HelloWorldToolStripMenuItemClick);
+ //
+ // _interruptToolStripMenuItem
+ //
+ this._interruptToolStripMenuItem.Name = "_interruptToolStripMenuItem";
+ this._interruptToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
+ this._interruptToolStripMenuItem.Text = "Interrupt Thread Sleep";
+ this._interruptToolStripMenuItem.Click += new System.EventHandler(this.InterruptToolStripMenuItemClick);
+ //
+ // _messageBoxToolStripMenuItem
+ //
+ this._messageBoxToolStripMenuItem.Name = "_messageBoxToolStripMenuItem";
+ this._messageBoxToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
+ this._messageBoxToolStripMenuItem.Text = "Message Box";
+ this._messageBoxToolStripMenuItem.Click += new System.EventHandler(this.MessageBoxToolStripMenuItemClick);
+ //
+ // _mainSplitContainer
+ //
+ this._mainSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+ this._mainSplitContainer.Location = new System.Drawing.Point(0, 25);
+ this._mainSplitContainer.Name = "_mainSplitContainer";
+ this._mainSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // _mainSplitContainer.Panel1
+ //
+ this._mainSplitContainer.Panel1.Controls.Add(this._scriptRichTextBox);
+ //
+ // _mainSplitContainer.Panel2
+ //
+ this._mainSplitContainer.Panel2.Controls.Add(this._outputRichTextBox);
+ this._mainSplitContainer.Size = new System.Drawing.Size(1008, 704);
+ this._mainSplitContainer.SplitterDistance = 336;
+ this._mainSplitContainer.TabIndex = 4;
+ //
+ // _scriptRichTextBox
+ //
+ this._scriptRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this._scriptRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this._scriptRichTextBox.Location = new System.Drawing.Point(0, 0);
+ this._scriptRichTextBox.Name = "_scriptRichTextBox";
+ this._scriptRichTextBox.Size = new System.Drawing.Size(1008, 336);
+ this._scriptRichTextBox.TabIndex = 2;
+ this._scriptRichTextBox.Text = "";
+ this._scriptRichTextBox.TextChanged += new System.EventHandler(this.ScriptRichTextBoxTextChanged);
+ //
+ // _outputRichTextBox
+ //
+ this._outputRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this._outputRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this._outputRichTextBox.Location = new System.Drawing.Point(0, 0);
+ this._outputRichTextBox.Name = "_outputRichTextBox";
+ this._outputRichTextBox.ReadOnly = true;
+ this._outputRichTextBox.Size = new System.Drawing.Size(1008, 364);
+ this._outputRichTextBox.TabIndex = 1;
+ this._outputRichTextBox.Text = "";
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(1008, 729);
+ this.Controls.Add(this._mainSplitContainer);
+ this.Controls.Add(this._mainToolStrip);
+ this.MinimumSize = new System.Drawing.Size(800, 600);
+ this.Name = "MainForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Editor";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainFormFormClosing);
+ this.Load += new System.EventHandler(this.MainFormLoad);
+ this._mainToolStrip.ResumeLayout(false);
+ this._mainToolStrip.PerformLayout();
+ this._mainSplitContainer.Panel1.ResumeLayout(false);
+ this._mainSplitContainer.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this._mainSplitContainer)).EndInit();
+ this._mainSplitContainer.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ToolStrip _mainToolStrip;
+ private System.Windows.Forms.ToolStripButton _runToolStripButton;
+ private System.Windows.Forms.ToolStripButton _stopToolStripButton;
+ private System.Windows.Forms.ToolStripDropDownButton _examplesToolStripDropDownButton;
+ private System.Windows.Forms.ToolStripMenuItem _helloWorldToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem _interruptToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem _messageBoxToolStripMenuItem;
+ private System.Windows.Forms.SplitContainer _mainSplitContainer;
+ private System.Windows.Forms.RichTextBox _scriptRichTextBox;
+ private System.Windows.Forms.RichTextBox _outputRichTextBox;
+ private System.Windows.Forms.ToolStripButton _loadScriptToolStripButton;
+ }
+}
+
diff --git a/Editor/Forms/MainForm.cs b/Editor/Forms/MainForm.cs
new file mode 100644
index 000000000..acb4d7cff
--- /dev/null
+++ b/Editor/Forms/MainForm.cs
@@ -0,0 +1,220 @@
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+using Python.Runtime;
+
+namespace Editor.Forms
+{
+ public partial class MainForm : Form
+ {
+ private const string HelloWorldScript = @"print ('Hello, world!')";
+
+ private const string ThreadSleepScript = @"import time
+
+print('Printed immediately.')
+time.sleep(10)
+print('Printed after 10 seconds.')";
+
+ private const string MessageBoxScript = @"import tkinter
+from tkinter import messagebox
+
+top = tkinter.Tk()
+def hello():
+ messagebox.showinfo('Say Hello', 'Hello World!')
+
+button = tkinter.Button(top, text = 'Say Hello', command = hello)
+button.pack()
+
+top.mainloop()";
+
+ private IntPtr _threadState;
+
+ ulong _pythonThreadID;
+
+ Output _output;
+
+ private void MainFormLoad(object sender, System.EventArgs e)
+ {
+ _stopToolStripButton.Enabled = false;
+
+ if (Environment.GetEnvironmentVariable("PYTHONPATH") is null)
+ {
+ MessageBox.Show(
+ "PYTHONPATH is missing from the Environment Variables.",
+ "Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ Environment.Exit(1);
+ }
+
+ string pythonHome = Environment.GetEnvironmentVariable("PYTHONHOME");
+ if (pythonHome is null)
+ {
+ MessageBox.Show(
+ "PYTHONHOME is missing from the Environment Variables.",
+ "Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ Environment.Exit(1);
+ }
+
+ for (int i = 9; i > 5; i--)
+ {
+ string pythonDLLPath = Path.Combine(pythonHome, $"python3{i}.dll");
+ if (File.Exists(pythonDLLPath))
+ {
+ Runtime.PythonDLL = pythonDLLPath;
+ break;
+ }
+ }
+
+ if (string.IsNullOrWhiteSpace(Runtime.PythonDLL))
+ {
+ MessageBox.Show(
+ "Could not find PythonDLL.",
+ "Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ Environment.Exit(1);
+ }
+
+ try
+ {
+ PythonEngine.Initialize();
+ _threadState = PythonEngine.BeginAllowThreads();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(
+ ex.ToString(),
+ "Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ Environment.Exit(1);
+ }
+
+ RichTextBoxStreamWriter richTextBoxStreamWriter = new RichTextBoxStreamWriter(_outputRichTextBox);
+ _output = new Output(richTextBoxStreamWriter);
+
+ string[] args = Environment.GetCommandLineArgs();
+ if (args.Length > 1)
+ {
+ string filePath = args[1];
+ if (File.Exists(filePath))
+ {
+ string scriptText = File.ReadAllText(filePath);
+ _scriptRichTextBox.Text = scriptText;
+ }
+ }
+ else
+ {
+ _scriptRichTextBox.Text = HelloWorldScript;
+ }
+ }
+
+ private void MainFormFormClosing(object sender, FormClosingEventArgs e)
+ {
+ if (!_runToolStripButton.Enabled && !_stopToolStripButton.Enabled)
+ {
+ StopToolStripButtonClick(null, new EventArgs());
+ }
+
+ try
+ {
+ PythonEngine.EndAllowThreads(_threadState);
+ PythonEngine.Shutdown();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(
+ ex.ToString(),
+ "Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ Environment.Exit(1);
+ }
+ }
+
+ private void LoadScriptToolStripButtonClick(object sender, EventArgs e)
+ {
+ OpenFileDialog openFileDialog = new OpenFileDialog();
+ openFileDialog.Filter = "Python files (*.py)|*.py";
+ DialogResult dialogResult = openFileDialog.ShowDialog();
+ if (dialogResult == DialogResult.OK)
+ {
+ _scriptRichTextBox.Text = File.ReadAllText(openFileDialog.FileName);
+ }
+ }
+
+ private void RunToolStripButtonClick(object sender, EventArgs e)
+ {
+ _loadScriptToolStripButton.Enabled = false;
+ _runToolStripButton.Enabled = false;
+ _stopToolStripButton.Enabled = true;
+ _examplesToolStripDropDownButton.Enabled = false;
+ _scriptRichTextBox.Enabled = false;
+ string scriptText = _scriptRichTextBox.Text;
+ _outputRichTextBox.Text = string.Empty;
+ TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
+ Task.Factory.StartNew(
+ () =>
+ {
+ using (Py.GIL())
+ {
+ _pythonThreadID = PythonEngine.GetPythonThreadID();
+ dynamic sys = Py.Import("sys");
+ sys.stdout = _output;
+ sys.stderr = _output;
+ PythonEngine.RunSimpleString(scriptText);
+ }
+ }).ContinueWith(
+ task =>
+ {
+ _loadScriptToolStripButton.Enabled = true;
+ _runToolStripButton.Enabled = true;
+ _stopToolStripButton.Enabled = false;
+ _examplesToolStripDropDownButton.Enabled = true;
+ _scriptRichTextBox.Enabled = true;
+ },
+ uiScheduler);
+ }
+
+ private void StopToolStripButtonClick(object sender, EventArgs e)
+ {
+ _stopToolStripButton.Enabled = false;
+
+ using (Py.GIL())
+ {
+ PythonEngine.Interrupt(_pythonThreadID);
+ }
+ }
+
+ private void HelloWorldToolStripMenuItemClick(object sender, EventArgs e)
+ {
+ _scriptRichTextBox.Text = HelloWorldScript;
+ }
+
+ private void InterruptToolStripMenuItemClick(object sender, EventArgs e)
+ {
+ _scriptRichTextBox.Text = ThreadSleepScript;
+ }
+
+ private void MessageBoxToolStripMenuItemClick(object sender, EventArgs e)
+ {
+ _scriptRichTextBox.Text = MessageBoxScript;
+ }
+
+ private void ScriptRichTextBoxTextChanged(object sender, EventArgs e)
+ {
+ _runToolStripButton.Enabled = !string.IsNullOrWhiteSpace(_scriptRichTextBox.Text);
+ }
+
+ public MainForm()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Editor/Forms/MainForm.resx b/Editor/Forms/MainForm.resx
new file mode 100644
index 000000000..f413e8efd
--- /dev/null
+++ b/Editor/Forms/MainForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Editor/Output.cs b/Editor/Output.cs
new file mode 100644
index 000000000..6fd4ee255
--- /dev/null
+++ b/Editor/Output.cs
@@ -0,0 +1,59 @@
+
+using System;
+using System.IO;
+
+namespace Editor
+{
+ public class Output
+ {
+ private TextWriter _textWriter = null;
+
+ public void write(string str)
+ {
+ if (_textWriter != null)
+ {
+ _textWriter.Write(str);
+ }
+ else
+ {
+ Console.Write(str);
+ }
+ }
+
+ public void writelines(string[] str)
+ {
+ foreach (string line in str)
+ {
+ if (_textWriter != null)
+ {
+ _textWriter.Write(line);
+ }
+ else
+ {
+ Console.Write(line);
+ }
+ }
+ }
+
+ public void flush()
+ {
+ if (_textWriter != null)
+ {
+ _textWriter.Flush();
+ }
+ }
+
+ public void close()
+ {
+ if (_textWriter != null)
+ {
+ _textWriter.Close();
+ }
+ }
+
+ public Output(TextWriter textWriter)
+ {
+ _textWriter = textWriter;
+ }
+ }
+}
diff --git a/Editor/Program.cs b/Editor/Program.cs
new file mode 100644
index 000000000..aab7ed006
--- /dev/null
+++ b/Editor/Program.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Windows.Forms;
+
+using Editor.Forms;
+
+namespace Editor
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+#if !NET472
+ Application.SetHighDpiMode(HighDpiMode.SystemAware);
+#endif
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainForm());
+ }
+ }
+}
diff --git a/Editor/Properties/Resources.Designer.cs b/Editor/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..0820ae1cb
--- /dev/null
+++ b/Editor/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Editor.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Editor.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Editor/Properties/Resources.resx b/Editor/Properties/Resources.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/Editor/Properties/Resources.resx
@@ -0,0 +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
+
+
\ No newline at end of file
diff --git a/Editor/RichTextBoxStreamWriter.cs b/Editor/RichTextBoxStreamWriter.cs
new file mode 100644
index 000000000..6acf343f0
--- /dev/null
+++ b/Editor/RichTextBoxStreamWriter.cs
@@ -0,0 +1,29 @@
+
+using System.IO;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Editor
+{
+ public class RichTextBoxStreamWriter : TextWriter
+ {
+ RichTextBox _richTextBox = null;
+
+ public override Encoding Encoding => Encoding.UTF8;
+
+ public override void Write(char value)
+ {
+ base.Write(value);
+ MethodInvoker action = delegate
+ {
+ _richTextBox.AppendText(value.ToString());
+ };
+ _richTextBox.BeginInvoke(action);
+ }
+
+ public RichTextBoxStreamWriter(RichTextBox richTextBox)
+ {
+ _richTextBox = richTextBox;
+ }
+ }
+}
diff --git a/pythonnet.sln b/pythonnet.sln
index c80ee8e60..2134f92f6 100644
--- a/pythonnet.sln
+++ b/pythonnet.sln
@@ -59,6 +59,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{142A6752
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Editor", "Editor\Editor.csproj", "{99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -165,6 +167,18 @@ Global
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x64.Build.0 = Release|Any CPU
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x86.ActiveCfg = Release|Any CPU
{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x86.Build.0 = Release|Any CPU
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Debug|Any CPU.Build.0 = Debug|x64
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Debug|x64.ActiveCfg = Debug|x64
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Debug|x64.Build.0 = Debug|x64
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Debug|x86.ActiveCfg = Debug|x86
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Debug|x86.Build.0 = Debug|x86
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Release|x64.ActiveCfg = Release|x64
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Release|x64.Build.0 = Release|x64
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Release|x86.ActiveCfg = Release|x86
+ {99FE9D2F-0E9A-428D-9F52-83C10EB48FD5}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE