wxxdot.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # wxpython widgets for using Jose Fonseca's cairo graphviz visualizer
4 # Copyright (c) 2010, Willow Garage, Inc.
5 #
6 # Source modified from Jose Fonseca's XDot pgtk widgets. That code is
7 # Copyright 2008 Jose Fonseca
8 #
9 # This program is free software: you can redistribute it and/or modify it
10 # under the terms of the GNU Lesser General Public License as published
11 # by the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU Lesser General Public License for more details.
18 #
19 # You should have received a copy of the GNU Lesser General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22 try:
23  # intentionally use from xdot, instead of from .xdot, because we want to use local xdot for Python2 and system xdot for Python3
24  from xdot.ui.elements import *
25  from xdot.ui.animation import *
26  from xdot.dot.lexer import *
27  from xdot.dot.parser import *
28  import subprocess
29 except:
30  from xdot import *
31 
32 from distutils.version import LooseVersion
33 
34 # Python 3 renamed the unicode type to str, the old str type has been replaced by bytes.
35 if sys.version_info[0] >= 3:
36  unicode = str
37 
38 __all__ = ['WxDotWindow', 'WxDotFrame']
39 
40 # We need to get the wx version with built-in cairo support
41 try:
42  import wxversion
43  if wxversion.checkInstalled("2.8"):
44  wxversion.select("2.8")
45  else:
46  print("wxversion 2.8 is not installed, installed versions are {}".format(wxversion.getInstalled()))
47 except:
48  pass # Python3
49 
50 import wx
51 import wx.lib.wxcairo as wxcairo
52 
53 # This is a crazy hack to get this to work on 64-bit systems
54 try:
55  if 'wxMac' in wx.PlatformInfo:
56  pass # Implement if necessary
57  elif 'wxMSW' in wx.PlatformInfo:
58  pass # Implement if necessary
59  elif 'wxGTK' in wx.PlatformInfo:
60  import ctypes
61  gdkLib = wx.lib.wxcairo._findGDKLib()
62  gdkLib.gdk_cairo_create.restype = ctypes.c_void_p
63 except:
64  pass # Python3
65 
67 
68  def __init__(self, xdotcode):
69  XDotParser.__init__(self,xdotcode)
70  self.subgraph_shapes = {}
71 
72  def parse_subgraph(self):
73  shapes_before = set(self.shapes)
74 
75  id = XDotParser.parse_subgraph(self)
76 
77  new_shapes = set(self.shapes) - shapes_before
78  self.subgraph_shapes[id.decode()] = [s for s in new_shapes if not any([s in ss for ss in self.subgraph_shapes.values()])]
79 
80  return id
81 
82  def parse(self):
83  graph = XDotParser.parse(self)
84  graph.subgraph_shapes = self.subgraph_shapes
85  return graph
86 
87 class WxDragAction(object):
88  def __init__(self, dot_widget):
89  self.dot_widget = dot_widget
90 
91  def on_button_press(self, event):
92  x,y = event.GetPosition()
93  self.startmousex = self.prevmousex = x
94  self.startmousey = self.prevmousey = y
95  self.start()
96 
97  def on_motion_notify(self, event):
98  x,y = event.GetPosition()
99  deltax = self.prevmousex - x
100  deltay = self.prevmousey - y
101  self.drag(deltax, deltay)
102  self.prevmousex = x
103  self.prevmousey = y
104 
105  def on_button_release(self, event):
106  x,y = event.GetPosition()
107  self.stopmousex = x
108  self.stopmousey = y
109  self.stop()
110 
111  def draw(self, cr):
112  pass
113 
114  def start(self):
115  pass
116 
117  def drag(self, deltax, deltay):
118  pass
119 
120  def stop(self):
121  pass
122 
123  def abort(self):
124  pass
125 
126 class WxNullAction(WxDragAction):
127  def on_motion_notify(self, event):
128  pass
129 
130 class WxPanAction(WxDragAction):
131  def start(self):
132  self.dot_widget.set_cursor(wx.CURSOR_SIZING)
133 
134  def drag(self, deltax, deltay):
135  self.dot_widget.x += deltax / self.dot_widget.zoom_ratio
136  self.dot_widget.y += deltay / self.dot_widget.zoom_ratio
137  self.dot_widget.Refresh()
138 
139  def stop(self):
140  self.dot_widget.set_cursor(wx.CURSOR_ARROW)
141 
142  abort = stop
143 
145  def drag(self, deltax, deltay):
146  self.dot_widget.zoom_ratio *= 1.005 ** (deltax + deltay)
147  self.dot_widget.zoom_to_fit_on_resize = False
148  self.dot_widget.Refresh()
149 
150  def stop(self):
151  self.dot_widget.Refresh()
152 
154  def drag(self, deltax, deltay):
155  self.dot_widget.Refresh()
156 
157  def draw(self, cr):
158  cr.save()
159  cr.set_source_rgba(.5, .5, 1.0, 0.25)
160  cr.rectangle(self.startmousex, self.startmousey,
161  self.prevmousex - self.startmousex,
162  self.prevmousey - self.startmousey)
163  cr.fill()
164  cr.set_source_rgba(.5, .5, 1.0, 1.0)
165  cr.set_line_width(1)
166  cr.rectangle(self.startmousex - .5, self.startmousey - .5,
167  self.prevmousex - self.startmousex + 1,
168  self.prevmousey - self.startmousey + 1)
169  cr.stroke()
170  cr.restore()
171 
172  def stop(self):
173  x1, y1 = self.dot_widget.window2graph(self.startmousex,
174  self.startmousey)
175  x2, y2 = self.dot_widget.window2graph(self.stopmousex,
176  self.stopmousey)
177  self.dot_widget.zoom_to_area(x1, y1, x2, y2)
178 
179  def abort(self):
180  self.dot_widget.Refresh()
181 
182 class WxDotWindow(wx.Panel):
183  """wxpython Frame that draws dot graphs."""
184  filter = 'dot'
185 
186  def __init__(self, parent, id):
187  """constructor"""
188  wx.Panel.__init__(self, parent, id)
189 
190  self.graph = Graph()
191  self.openfilename = None
192 
193  self.x, self.y = 0.0, 0.0
194  self.zoom_ratio = 1.0
196  self.animation = NoAnimation(self)
198  self.presstime = None
199  self.highlight = None
200 
201  # Bind events
202  self.Bind(wx.EVT_PAINT, self.OnPaint)
203  self.Bind(wx.EVT_SIZE, self.OnResize)
204 
205  self.Bind(wx.EVT_MOUSEWHEEL, self.OnScroll)
206 
207  self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
208 
209  self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
210 
211  # Callback register
212  self.select_cbs = []
213  self.dc = None
214  self.ctx = None
215  self.items_by_url = {}
216 
217 
219  self.select_cbs.append(cb)
220 
221 
222  def OnResize(self, event):
223  self.Refresh()
224 
225  def OnPaint(self, event):
226  """Redraw the graph."""
227  dc = wx.PaintDC(self)
228 
229  #print dc
230  ctx = wxcairo.ContextFromDC(dc)
231  #ctx = pangocairo.CairoContext(ctx)
232 
233  #print "DRAW"
234 
235  # Get widget size
236  width, height = self.GetSize()
237  #width,height = self.dc.GetSizeTuple()
238 
239  ctx.rectangle(0,0,width,height)
240  ctx.clip()
241 
242  ctx.set_source_rgba(1.0, 1.0, 1.0, 1.0)
243  ctx.paint()
244 
245  ctx.save()
246  ctx.translate(0.5*width, 0.5*height)
247 
248  ctx.scale(self.zoom_ratio, self.zoom_ratio)
249  ctx.translate(-self.x, -self.y)
250  self.graph.draw(ctx, highlight_items=self.highlight)
251  ctx.restore()
252 
253  self.drag_action.draw(ctx)
254 
255  def OnScroll(self, event):
256  """Zoom the view."""
257  if event.GetWheelRotation() > 0:
258  self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT,
259  pos=(event.GetX(), event.GetY()))
260  else:
261  self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT,
262  pos=(event.GetX(), event.GetY()))
263 
264  def OnKeyDown(self, event):
265  """Process key down event."""
266  key = event.GetKeyCode()
267  if key == wx.WXK_LEFT:
268  self.x -= self.POS_INCREMENT/self.zoom_ratio
269  self.Refresh()
270  if key == wx.WXK_RIGHT:
271  self.x += self.POS_INCREMENT/self.zoom_ratio
272  self.Refresh()
273  if key == wx.WXK_UP:
274  self.y -= self.POS_INCREMENT/self.zoom_ratio
275  self.Refresh()
276  if key == wx.WXK_DOWN:
277  self.y += self.POS_INCREMENT/self.zoom_ratio
278  self.Refresh()
279  if key == wx.WXK_PAGEUP:
280  self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT)
281  self.Refresh()
282  if key == wx.WXK_PAGEDOWN:
283  self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT)
284  self.Refresh()
285  if key == wx.WXK_ESCAPE:
286  self.drag_action.abort()
287  self.drag_action = WxNullAction(self)
288  if key == ord('F'):
289  self.zoom_to_fit()
290  if key == ord('R'):
291  self.reload()
292  if key == ord('Q'):
293  self.reload()
294  exit(0)
295 
296 
297  def get_current_pos(self):
298  """Get the current graph position."""
299  return self.x, self.y
300 
301  def set_current_pos(self, x, y):
302  """Set the current graph position."""
303  self.x = x
304  self.y = y
305  self.Refresh()
306 
307  def set_highlight(self, items):
308  """Set a number of items to be hilighted."""
309  if self.highlight != items:
310  self.highlight = items
311  self.Refresh()
312 
313 
314  def set_cursor(self, cursor_type):
315  if LooseVersion(wx.__version__) >= LooseVersion('4.0'):
316  self.cursor = wx.Cursor(cursor_type)
317  else:
318  self.cursor = wx.StockCursor(cursor_type)
319  self.SetCursor(self.cursor)
320 
321 
322  def zoom_image(self, zoom_ratio, center=False, pos=None):
323  """Zoom the graph."""
324  if center:
325  self.x = self.graph.width/2
326  self.y = self.graph.height/2
327  elif pos is not None:
328  width, height = self.GetSize()
329  x, y = pos
330  x -= 0.5*width
331  y -= 0.5*height
332  self.x += x / self.zoom_ratio - x / zoom_ratio
333  self.y += y / self.zoom_ratio - y / zoom_ratio
334  self.zoom_ratio = zoom_ratio
335  self.zoom_to_fit_on_resize = False
336  self.Refresh()
337 
338  def zoom_to_area(self, x1, y1, x2, y2):
339  """Zoom to an area of the graph."""
340  width, height = self.GetSize()
341  area_width = abs(x1 - x2)
342  area_height = abs(y1 - y2)
343  self.zoom_ratio = min(
344  float(width)/float(area_width),
345  float(height)/float(area_height)
346  )
347  self.zoom_to_fit_on_resize = False
348  self.x = (x1 + x2) / 2
349  self.y = (y1 + y2) / 2
350  self.Refresh()
351 
352  def zoom_to_fit(self):
353  """Zoom to fit the size of the graph."""
354  width,height = self.GetSize()
355  x = self.ZOOM_TO_FIT_MARGIN
356  y = self.ZOOM_TO_FIT_MARGIN
357  width -= 2 * self.ZOOM_TO_FIT_MARGIN
358  height -= 2 * self.ZOOM_TO_FIT_MARGIN
359 
360  if float(self.graph.width) > 0 and float(self.graph.height) > 0 and width > 0 and height > 0:
361  zoom_ratio = min(
362  float(width)/float(self.graph.width),
363  float(height)/float(self.graph.height)
364  )
365  self.zoom_image(zoom_ratio, center=True)
366  self.zoom_to_fit_on_resize = True
367 
368  ZOOM_INCREMENT = 1.25
369  ZOOM_TO_FIT_MARGIN = 12
370 
371  def on_zoom_in(self, action):
372  self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT)
373 
374  def on_zoom_out(self, action):
375  self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT)
376 
377  def on_zoom_fit(self, action):
378  self.zoom_to_fit()
379 
380  def on_zoom_100(self, action):
381  self.zoom_image(1.0)
382 
383  POS_INCREMENT = 100
384 
385  def get_drag_action(self, event):
386  """Get a drag action for this click."""
387  # Grab the button
388  button = event.GetButton()
389  # Grab modifier keys
390  control_down = event.ControlDown()
391  alt_down = event.AltDown()
392  shift_down = event.ShiftDown()
393 
394  drag = event.Dragging()
395  motion = event.Moving()
396 
397  # Get the correct drag action for this click
398  if button in (wx.MOUSE_BTN_LEFT, wx.MOUSE_BTN_MIDDLE): # left or middle button
399  if control_down:
400  if shift_down:
401  return WxZoomAreaAction(self)
402  else:
403  return WxZoomAction(self)
404  else:
405  return WxPanAction(self)
406 
407  return WxNullAction(self)
408 
409  def OnMouse(self, event):
410  x,y = event.GetPosition()
411 
412  item = None
413 
414  # Get the item
415  if not event.Dragging():
416  item = self.get_url(x, y)
417  if item is None:
418  item = self.get_jump(x, y)
419 
420  if item is not None:
421  self.set_cursor(wx.CURSOR_HAND)
422  self.set_highlight(item.highlight)
423 
424  for cb in self.select_cbs:
425  cb(item,event)
426  else:
427  self.set_cursor(wx.CURSOR_ARROW)
428  self.set_highlight(None)
429 
430  if item is None:
431  if event.ButtonDown():
432  self.animation.stop()
433  self.drag_action.abort()
434 
435  # Get the drag action
436  self.drag_action = self.get_drag_action(event)
437  self.drag_action.on_button_press(event)
438 
439  self.pressx = x
440  self.pressy = y
441 
442  if event.Dragging() or event.Moving():
443  self.drag_action.on_motion_notify(event)
444 
445  if event.ButtonUp():
446  self.drag_action.on_button_release(event)
447  self.drag_action = WxNullAction(self)
448 
449  event.Skip()
450 
451 
452  def on_area_size_allocate(self, area, allocation):
453  if self.zoom_to_fit_on_resize:
454  self.zoom_to_fit()
455 
456  def animate_to(self, x, y):
457  self.animation = ZoomToAnimation(self, x, y)
458  self.animation.start()
459 
460  def window2graph(self, x, y):
461  "Get the x,y coordinates in the graph from the x,y coordinates in the window."""
462  width, height = self.GetSize()
463  x -= 0.5*width
464  y -= 0.5*height
465  x /= self.zoom_ratio
466  y /= self.zoom_ratio
467  x += self.x
468  y += self.y
469  return x, y
470 
471  def get_url(self, x, y):
472  x, y = self.window2graph(x, y)
473  return self.graph.get_url(x, y)
474 
475  def get_jump(self, x, y):
476  x, y = self.window2graph(x, y)
477  return self.graph.get_jump(x, y)
478 
479  def set_filter(self, filter):
480  self.filter = filter
481 
482  def set_dotcode(self, dotcode, filename='<stdin>'):
483  # Python 3 renamed the unicode type to str, the old str type has been replaced by bytes.
484  if sys.version_info[0] < 3 and isinstance(dotcode, unicode):
485  dotcode = dotcode.encode('utf8')
486  p = subprocess.Popen(
487  [self.filter, '-Txdot'],
488  stdin=subprocess.PIPE,
489  stdout=subprocess.PIPE,
490  stderr=subprocess.PIPE,
491  shell=False,
492  universal_newlines=True
493  )
494  xdotcode, error = p.communicate(dotcode)
495  if p.returncode != 0:
496  print("ERROR PARSING DOT CODE {}".format(error))
497  dialog = Gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
498  message_format=error,
499  buttons=gtk.BUTTONS_OK)
500  dialog.set_title('Dot Viewer')
501  dialog.run()
502  dialog.destroy()
503  return False
504  try:
505  self.set_xdotcode(xdotcode)
506 
507  # Store references to all the items
508  self.items_by_url = {}
509  for item in self.graph.nodes: # + self.graph.edges:
510  if item.url is not None:
511  self.items_by_url[item.url] = item
512 
513  # Store references to subgraph states
514  self.subgraph_shapes = self.graph.subgraph_shapes
515 
516  except ParseError as ex:
517  print("ERROR PARSING XDOT CODE")
518  dialog = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
519  message_format=str(ex),
520  buttons=gtk.BUTTONS_OK)
521  dialog.set_title('Dot Viewer')
522  dialog.run()
523  dialog.destroy()
524  return False
525  else:
526  self.openfilename = filename
527  return True
528 
529  def set_xdotcode(self, xdotcode):
530  """Set xdot code."""
531  #print xdotcode
532  if sys.version_info[0] >= 3:
533  parser = MyXDotParser(xdotcode.encode("utf-8"))
534  else:
535  parser = XDotParser(xdotcode)
536  self.graph = parser.parse()
537  self.highlight = None
538  #self.zoom_image(self.zoom_ratio, center=True)
539 
540  def reload(self):
541  if self.openfilename is not None:
542  try:
543  fp = file(self.openfilename, 'rt')
544  self.set_dotcode(fp.read(), self.openfilename)
545  fp.close()
546  except IOError:
547  pass
548 
549 
550 class WxDotFrame(wx.Frame):
551  def __init__(self):
552  wx.Frame.__init__(self, None, -1, "Dot Viewer", size=(512,512))
553 
554  vbox = wx.BoxSizer(wx.VERTICAL)
555 
556  # Construct toolbar
557  toolbar = wx.ToolBar(self, -1)
558  toolbar.AddLabelTool(wx.ID_OPEN, 'Open File',
559  wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN,wx.ART_OTHER,(16,16)))
560  toolbar.AddLabelTool(wx.ID_HELP, 'Help',
561  wx.ArtProvider.GetBitmap(wx.ART_HELP,wx.ART_OTHER,(16,16)) )
562  toolbar.Realize()
563 
564  self.Bind(wx.EVT_TOOL, self.DoOpenFile, id=wx.ID_OPEN)
565  self.Bind(wx.EVT_TOOL, self.ShowControlsDialog, id=wx.ID_HELP)
566 
567  # Create dot widge
568  self.widget = WxDotWindow(self, -1)
569 
570  # Add elements to sizer
571  vbox.Add(toolbar, 0, wx.EXPAND)
572  vbox.Add(self.widget, 100, wx.EXPAND | wx.ALL)
573 
574  self.SetSizer(vbox)
575  self.Center()
576 
577  def ShowControlsDialog(self,event):
578  dial = wx.MessageDialog(None,
579  "\
580 Pan: Arrow Keys\n\
581 Zoom: PageUp / PageDown\n\
582 Zoom To Fit: F\n\
583 Refresh: R",
584  'Keyboard Controls', wx.OK)
585  dial.ShowModal()
586 
587  def DoOpenFile(self,event):
588  wcd = 'All files (*)|*|GraphViz Dot Files(*.dot)|*.dot|'
589  dir = os.getcwd()
590  open_dlg = wx.FileDialog(self, message='Choose a file', defaultDir=dir, defaultFile='',
591  wildcard=wcd, style=wx.OPEN|wx.CHANGE_DIR)
592  if open_dlg.ShowModal() == wx.ID_OK:
593  path = open_dlg.GetPath()
594 
595  try:
596  self.open_file(path)
597 
598  except IOError as error:
599  dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error))
600  dlg.ShowModal()
601 
602  except UnicodeDecodeError as error:
603  dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error))
604  dlg.ShowModal()
605 
606  open_dlg.Destroy()
607 
608  def OnExit(self, event):
609  pass
610 
611  def set_dotcode(self, dotcode, filename='<stdin>'):
612  if self.widget.set_dotcode(dotcode, filename):
613  self.SetTitle(os.path.basename(filename) + ' - Dot Viewer')
614  self.widget.zoom_to_fit()
615 
616  def set_xdotcode(self, xdotcode, filename='<stdin>'):
617  if self.widget.set_xdotcode(xdotcode):
618  self.SetTitle(os.path.basename(filename) + ' - Dot Viewer')
619  self.widget.zoom_to_fit()
620 
621  def open_file(self, filename):
622  try:
623  fp = file(filename, 'rt')
624  self.set_dotcode(fp.read(), filename)
625  fp.close()
626  except IOError as ex:
627  """
628  dlg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
629  message_format=str(ex),
630  buttons=gtk.BUTTONS_OK)
631  dlg.set_title('Dot Viewer')
632  dlg.run()
633  dlg.destroy()
634  """
635 
636  def set_filter(self, filter):
637  self.widget.set_filter(filter)
638 
smach_viewer.xdot.wxxdot.WxDotWindow.cursor
cursor
Definition: wxxdot.py:316
smach_viewer.xdot.wxxdot.WxDragAction.stopmousex
stopmousex
Definition: wxxdot.py:107
smach_viewer.xdot.wxxdot.WxDotWindow.graph
graph
Definition: wxxdot.py:190
smach_viewer.xdot.wxxdot.WxDotWindow.get_current_pos
def get_current_pos(self)
Helper functions.
Definition: wxxdot.py:297
smach_viewer.xdot.wxxdot.WxDotFrame.set_xdotcode
def set_xdotcode(self, xdotcode, filename='< stdin >')
Definition: wxxdot.py:616
smach_viewer.xdot.wxxdot.WxDotWindow.OnMouse
def OnMouse(self, event)
Definition: wxxdot.py:409
smach_viewer.xdot.wxxdot.WxDragAction.stopmousey
stopmousey
Definition: wxxdot.py:108
lexer
smach_viewer.xdot.wxxdot.WxDragAction.on_button_release
def on_button_release(self, event)
Definition: wxxdot.py:105
smach_viewer.xdot.wxxdot.WxDotWindow.openfilename
openfilename
Definition: wxxdot.py:191
smach_viewer.xdot.wxxdot.WxDotFrame.ShowControlsDialog
def ShowControlsDialog(self, event)
Definition: wxxdot.py:577
smach_viewer.xdot.xdot.NoAnimation
Definition: xdot.py:1352
smach_viewer.xdot.wxxdot.WxDragAction.abort
def abort(self)
Definition: wxxdot.py:123
smach_viewer.xdot.wxxdot.WxDotWindow.OnResize
def OnResize(self, event)
Event handlers.
Definition: wxxdot.py:222
smach_viewer.xdot.wxxdot.WxDotWindow.select_cbs
select_cbs
Definition: wxxdot.py:212
smach_viewer.xdot.wxxdot.WxDotWindow.on_zoom_in
def on_zoom_in(self, action)
Definition: wxxdot.py:371
smach_viewer.xdot.wxxdot.WxNullAction.on_motion_notify
def on_motion_notify(self, event)
Definition: wxxdot.py:127
smach_viewer.xdot.wxxdot.WxDotWindow.dc
dc
Definition: wxxdot.py:213
smach_viewer.xdot.wxxdot.WxDragAction.startmousex
startmousex
Definition: wxxdot.py:93
smach_viewer.xdot.xdot.ZoomToAnimation
Definition: xdot.py:1395
smach_viewer.xdot.wxxdot.WxDotWindow.get_jump
def get_jump(self, x, y)
Definition: wxxdot.py:475
smach_viewer.xdot.wxxdot.WxDotWindow.ZOOM_TO_FIT_MARGIN
int ZOOM_TO_FIT_MARGIN
Definition: wxxdot.py:369
smach_viewer.xdot.wxxdot.WxZoomAreaAction
Definition: wxxdot.py:153
smach_viewer.xdot.wxxdot.WxDotWindow.y
y
Definition: wxxdot.py:193
smach_viewer.xdot.wxxdot.WxDotWindow.zoom_to_fit
def zoom_to_fit(self)
Definition: wxxdot.py:352
smach_viewer.xdot.wxxdot.WxDotWindow.OnScroll
def OnScroll(self, event)
Definition: wxxdot.py:255
smach_viewer.xdot.wxxdot.WxZoomAreaAction.draw
def draw(self, cr)
Definition: wxxdot.py:157
smach_viewer.xdot.wxxdot.WxDotWindow
Definition: wxxdot.py:182
smach_viewer.xdot.wxxdot.WxDotWindow.zoom_to_fit_on_resize
zoom_to_fit_on_resize
Definition: wxxdot.py:195
smach_viewer.xdot.wxxdot.WxDragAction
Definition: wxxdot.py:87
smach_viewer.xdot.wxxdot.WxDotWindow.on_area_size_allocate
def on_area_size_allocate(self, area, allocation)
Definition: wxxdot.py:452
smach_viewer.xdot.wxxdot.WxDragAction.drag
def drag(self, deltax, deltay)
Definition: wxxdot.py:117
smach_viewer.xdot.wxxdot.WxDragAction.stop
def stop(self)
Definition: wxxdot.py:120
smach_viewer.xdot.wxxdot.WxZoomAreaAction.abort
def abort(self)
Definition: wxxdot.py:179
smach_viewer.xdot.wxxdot.WxDotWindow.on_zoom_100
def on_zoom_100(self, action)
Definition: wxxdot.py:380
smach_viewer.xdot.wxxdot.WxDotWindow.zoom_image
def zoom_image(self, zoom_ratio, center=False, pos=None)
Zooming methods.
Definition: wxxdot.py:322
smach_viewer.xdot.wxxdot.WxDotWindow.register_select_callback
def register_select_callback(self, cb)
User callbacks.
Definition: wxxdot.py:218
smach_viewer.xdot.wxxdot.WxNullAction
Definition: wxxdot.py:126
smach_viewer.xdot.wxxdot.WxDotWindow.pressx
pressx
Definition: wxxdot.py:439
smach_viewer.xdot.xdot.Graph
Definition: xdot.py:492
smach_viewer.xdot.xdot.XDotParser.shapes
shapes
Definition: xdot.py:1222
smach_viewer.xdot.wxxdot.WxDotFrame.OnExit
def OnExit(self, event)
Definition: wxxdot.py:608
smach_viewer.xdot.wxxdot.WxDotFrame.__init__
def __init__(self)
Definition: wxxdot.py:551
smach_viewer.xdot.wxxdot.MyXDotParser.parse_subgraph
def parse_subgraph(self)
Definition: wxxdot.py:72
smach_viewer.xdot.wxxdot.WxDragAction.dot_widget
dot_widget
Definition: wxxdot.py:89
smach_viewer.xdot.wxxdot.WxDragAction.on_motion_notify
def on_motion_notify(self, event)
Definition: wxxdot.py:97
elements
smach_viewer.xdot.wxxdot.WxPanAction
Definition: wxxdot.py:130
smach_viewer.xdot.wxxdot.WxZoomAreaAction.drag
def drag(self, deltax, deltay)
Definition: wxxdot.py:154
smach_viewer.xdot.wxxdot.WxDotFrame.widget
widget
Definition: wxxdot.py:568
smach_viewer.xdot.wxxdot.WxDotWindow.pressy
pressy
Definition: wxxdot.py:440
smach_viewer.xdot.wxxdot.WxDotWindow.OnKeyDown
def OnKeyDown(self, event)
Definition: wxxdot.py:264
smach_viewer.xdot.wxxdot.WxZoomAreaAction.stop
def stop(self)
Definition: wxxdot.py:172
smach_viewer.xdot.wxxdot.WxDragAction.prevmousey
prevmousey
Definition: wxxdot.py:94
smach_viewer.xdot.wxxdot.WxDotWindow.set_dotcode
def set_dotcode(self, dotcode, filename='< stdin >')
Definition: wxxdot.py:482
smach_viewer.xdot.wxxdot.WxDotWindow.items_by_url
items_by_url
Definition: wxxdot.py:215
smach_viewer.xdot.wxxdot.WxDotFrame
Definition: wxxdot.py:550
smach_viewer.xdot.wxxdot.WxZoomAction.drag
def drag(self, deltax, deltay)
Definition: wxxdot.py:145
smach_viewer.xdot.wxxdot.WxDotFrame.DoOpenFile
def DoOpenFile(self, event)
Definition: wxxdot.py:587
smach_viewer.xdot.wxxdot.WxDotWindow.zoom_ratio
zoom_ratio
Definition: wxxdot.py:194
smach_viewer.xdot.wxxdot.WxDragAction.__init__
def __init__(self, dot_widget)
Definition: wxxdot.py:88
smach_viewer.xdot.xdot.XDotParser
Definition: xdot.py:1212
smach_viewer.xdot.wxxdot.WxDotFrame.set_dotcode
def set_dotcode(self, dotcode, filename='< stdin >')
Definition: wxxdot.py:611
smach_viewer.xdot.wxxdot.WxDotWindow.zoom_to_area
def zoom_to_area(self, x1, y1, x2, y2)
Definition: wxxdot.py:338
smach_viewer.xdot.xdot_qt.stop
def stop(self)
Definition: xdot_qt.py:1305
smach_viewer.xdot.wxxdot.WxPanAction.start
def start(self)
Definition: wxxdot.py:131
smach_viewer.xdot.wxxdot.WxDotWindow.on_zoom_out
def on_zoom_out(self, action)
Definition: wxxdot.py:374
smach_viewer.xdot.wxxdot.WxDotWindow.get_url
def get_url(self, x, y)
Definition: wxxdot.py:471
smach_viewer.xdot.wxxdot.WxZoomAction.stop
def stop(self)
Definition: wxxdot.py:150
smach_viewer.xdot.wxxdot.WxDotWindow.x
x
Definition: wxxdot.py:303
smach_viewer.xdot.wxxdot.WxDotWindow.subgraph_shapes
subgraph_shapes
Definition: wxxdot.py:514
smach_viewer.xdot.wxxdot.WxDragAction.startmousey
startmousey
Definition: wxxdot.py:94
smach_viewer.xdot.wxxdot.WxDotWindow.set_current_pos
def set_current_pos(self, x, y)
Definition: wxxdot.py:301
smach_viewer.xdot.wxxdot.WxDotWindow.presstime
presstime
Definition: wxxdot.py:198
smach_viewer.xdot.wxxdot.WxDotWindow.drag_action
drag_action
Definition: wxxdot.py:197
smach_viewer.xdot.wxxdot.WxDotWindow.set_filter
def set_filter(self, filter)
Definition: wxxdot.py:479
smach_viewer.xdot.wxxdot.MyXDotParser.parse
def parse(self)
Definition: wxxdot.py:82
smach_viewer.xdot.wxxdot.WxDotWindow.set_xdotcode
def set_xdotcode(self, xdotcode)
Definition: wxxdot.py:529
smach_viewer.xdot.wxxdot.MyXDotParser.__init__
def __init__(self, xdotcode)
Definition: wxxdot.py:68
smach_viewer.xdot.wxxdot.WxDotWindow.POS_INCREMENT
int POS_INCREMENT
Definition: wxxdot.py:383
smach_viewer.xdot.wxxdot.WxDotWindow.window2graph
def window2graph(self, x, y)
Definition: wxxdot.py:460
smach_viewer.xdot.wxxdot.WxDragAction.start
def start(self)
Definition: wxxdot.py:114
smach_viewer.xdot.wxxdot.WxPanAction.stop
def stop(self)
Definition: wxxdot.py:139
smach_viewer.xdot.wxxdot.MyXDotParser.subgraph_shapes
subgraph_shapes
Definition: wxxdot.py:70
smach_viewer.xdot.wxxdot.WxDotWindow.__init__
def __init__(self, parent, id)
Definition: wxxdot.py:186
smach_viewer.xdot.wxxdot.WxDragAction.on_button_press
def on_button_press(self, event)
Definition: wxxdot.py:91
smach_viewer.xdot.wxxdot.WxDotWindow.get_drag_action
def get_drag_action(self, event)
Definition: wxxdot.py:385
smach_viewer.xdot.wxxdot.WxDotWindow.set_highlight
def set_highlight(self, items)
Definition: wxxdot.py:307
smach_viewer.xdot.wxxdot.WxDotWindow.set_cursor
def set_cursor(self, cursor_type)
Cursor manipulation.
Definition: wxxdot.py:314
smach_viewer.xdot.wxxdot.WxDotFrame.open_file
def open_file(self, filename)
Definition: wxxdot.py:621
parser
smach_viewer.xdot.wxxdot.WxDragAction.draw
def draw(self, cr)
Definition: wxxdot.py:111
smach_viewer.xdot.wxxdot.WxDotFrame.set_filter
def set_filter(self, filter)
Definition: wxxdot.py:636
smach_viewer.xdot.wxxdot.WxDotWindow.reload
def reload(self)
Definition: wxxdot.py:540
smach_viewer.xdot.wxxdot.WxDotWindow.ZOOM_INCREMENT
float ZOOM_INCREMENT
Definition: wxxdot.py:368
smach_viewer.xdot.wxxdot.WxPanAction.drag
def drag(self, deltax, deltay)
Definition: wxxdot.py:134
smach_viewer.xdot.wxxdot.WxDotWindow.OnPaint
def OnPaint(self, event)
Definition: wxxdot.py:225
smach_viewer.xdot.wxxdot.WxDotWindow.animation
animation
Definition: wxxdot.py:196
smach_viewer.xdot.wxxdot.MyXDotParser
Definition: wxxdot.py:66
smach_viewer.xdot.wxxdot.WxDotWindow.animate_to
def animate_to(self, x, y)
Definition: wxxdot.py:456
animation
smach_viewer.xdot.wxxdot.WxDotWindow.filter
string filter
Definition: wxxdot.py:184
smach_viewer.xdot.wxxdot.WxDotWindow.on_zoom_fit
def on_zoom_fit(self, action)
Definition: wxxdot.py:377
smach_viewer.xdot.wxxdot.WxDragAction.prevmousex
prevmousex
Definition: wxxdot.py:93
smach_viewer.xdot.wxxdot.WxDotWindow.highlight
highlight
Definition: wxxdot.py:199
smach_viewer.xdot.wxxdot.WxZoomAction
Definition: wxxdot.py:144
smach_viewer.xdot.wxxdot.WxDotWindow.ctx
ctx
Definition: wxxdot.py:214


smach_viewer
Author(s): Jonathan Bohren
autogenerated on Thu Feb 20 2025 03:09:09