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