184 lines · 5.3 KB · Python
RawDownload
# SchedGui.py - Python extension for perf script, basic GUI code for#		traces drawing and overview.## Copyright (C) 2010 by Frederic Weisbecker <fweisbec@gmail.com>## This software is distributed under the terms of the GNU General# Public License ("GPL") version 2 as published by the Free Software# Foundation.  try:	import wxexcept ImportError:	raise ImportError("You need to install the wxpython lib for this script")  class RootFrame(wx.Frame):	Y_OFFSET = 100	RECT_HEIGHT = 100	RECT_SPACE = 50	EVENT_MARKING_WIDTH = 5 	def __init__(self, sched_tracer, title, parent = None, id = -1):		wx.Frame.__init__(self, parent, id, title) 		(self.screen_width, self.screen_height) = wx.GetDisplaySize()		self.screen_width -= 10		self.screen_height -= 10		self.zoom = 0.5		self.scroll_scale = 20		self.sched_tracer = sched_tracer		self.sched_tracer.set_root_win(self)		(self.ts_start, self.ts_end) = sched_tracer.interval()		self.update_width_virtual()		self.nr_rects = sched_tracer.nr_rectangles() + 1		self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)) 		# whole window panel		self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height)) 		# scrollable container		self.scroll = wx.ScrolledWindow(self.panel)		self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)		self.scroll.EnableScrolling(True, True)		self.scroll.SetFocus() 		# scrollable drawing area		self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))		self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)		self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)		self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)		self.scroll.Bind(wx.EVT_PAINT, self.on_paint)		self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)		self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down) 		self.scroll.Fit()		self.Fit() 		self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING) 		self.txt = None 		self.Show(True) 	def us_to_px(self, val):		return val / (10 ** 3) * self.zoom 	def px_to_us(self, val):		return (val / self.zoom) * (10 ** 3) 	def scroll_start(self):		(x, y) = self.scroll.GetViewStart()		return (x * self.scroll_scale, y * self.scroll_scale) 	def scroll_start_us(self):		(x, y) = self.scroll_start()		return self.px_to_us(x) 	def paint_rectangle_zone(self, nr, color, top_color, start, end):		offset_px = self.us_to_px(start - self.ts_start)		width_px = self.us_to_px(end - self.ts_start) 		offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))		width_py = RootFrame.RECT_HEIGHT 		dc = self.dc 		if top_color is not None:			(r, g, b) = top_color			top_color = wx.Colour(r, g, b)			brush = wx.Brush(top_color, wx.SOLID)			dc.SetBrush(brush)			dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)			width_py -= RootFrame.EVENT_MARKING_WIDTH			offset_py += RootFrame.EVENT_MARKING_WIDTH 		(r ,g, b) = color		color = wx.Colour(r, g, b)		brush = wx.Brush(color, wx.SOLID)		dc.SetBrush(brush)		dc.DrawRectangle(offset_px, offset_py, width_px, width_py) 	def update_rectangles(self, dc, start, end):		start += self.ts_start		end += self.ts_start		self.sched_tracer.fill_zone(start, end) 	def on_paint(self, event):		dc = wx.PaintDC(self.scroll_panel)		self.dc = dc 		width = min(self.width_virtual, self.screen_width)		(x, y) = self.scroll_start()		start = self.px_to_us(x)		end = self.px_to_us(x + width)		self.update_rectangles(dc, start, end) 	def rect_from_ypixel(self, y):		y -= RootFrame.Y_OFFSET		rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)		height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE) 		if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:			return -1 		return rect 	def update_summary(self, txt):		if self.txt:			self.txt.Destroy()		self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))  	def on_mouse_down(self, event):		(x, y) = event.GetPositionTuple()		rect = self.rect_from_ypixel(y)		if rect == -1:			return 		t = self.px_to_us(x) + self.ts_start 		self.sched_tracer.mouse_down(rect, t)  	def update_width_virtual(self):		self.width_virtual = self.us_to_px(self.ts_end - self.ts_start) 	def __zoom(self, x):		self.update_width_virtual()		(xpos, ypos) = self.scroll.GetViewStart()		xpos = self.us_to_px(x) / self.scroll_scale		self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)		self.Refresh() 	def zoom_in(self):		x = self.scroll_start_us()		self.zoom *= 2		self.__zoom(x) 	def zoom_out(self):		x = self.scroll_start_us()		self.zoom /= 2		self.__zoom(x)  	def on_key_press(self, event):		key = event.GetRawKeyCode()		if key == ord("+"):			self.zoom_in()			return		if key == ord("-"):			self.zoom_out()			return 		key = event.GetKeyCode()		(x, y) = self.scroll.GetViewStart()		if key == wx.WXK_RIGHT:			self.scroll.Scroll(x + 1, y)		elif key == wx.WXK_LEFT:			self.scroll.Scroll(x - 1, y)		elif key == wx.WXK_DOWN:			self.scroll.Scroll(x, y + 1)		elif key == wx.WXK_UP:			self.scroll.Scroll(x, y - 1)