Created
October 21, 2011 10:33
-
-
Save yatt/1303534 to your computer and use it in GitHub Desktop.
IronPython - VB.NET Interoperation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Imports Microsoft.Scripting | |
Imports Microsoft.Scripting.Hosting | |
Imports IronPython.Hosting | |
Public Class Form1 | |
Dim beziers As New List(Of Object) | |
Dim working As ArrayList = Nothing | |
Dim ctrls As New List(Of Point) | |
Dim index() As Integer = {-1, -1} | |
Dim focuses() As Integer = {-1, -1} | |
Const dimention As Integer = 3 ' ベジェ曲線の次元 | |
' IronPython | |
Dim engine As ScriptEngine | |
Dim scope As ScriptScope | |
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click | |
beziers.Clear() | |
working = Nothing | |
ctrls = New List(Of Point) | |
index(0) = -1 | |
index(1) = -1 | |
focuses(0) = -1 | |
focuses(1) = -1 | |
Refresh() | |
End Sub | |
Private Sub Panel1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel1.Click | |
If (Control.ModifierKeys And Keys.Shift) = Keys.Shift Then | |
Exit Sub | |
End If | |
If working Is Nothing Then | |
working = New ArrayList | |
End If | |
' 点の記録 | |
Dim p As Point = Panel1.PointToClient(Cursor.Position) | |
working.Add(p) | |
' ベジェ曲線への記録 | |
If working.Count = dimention + 1 Then | |
' IronPython.Runtime.List(Of IronPython.Runtime.PythonTuple) に自動変換してくれるかな? | |
Dim lst As New IronPython.Runtime.List | |
For Each p In working | |
Dim item As New IronPython.Runtime.List | |
item.Add(p.X) | |
item.Add(p.Y) | |
lst.Add(item) | |
ctrls.Add(p) | |
Next | |
Dim args() As Object = {lst, 0.01} | |
Dim bezier As Object = engine.Operations.Invoke(scope.GetVariable("Bezier"), args) | |
beziers.Add(bezier) | |
' 初期化 | |
working = Nothing | |
End If | |
Panel1_Paint(Nothing, Nothing) | |
End Sub | |
Private Sub Panel1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown | |
If (Control.ModifierKeys And Keys.Shift) = Keys.Shift Then | |
' 点の選択 | |
index(0) = focuses(0) | |
index(1) = focuses(1) | |
Debug.Print("select!") | |
End If | |
End Sub | |
Private Sub Panel1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove | |
If (Control.ModifierKeys And Keys.Shift) = Keys.Shift Then | |
If index(0) = -1 Then | |
Exit Sub | |
End If | |
Dim pnt As Point = Panel1.PointToClient(Cursor.Position) | |
Dim lst As New IronPython.Runtime.List | |
lst.Add(pnt.X) | |
lst.Add(pnt.Y) | |
Dim tup As New IronPython.Runtime.PythonTuple(lst) | |
beziers(index(0)).ctrls(index(1)) = tup | |
Else | |
For i = 0 To beziers.Count - 1 | |
Dim lst As IronPython.Runtime.List = beziers(i).ctrls | |
For j = 0 To lst.Count - 1 | |
If IsOvered(New Point(lst(j)(0), lst(j)(1))) Then | |
focuses(0) = i | |
focuses(1) = j | |
Debug.Print("@" & focuses(0) & " " & focuses(1)) | |
End If | |
Next | |
Next | |
End If | |
Refresh() | |
'Debug.Print(Cursor.Position.X & " " & Cursor.Position.Y) | |
End Sub | |
Private Sub Panel1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseUp | |
index(0) = -1 | |
index(1) = -1 | |
focuses(0) = -1 | |
focuses(1) = -1 | |
End Sub | |
Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint | |
Using g As Graphics = Panel1.CreateGraphics | |
g.Clear(Color.White) | |
For Each bezier In beziers | |
' ジェネレータを使って全ての点を取得して描画する | |
Dim gen As IronPython.Runtime.PythonGenerator = engine.Operations.InvokeMember(bezier, "__iter__") | |
Dim lst As New List(Of Point) | |
Try | |
While True | |
Dim pnt As IronPython.Runtime.PythonTuple = gen.next | |
lst.Add(New Point(pnt(0), pnt(1))) | |
End While | |
Catch ex As System.InvalidCastException | |
g.DrawLines(Pens.Black, lst.ToArray) | |
Catch ex As Exception | |
MessageBox.Show(ex.Message) | |
End Try | |
If Not CheckBox1.Checked Then | |
Dim mst As IronPython.Runtime.List = bezier.ctrls | |
For i = 0 To mst.Count - 1 | |
Dim q As Point = New Point(mst(i)(0), mst(i)(1)) | |
If IsOvered(q) Then | |
g.FillRectangle(Brushes.Blue, New Rectangle(New Point(q.X - 2, q.Y - 2), New Size(5, 5))) | |
Else | |
g.FillRectangle(Brushes.Red, New Rectangle(New Point(q.X - 2, q.Y - 2), New Size(5, 5))) | |
End If | |
Next | |
End If | |
Next | |
If Not CheckBox1.Checked Then | |
If Not (working Is Nothing) Then | |
For Each p In working | |
g.FillRectangle(Brushes.Red, New Rectangle(New Point(p.X - 2, p.Y - 2), New Size(5, 5))) | |
Next | |
End If | |
End If | |
End Using | |
End Sub | |
Function IsOvered(ByVal point As Point) | |
'Debug.Print("isOvered: " & Cursor.Position.X & " " & Cursor.Position.Y & "," & point.X & " " & point.Y) | |
Dim q As Point = Panel1.PointToClient(Cursor.Position) | |
Return point.X - 2 <= q.X AndAlso q.X <= point.X + 2 AndAlso point.Y - 2 <= q.Y AndAlso q.Y <= point.Y + 2 | |
End Function | |
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load | |
InitPythonEngine() | |
End Sub | |
Sub InitPythonEngine() | |
engine = Python.CreateEngine() | |
' サーチパス設定(モジュールのインポートに必要) | |
engine.SetSearchPaths(New String() {"..\..\IronPython 2.7\Lib", "..\..\PythonLibrary", "."}) | |
' .py読み込み | |
scope = engine.Runtime.ImportModule("Bezier") | |
End Sub | |
Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged | |
Refresh() | |
End Sub | |
End Class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment