SchedGui.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. # SchedGui.py - Python extension for perf trace, basic GUI code for
  2. # traces drawing and overview.
  3. #
  4. # Copyright (C) 2010 by Frederic Weisbecker <fweisbec@gmail.com>
  5. #
  6. # This software is distributed under the terms of the GNU General
  7. # Public License ("GPL") version 2 as published by the Free Software
  8. # Foundation.
  9. try:
  10. import wx
  11. except ImportError:
  12. raise ImportError, "You need to install the wxpython lib for this script"
  13. class RootFrame(wx.Frame):
  14. Y_OFFSET = 100
  15. RECT_HEIGHT = 100
  16. RECT_SPACE = 50
  17. EVENT_MARKING_WIDTH = 5
  18. def __init__(self, sched_tracer, title, parent = None, id = -1):
  19. wx.Frame.__init__(self, parent, id, title)
  20. (self.screen_width, self.screen_height) = wx.GetDisplaySize()
  21. self.screen_width -= 10
  22. self.screen_height -= 10
  23. self.zoom = 0.5
  24. self.scroll_scale = 20
  25. self.sched_tracer = sched_tracer
  26. self.sched_tracer.set_root_win(self)
  27. (self.ts_start, self.ts_end) = sched_tracer.interval()
  28. self.update_width_virtual()
  29. self.nr_rects = sched_tracer.nr_rectangles() + 1
  30. self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
  31. # whole window panel
  32. self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
  33. # scrollable container
  34. self.scroll = wx.ScrolledWindow(self.panel)
  35. self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
  36. self.scroll.EnableScrolling(True, True)
  37. self.scroll.SetFocus()
  38. # scrollable drawing area
  39. self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
  40. self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
  41. self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
  42. self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
  43. self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
  44. self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
  45. self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
  46. self.scroll.Fit()
  47. self.Fit()
  48. self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
  49. self.txt = None
  50. self.Show(True)
  51. def us_to_px(self, val):
  52. return val / (10 ** 3) * self.zoom
  53. def px_to_us(self, val):
  54. return (val / self.zoom) * (10 ** 3)
  55. def scroll_start(self):
  56. (x, y) = self.scroll.GetViewStart()
  57. return (x * self.scroll_scale, y * self.scroll_scale)
  58. def scroll_start_us(self):
  59. (x, y) = self.scroll_start()
  60. return self.px_to_us(x)
  61. def paint_rectangle_zone(self, nr, color, top_color, start, end):
  62. offset_px = self.us_to_px(start - self.ts_start)
  63. width_px = self.us_to_px(end - self.ts_start)
  64. offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
  65. width_py = RootFrame.RECT_HEIGHT
  66. dc = self.dc
  67. if top_color is not None:
  68. (r, g, b) = top_color
  69. top_color = wx.Colour(r, g, b)
  70. brush = wx.Brush(top_color, wx.SOLID)
  71. dc.SetBrush(brush)
  72. dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
  73. width_py -= RootFrame.EVENT_MARKING_WIDTH
  74. offset_py += RootFrame.EVENT_MARKING_WIDTH
  75. (r ,g, b) = color
  76. color = wx.Colour(r, g, b)
  77. brush = wx.Brush(color, wx.SOLID)
  78. dc.SetBrush(brush)
  79. dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
  80. def update_rectangles(self, dc, start, end):
  81. start += self.ts_start
  82. end += self.ts_start
  83. self.sched_tracer.fill_zone(start, end)
  84. def on_paint(self, event):
  85. dc = wx.PaintDC(self.scroll_panel)
  86. self.dc = dc
  87. width = min(self.width_virtual, self.screen_width)
  88. (x, y) = self.scroll_start()
  89. start = self.px_to_us(x)
  90. end = self.px_to_us(x + width)
  91. self.update_rectangles(dc, start, end)
  92. def rect_from_ypixel(self, y):
  93. y -= RootFrame.Y_OFFSET
  94. rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
  95. height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
  96. if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
  97. return -1
  98. return rect
  99. def update_summary(self, txt):
  100. if self.txt:
  101. self.txt.Destroy()
  102. self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
  103. def on_mouse_down(self, event):
  104. (x, y) = event.GetPositionTuple()
  105. rect = self.rect_from_ypixel(y)
  106. if rect == -1:
  107. return
  108. t = self.px_to_us(x) + self.ts_start
  109. self.sched_tracer.mouse_down(rect, t)
  110. def update_width_virtual(self):
  111. self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
  112. def __zoom(self, x):
  113. self.update_width_virtual()
  114. (xpos, ypos) = self.scroll.GetViewStart()
  115. xpos = self.us_to_px(x) / self.scroll_scale
  116. self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
  117. self.Refresh()
  118. def zoom_in(self):
  119. x = self.scroll_start_us()
  120. self.zoom *= 2
  121. self.__zoom(x)
  122. def zoom_out(self):
  123. x = self.scroll_start_us()
  124. self.zoom /= 2
  125. self.__zoom(x)
  126. def on_key_press(self, event):
  127. key = event.GetRawKeyCode()
  128. if key == ord("+"):
  129. self.zoom_in()
  130. return
  131. if key == ord("-"):
  132. self.zoom_out()
  133. return
  134. key = event.GetKeyCode()
  135. (x, y) = self.scroll.GetViewStart()
  136. if key == wx.WXK_RIGHT:
  137. self.scroll.Scroll(x + 1, y)
  138. elif key == wx.WXK_LEFT:
  139. self.scroll.Scroll(x - 1, y)
  140. elif key == wx.WXK_DOWN:
  141. self.scroll.Scroll(x, y + 1)
  142. elif key == wx.WXK_UP:
  143. self.scroll.Scroll(x, y - 1)