| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 |
|
| 10 |
|
| 11 | try:
|
| 12 | import wx
|
| 13 | except ImportError:
|
| 14 | raise ImportError("You need to install the wxpython lib for this script")
|
| 15 |
|
| 16 |
|
| 17 | class RootFrame(wx.Frame):
|
| 18 | Y_OFFSET = 100
|
| 19 | RECT_HEIGHT = 100
|
| 20 | RECT_SPACE = 50
|
| 21 | EVENT_MARKING_WIDTH = 5
|
| 22 |
|
| 23 | def __init__(self, sched_tracer, title, parent = None, id = -1):
|
| 24 | wx.Frame.__init__(self, parent, id, title)
|
| 25 |
|
| 26 | (self.screen_width, self.screen_height) = wx.GetDisplaySize()
|
| 27 | self.screen_width -= 10
|
| 28 | self.screen_height -= 10
|
| 29 | self.zoom = 0.5
|
| 30 | self.scroll_scale = 20
|
| 31 | self.sched_tracer = sched_tracer
|
| 32 | self.sched_tracer.set_root_win(self)
|
| 33 | (self.ts_start, self.ts_end) = sched_tracer.interval()
|
| 34 | self.update_width_virtual()
|
| 35 | self.nr_rects = sched_tracer.nr_rectangles() + 1
|
| 36 | self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
|
| 37 |
|
| 38 | |
| 39 | self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
|
| 40 |
|
| 41 | |
| 42 | self.scroll = wx.ScrolledWindow(self.panel)
|
| 43 | self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
|
| 44 | self.scroll.EnableScrolling(True, True)
|
| 45 | self.scroll.SetFocus()
|
| 46 |
|
| 47 | |
| 48 | self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
|
| 49 | self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
|
| 50 | self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
|
| 51 | self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
|
| 52 | self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
|
| 53 | self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
|
| 54 | self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
|
| 55 |
|
| 56 | self.scroll.Fit()
|
| 57 | self.Fit()
|
| 58 |
|
| 59 | self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
|
| 60 |
|
| 61 | self.txt = None
|
| 62 |
|
| 63 | self.Show(True)
|
| 64 |
|
| 65 | def us_to_px(self, val):
|
| 66 | return val / (10 ** 3) * self.zoom
|
| 67 |
|
| 68 | def px_to_us(self, val):
|
| 69 | return (val / self.zoom) * (10 ** 3)
|
| 70 |
|
| 71 | def scroll_start(self):
|
| 72 | (x, y) = self.scroll.GetViewStart()
|
| 73 | return (x * self.scroll_scale, y * self.scroll_scale)
|
| 74 |
|
| 75 | def scroll_start_us(self):
|
| 76 | (x, y) = self.scroll_start()
|
| 77 | return self.px_to_us(x)
|
| 78 |
|
| 79 | def paint_rectangle_zone(self, nr, color, top_color, start, end):
|
| 80 | offset_px = self.us_to_px(start - self.ts_start)
|
| 81 | width_px = self.us_to_px(end - self.ts_start)
|
| 82 |
|
| 83 | offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
|
| 84 | width_py = RootFrame.RECT_HEIGHT
|
| 85 |
|
| 86 | dc = self.dc
|
| 87 |
|
| 88 | if top_color is not None:
|
| 89 | (r, g, b) = top_color
|
| 90 | top_color = wx.Colour(r, g, b)
|
| 91 | brush = wx.Brush(top_color, wx.SOLID)
|
| 92 | dc.SetBrush(brush)
|
| 93 | dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
|
| 94 | width_py -= RootFrame.EVENT_MARKING_WIDTH
|
| 95 | offset_py += RootFrame.EVENT_MARKING_WIDTH
|
| 96 |
|
| 97 | (r ,g, b) = color
|
| 98 | color = wx.Colour(r, g, b)
|
| 99 | brush = wx.Brush(color, wx.SOLID)
|
| 100 | dc.SetBrush(brush)
|
| 101 | dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
|
| 102 |
|
| 103 | def update_rectangles(self, dc, start, end):
|
| 104 | start += self.ts_start
|
| 105 | end += self.ts_start
|
| 106 | self.sched_tracer.fill_zone(start, end)
|
| 107 |
|
| 108 | def on_paint(self, event):
|
| 109 | dc = wx.PaintDC(self.scroll_panel)
|
| 110 | self.dc = dc
|
| 111 |
|
| 112 | width = min(self.width_virtual, self.screen_width)
|
| 113 | (x, y) = self.scroll_start()
|
| 114 | start = self.px_to_us(x)
|
| 115 | end = self.px_to_us(x + width)
|
| 116 | self.update_rectangles(dc, start, end)
|
| 117 |
|
| 118 | def rect_from_ypixel(self, y):
|
| 119 | y -= RootFrame.Y_OFFSET
|
| 120 | rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
|
| 121 | height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
|
| 122 |
|
| 123 | if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
|
| 124 | return -1
|
| 125 |
|
| 126 | return rect
|
| 127 |
|
| 128 | def update_summary(self, txt):
|
| 129 | if self.txt:
|
| 130 | self.txt.Destroy()
|
| 131 | self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
|
| 132 |
|
| 133 |
|
| 134 | def on_mouse_down(self, event):
|
| 135 | (x, y) = event.GetPositionTuple()
|
| 136 | rect = self.rect_from_ypixel(y)
|
| 137 | if rect == -1:
|
| 138 | return
|
| 139 |
|
| 140 | t = self.px_to_us(x) + self.ts_start
|
| 141 |
|
| 142 | self.sched_tracer.mouse_down(rect, t)
|
| 143 |
|
| 144 |
|
| 145 | def update_width_virtual(self):
|
| 146 | self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
|
| 147 |
|
| 148 | def __zoom(self, x):
|
| 149 | self.update_width_virtual()
|
| 150 | (xpos, ypos) = self.scroll.GetViewStart()
|
| 151 | xpos = self.us_to_px(x) / self.scroll_scale
|
| 152 | self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
|
| 153 | self.Refresh()
|
| 154 |
|
| 155 | def zoom_in(self):
|
| 156 | x = self.scroll_start_us()
|
| 157 | self.zoom *= 2
|
| 158 | self.__zoom(x)
|
| 159 |
|
| 160 | def zoom_out(self):
|
| 161 | x = self.scroll_start_us()
|
| 162 | self.zoom /= 2
|
| 163 | self.__zoom(x)
|
| 164 |
|
| 165 |
|
| 166 | def on_key_press(self, event):
|
| 167 | key = event.GetRawKeyCode()
|
| 168 | if key == ord("+"):
|
| 169 | self.zoom_in()
|
| 170 | return
|
| 171 | if key == ord("-"):
|
| 172 | self.zoom_out()
|
| 173 | return
|
| 174 |
|
| 175 | key = event.GetKeyCode()
|
| 176 | (x, y) = self.scroll.GetViewStart()
|
| 177 | if key == wx.WXK_RIGHT:
|
| 178 | self.scroll.Scroll(x + 1, y)
|
| 179 | elif key == wx.WXK_LEFT:
|
| 180 | self.scroll.Scroll(x - 1, y)
|
| 181 | elif key == wx.WXK_DOWN:
|
| 182 | self.scroll.Scroll(x, y + 1)
|
| 183 | elif key == wx.WXK_UP:
|
| 184 | self.scroll.Scroll(x, y - 1)
|