32 from targets.typemapping import LogLevelsCount, LogLevels |
32 from targets.typemapping import LogLevelsCount, LogLevels |
33 from util.BitmapLibrary import GetBitmap |
33 from util.BitmapLibrary import GetBitmap |
34 |
34 |
35 THUMB_SIZE_RATIO = 1. / 8. |
35 THUMB_SIZE_RATIO = 1. / 8. |
36 |
36 |
37 class MyScrollBar(wx.Panel): |
37 class LogScrollBar(wx.Panel): |
38 |
38 |
39 def __init__(self, parent, size): |
39 def __init__(self, parent, size): |
40 wx.Panel.__init__(self, parent, size=size) |
40 wx.Panel.__init__(self, parent, size=size) |
41 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) |
41 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) |
42 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) |
42 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) |
151 thumb_rect.width, thumb_rect.height) |
151 thumb_rect.width, thumb_rect.height) |
152 |
152 |
153 dc.EndDrawing() |
153 dc.EndDrawing() |
154 event.Skip() |
154 event.Skip() |
155 |
155 |
|
156 BUTTON_SIZE = (30, 15) |
|
157 |
|
158 class LogButton(): |
|
159 |
|
160 def __init__(self, label, callback): |
|
161 self.Position = wx.Point(0, 0) |
|
162 self.Size = wx.Size(*BUTTON_SIZE) |
|
163 if wx.Platform == '__WXMSW__': |
|
164 self.Font = wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New') |
|
165 else: |
|
166 self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier') |
|
167 self.Label = label |
|
168 self.Shown = True |
|
169 self.Callback = callback |
|
170 |
|
171 def __del__(self): |
|
172 self.callback = None |
|
173 |
|
174 def GetSize(self): |
|
175 return self.Size |
|
176 |
|
177 def SetPosition(self, x, y): |
|
178 self.Position = wx.Point(x, y) |
|
179 |
|
180 def HitTest(self, x, y): |
|
181 rect = wx.Rect(self.Position.x, self.Position.y, |
|
182 self.Size.width, self.Size.height) |
|
183 if rect.InsideXY(x, y): |
|
184 return True |
|
185 return False |
|
186 |
|
187 def ProcessCallback(self): |
|
188 if self.Callback is not None: |
|
189 wx.CallAfter(self.Callback) |
|
190 |
|
191 def Draw(self, dc): |
|
192 dc.SetPen(wx.TRANSPARENT_PEN) |
|
193 dc.SetBrush(wx.Brush(wx.NamedColour("LIGHT GREY"))) |
|
194 |
|
195 dc.DrawRectangle(self.Position.x, self.Position.y, |
|
196 self.Size.width, self.Size.height) |
|
197 |
|
198 dc.SetFont(self.Font) |
|
199 |
|
200 w, h = dc.GetTextExtent(self.Label) |
|
201 dc.DrawText(self.Label, |
|
202 self.Position.x + (self.Size.width - w) / 2, |
|
203 self.Position.y + (self.Size.height - h) / 2) |
|
204 |
156 DATE_INFO_SIZE = 10 |
205 DATE_INFO_SIZE = 10 |
157 MESSAGE_INFO_SIZE = 30 |
206 MESSAGE_INFO_SIZE = 30 |
158 |
207 |
159 class LogMessage: |
208 class LogMessage: |
160 |
209 |
236 self.OnSearchMessageSearchButtonClick, self.SearchMessage) |
283 self.OnSearchMessageSearchButtonClick, self.SearchMessage) |
237 self.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, |
284 self.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, |
238 self.OnSearchMessageCancelButtonClick, self.SearchMessage) |
285 self.OnSearchMessageCancelButtonClick, self.SearchMessage) |
239 filter_sizer.AddWindow(self.SearchMessage, 3, flag=wx.GROW) |
286 filter_sizer.AddWindow(self.SearchMessage, 3, flag=wx.GROW) |
240 |
287 |
241 message_panel_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0) |
288 message_panel_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0) |
242 message_panel_sizer.AddGrowableCol(1) |
289 message_panel_sizer.AddGrowableCol(0) |
243 message_panel_sizer.AddGrowableRow(0) |
290 message_panel_sizer.AddGrowableRow(0) |
244 main_sizer.AddSizer(message_panel_sizer, border=5, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW) |
291 main_sizer.AddSizer(message_panel_sizer, border=5, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW) |
245 |
|
246 buttons_sizer = wx.BoxSizer(wx.VERTICAL) |
|
247 for label, callback in [("+" + text, self.GenerateOnDurationButton(duration)) |
|
248 for text, duration in CHANGE_TIMESTAMP_BUTTONS] +\ |
|
249 [("-" + text, self.GenerateOnDurationButton(-duration)) |
|
250 for text, duration in REVERSE_CHANGE_TIMESTAMP_BUTTONS]: |
|
251 button = wx.Button(self, label=label) |
|
252 self.Bind(wx.EVT_BUTTON, callback, button) |
|
253 buttons_sizer.AddWindow(button, 1, wx.ALIGN_CENTER_VERTICAL) |
|
254 message_panel_sizer.AddSizer(buttons_sizer, flag=wx.GROW) |
|
255 |
292 |
256 self.MessagePanel = wx.Panel(self) |
293 self.MessagePanel = wx.Panel(self) |
257 if wx.Platform == '__WXMSW__': |
294 if wx.Platform == '__WXMSW__': |
258 self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New') |
295 self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New') |
259 else: |
296 else: |
260 self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier') |
297 self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier') |
|
298 self.MessagePanel.Bind(wx.EVT_LEFT_DOWN, self.OnMessagePanelLeftDown) |
261 self.MessagePanel.Bind(wx.EVT_MOUSEWHEEL, self.OnMessagePanelMouseWheel) |
299 self.MessagePanel.Bind(wx.EVT_MOUSEWHEEL, self.OnMessagePanelMouseWheel) |
262 self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint) |
300 self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint) |
263 self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize) |
301 self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize) |
264 message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW) |
302 message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW) |
265 |
303 |
266 self.MessageScrollBar = MyScrollBar(self, wx.Size(16, -1)) |
304 self.MessageScrollBar = LogScrollBar(self, wx.Size(16, -1)) |
267 message_panel_sizer.AddWindow(self.MessageScrollBar, flag=wx.GROW) |
305 message_panel_sizer.AddWindow(self.MessageScrollBar, flag=wx.GROW) |
268 |
306 |
269 self.SetSizer(main_sizer) |
307 self.SetSizer(main_sizer) |
270 |
308 |
|
309 self.LeftButtons = [] |
|
310 for label, callback in [("+" + text, self.GenerateOnDurationButton(duration)) |
|
311 for text, duration in CHANGE_TIMESTAMP_BUTTONS]: |
|
312 self.LeftButtons.append(LogButton(label, callback)) |
|
313 |
|
314 self.RightButtons = [] |
|
315 for label, callback in [("-" + text, self.GenerateOnDurationButton(-duration)) |
|
316 for text, duration in CHANGE_TIMESTAMP_BUTTONS]: |
|
317 self.RightButtons.append(LogButton(label, callback)) |
|
318 |
271 self.MessageFilter.SetSelection(0) |
319 self.MessageFilter.SetSelection(0) |
272 self.LogSource = None |
320 self.LogSource = None |
273 self.ResetLogMessages() |
321 self.ResetLogMessages() |
274 self.ParentWindow = window |
322 self.ParentWindow = window |
275 |
323 |
407 def RefreshView(self): |
455 def RefreshView(self): |
408 width, height = self.MessagePanel.GetClientSize() |
456 width, height = self.MessagePanel.GetClientSize() |
409 bitmap = wx.EmptyBitmap(width, height) |
457 bitmap = wx.EmptyBitmap(width, height) |
410 dc = wx.BufferedDC(wx.ClientDC(self.MessagePanel), bitmap) |
458 dc = wx.BufferedDC(wx.ClientDC(self.MessagePanel), bitmap) |
411 dc.Clear() |
459 dc.Clear() |
412 dc.SetFont(self.Font) |
|
413 dc.BeginDrawing() |
460 dc.BeginDrawing() |
414 |
461 |
415 if self.CurrentMessage is not None: |
462 if self.CurrentMessage is not None: |
|
463 |
|
464 for button in self.LeftButtons + self.RightButtons: |
|
465 button.Draw(dc) |
|
466 |
|
467 dc.SetFont(self.Font) |
|
468 |
416 message_idx = self.CurrentMessage |
469 message_idx = self.CurrentMessage |
417 message = self.LogMessages[message_idx] |
470 message = self.LogMessages[message_idx] |
418 draw_date = True |
471 draw_date = True |
419 offset = 5 |
472 offset = 5 |
420 while offset < height and message is not None: |
473 while offset < height and message is not None: |
507 self.SearchMessage.SetValue("") |
560 self.SearchMessage.SetValue("") |
508 self.ResetMessagePanel() |
561 self.ResetMessagePanel() |
509 event.Skip() |
562 event.Skip() |
510 |
563 |
511 def GenerateOnDurationButton(self, duration): |
564 def GenerateOnDurationButton(self, duration): |
512 def OnDurationButton(event): |
565 def OnDurationButton(): |
513 self.ScrollMessagePanelByTimestamp(duration) |
566 self.ScrollMessagePanelByTimestamp(duration) |
514 event.Skip() |
|
515 return OnDurationButton |
567 return OnDurationButton |
|
568 |
|
569 def OnMessagePanelLeftDown(self, event): |
|
570 if self.CurrentMessage is not None: |
|
571 posx, posy = event.GetPosition() |
|
572 for button in self.LeftButtons + self.RightButtons: |
|
573 if button.HitTest(posx, posy): |
|
574 button.ProcessCallback() |
|
575 event.Skip() |
516 |
576 |
517 def OnMessagePanelMouseWheel(self, event): |
577 def OnMessagePanelMouseWheel(self, event): |
518 self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta()) |
578 self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta()) |
519 event.Skip() |
579 event.Skip() |
520 |
580 |
521 def OnMessagePanelPaint(self, event): |
581 def OnMessagePanelPaint(self, event): |
522 self.RefreshView() |
582 self.RefreshView() |
523 event.Skip() |
583 event.Skip() |
524 |
584 |
525 def OnMessagePanelResize(self, event): |
585 def OnMessagePanelResize(self, event): |
|
586 if self.CurrentMessage is not None: |
|
587 width, height = self.MessagePanel.GetClientSize() |
|
588 offset = 2 |
|
589 for button in self.LeftButtons: |
|
590 button.SetPosition(offset, 2) |
|
591 w, h = button.GetSize() |
|
592 offset += w + 2 |
|
593 offset = width - 2 |
|
594 for button in self.RightButtons: |
|
595 w, h = button.GetSize() |
|
596 button.SetPosition(offset - w, 2) |
|
597 offset -= w + 2 |
526 if self.IsMessagePanelBottom(): |
598 if self.IsMessagePanelBottom(): |
527 self.ScrollToFirst() |
599 self.ScrollToFirst() |
528 else: |
600 else: |
529 self.RefreshView() |
601 self.RefreshView() |
530 event.Skip() |
602 event.Skip() |