1 """
2 A GTK area that hosts a VTK one, module developed
3 by John Hunter.
4
5 Description
6 ===========
7 Provides a pyGtk vtkRenderWindowInteractor widget. This embeds a
8 vtkRenderWindow inside a GTK widget and uses the
9 vtkGenericRenderWindowInteractor for the event handling. This is
10 similar to GtkVTKRenderWindowInteractor.py.
11
12 The extensions here allow the use of gtkglext rather than gtkgl and
13 pygtk-2 rather than pygtk-0. It requires pygtk-2.0.0 or later.
14
15 There is a working example at the bottom.
16
17 Credits
18 =======
19 John Hunter <jdhunter@ace.bsd.uchicago.edu> developed and tested
20 this code based on VTK's GtkVTKRenderWindow.py and extended it to
21 work with pygtk-2.0.0.
22
23 License
24 =======
25 VTK license.
26
27 """
28
29 import sys
30 import pygtk
31 pygtk.require('2.0')
32 import gtk
33 from gtk import gdk
34 import gtk.gtkgl
35 import vtk
36
38
39 """ Embeds a vtkRenderWindow into a pyGTK widget and uses
40 vtkGenericRenderWindowInteractor for the event handling. This
41 class embeds the RenderWindow correctly. A __getattr__ hook is
42 provided that makes the class behave like a
43 vtkGenericRenderWindowInteractor."""
44
46 gtk.gtkgl.DrawingArea.__init__(self)
47 self.set_double_buffered(False)
48
49 self._RenderWindow = vtk.vtkRenderWindow()
50
51
52 self.__Created = 0
53 self._ActiveButton = 0
54
55 self._Iren = vtk.vtkGenericRenderWindowInteractor()
56 self._Iren.SetRenderWindow(self._RenderWindow)
57 self._Iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
58 self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
59 self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
60 self.ConnectSignals()
61
62
63 self.set_flags(gtk.CAN_FOCUS)
64
66 gtk.gtkgl.DrawingArea.set_size_request(self, w, h)
67 self._RenderWindow.SetSize(w, h)
68 self._Iren.SetSize(w, h)
69 self._Iren.ConfigureEvent()
70
72 self.connect("realize", self.OnRealize)
73 self.connect("expose_event", self.OnExpose)
74 self.connect("configure_event", self.OnConfigure)
75 self.connect("button_press_event", self.OnButtonDown)
76 self.connect("button_release_event", self.OnButtonUp)
77 self.connect("motion_notify_event", self.OnMouseMove)
78 self.connect("enter_notify_event", self.OnEnter)
79 self.connect("leave_notify_event", self.OnLeave)
80 self.connect("key_press_event", self.OnKeyPress)
81 self.connect("delete_event", self.OnDestroy)
82 self.add_events(gdk.EXPOSURE_MASK| gdk.BUTTON_PRESS_MASK |
83 gdk.BUTTON_RELEASE_MASK |
84 gdk.KEY_PRESS_MASK |
85 gdk.POINTER_MOTION_MASK |
86 gdk.POINTER_MOTION_HINT_MASK |
87 gdk.ENTER_NOTIFY_MASK | gdk.LEAVE_NOTIFY_MASK)
88
90 """Makes the object behave like a
91 vtkGenericRenderWindowInteractor"""
92 if attr == '__vtk__':
93 return lambda t=self._Iren: t
94 elif hasattr(self._Iren, attr):
95 return getattr(self._Iren, attr)
96 else:
97 raise AttributeError, self.__class__.__name__ + \
98 " has no attribute named " + attr
99
101 gtk.timeout_add(10, self._Iren.TimerEvent)
102
104 """The timer is a one shot timer so will expire automatically."""
105 return 1
106
108 return self._RenderWindow
109
112
114 if self.__Created:
115 self._RenderWindow.Render()
116
118 if self.__Created == 0:
119
120 self.realize()
121 if sys.platform=='win32':
122 win_id = str(self.widget.window.handle)
123 else:
124 win_id = str(self.widget.window.xid)
125
126 self._RenderWindow.SetWindowInfo(win_id)
127
128 self.__Created = 1
129 return True
130
137
139 self.Render()
140 return True
141
143 self.hide()
144 del self._RenderWindow
145 self.destroy()
146 return True
147
149 ctrl, shift = 0, 0
150 if ((event.state & gdk.CONTROL_MASK) == gdk.CONTROL_MASK):
151 ctrl = 1
152 if ((event.state & gdk.SHIFT_MASK) == gdk.SHIFT_MASK):
153 shift = 1
154 return ctrl, shift
155
174
193
195 """Mouse has moved."""
196 m = self.get_pointer()
197 ctrl, shift = self._GetCtrlShift(event)
198 self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
199 chr(0), 0, None)
200 self._Iren.MouseMoveEvent()
201 return True
202
204 """Entering the vtkRenderWindow."""
205 self.grab_focus()
206 m = self.get_pointer()
207 ctrl, shift = self._GetCtrlShift(event)
208 self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
209 chr(0), 0, None)
210 self._Iren.EnterEvent()
211 return True
212
214 """Leaving the vtkRenderWindow."""
215 m = self.get_pointer()
216 ctrl, shift = self._GetCtrlShift(event)
217 self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
218 chr(0), 0, None)
219 self._Iren.LeaveEvent()
220 return True
221
223 """Key pressed."""
224 m = self.get_pointer()
225 ctrl, shift = self._GetCtrlShift(event)
226 keycode, keysym = event.keyval, event.string
227 key = chr(0)
228 if keycode < 256:
229 key = chr(keycode)
230 self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
231 key, 0, keysym)
232 self._Iren.KeyPressEvent()
233 self._Iren.CharEvent()
234 return True
235
237 "Key released."
238 m = self.get_pointer()
239 ctrl, shift = self._GetCtrlShift(event)
240 keycode, keysym = event.keyval, event.string
241 key = chr(0)
242 if keycode < 256:
243 key = chr(keycode)
244 self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
245 key, 0, keysym)
246 self._Iren.KeyReleaseEvent()
247 return True
248
250 if self.__Created:
251 self._Iren.Initialize()
252
255
258
261
262
263 GtkRenderWindowInteractor = GtkGLExtVTKRenderWindowInteractor
264