0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 try:
0012 import wx
0013 except ImportError:
0014 raise ImportError("You need to install the wxpython lib for this script")
0015
0016
0017 class RootFrame(wx.Frame):
0018 Y_OFFSET = 100
0019 RECT_HEIGHT = 100
0020 RECT_SPACE = 50
0021 EVENT_MARKING_WIDTH = 5
0022
0023 def __init__(self, sched_tracer, title, parent = None, id = -1):
0024 wx.Frame.__init__(self, parent, id, title)
0025
0026 (self.screen_width, self.screen_height) = wx.GetDisplaySize()
0027 self.screen_width -= 10
0028 self.screen_height -= 10
0029 self.zoom = 0.5
0030 self.scroll_scale = 20
0031 self.sched_tracer = sched_tracer
0032 self.sched_tracer.set_root_win(self)
0033 (self.ts_start, self.ts_end) = sched_tracer.interval()
0034 self.update_width_virtual()
0035 self.nr_rects = sched_tracer.nr_rectangles() + 1
0036 self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
0037
0038
0039 self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
0040
0041
0042 self.scroll = wx.ScrolledWindow(self.panel)
0043 self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
0044 self.scroll.EnableScrolling(True, True)
0045 self.scroll.SetFocus()
0046
0047
0048 self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
0049 self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
0050 self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
0051 self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
0052 self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
0053 self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
0054 self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
0055
0056 self.scroll.Fit()
0057 self.Fit()
0058
0059 self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
0060
0061 self.txt = None
0062
0063 self.Show(True)
0064
0065 def us_to_px(self, val):
0066 return val / (10 ** 3) * self.zoom
0067
0068 def px_to_us(self, val):
0069 return (val / self.zoom) * (10 ** 3)
0070
0071 def scroll_start(self):
0072 (x, y) = self.scroll.GetViewStart()
0073 return (x * self.scroll_scale, y * self.scroll_scale)
0074
0075 def scroll_start_us(self):
0076 (x, y) = self.scroll_start()
0077 return self.px_to_us(x)
0078
0079 def paint_rectangle_zone(self, nr, color, top_color, start, end):
0080 offset_px = self.us_to_px(start - self.ts_start)
0081 width_px = self.us_to_px(end - self.ts_start)
0082
0083 offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
0084 width_py = RootFrame.RECT_HEIGHT
0085
0086 dc = self.dc
0087
0088 if top_color is not None:
0089 (r, g, b) = top_color
0090 top_color = wx.Colour(r, g, b)
0091 brush = wx.Brush(top_color, wx.SOLID)
0092 dc.SetBrush(brush)
0093 dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
0094 width_py -= RootFrame.EVENT_MARKING_WIDTH
0095 offset_py += RootFrame.EVENT_MARKING_WIDTH
0096
0097 (r ,g, b) = color
0098 color = wx.Colour(r, g, b)
0099 brush = wx.Brush(color, wx.SOLID)
0100 dc.SetBrush(brush)
0101 dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
0102
0103 def update_rectangles(self, dc, start, end):
0104 start += self.ts_start
0105 end += self.ts_start
0106 self.sched_tracer.fill_zone(start, end)
0107
0108 def on_paint(self, event):
0109 dc = wx.PaintDC(self.scroll_panel)
0110 self.dc = dc
0111
0112 width = min(self.width_virtual, self.screen_width)
0113 (x, y) = self.scroll_start()
0114 start = self.px_to_us(x)
0115 end = self.px_to_us(x + width)
0116 self.update_rectangles(dc, start, end)
0117
0118 def rect_from_ypixel(self, y):
0119 y -= RootFrame.Y_OFFSET
0120 rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
0121 height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
0122
0123 if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
0124 return -1
0125
0126 return rect
0127
0128 def update_summary(self, txt):
0129 if self.txt:
0130 self.txt.Destroy()
0131 self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
0132
0133
0134 def on_mouse_down(self, event):
0135 (x, y) = event.GetPositionTuple()
0136 rect = self.rect_from_ypixel(y)
0137 if rect == -1:
0138 return
0139
0140 t = self.px_to_us(x) + self.ts_start
0141
0142 self.sched_tracer.mouse_down(rect, t)
0143
0144
0145 def update_width_virtual(self):
0146 self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
0147
0148 def __zoom(self, x):
0149 self.update_width_virtual()
0150 (xpos, ypos) = self.scroll.GetViewStart()
0151 xpos = self.us_to_px(x) / self.scroll_scale
0152 self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
0153 self.Refresh()
0154
0155 def zoom_in(self):
0156 x = self.scroll_start_us()
0157 self.zoom *= 2
0158 self.__zoom(x)
0159
0160 def zoom_out(self):
0161 x = self.scroll_start_us()
0162 self.zoom /= 2
0163 self.__zoom(x)
0164
0165
0166 def on_key_press(self, event):
0167 key = event.GetRawKeyCode()
0168 if key == ord("+"):
0169 self.zoom_in()
0170 return
0171 if key == ord("-"):
0172 self.zoom_out()
0173 return
0174
0175 key = event.GetKeyCode()
0176 (x, y) = self.scroll.GetViewStart()
0177 if key == wx.WXK_RIGHT:
0178 self.scroll.Scroll(x + 1, y)
0179 elif key == wx.WXK_LEFT:
0180 self.scroll.Scroll(x - 1, y)
0181 elif key == wx.WXK_DOWN:
0182 self.scroll.Scroll(x, y + 1)
0183 elif key == wx.WXK_UP:
0184 self.scroll.Scroll(x, y - 1)