--- a/controls/LogViewer.py Thu Mar 21 17:33:50 2013 +0100
+++ b/controls/LogViewer.py Fri Mar 22 00:18:51 2013 +0100
@@ -28,21 +28,21 @@
-from graphics import DebugViewer, REFRESH_PERIOD
+from graphics import DebugViewer, REFRESH_PERIOD, ToolTip, TOOLTIP_WAIT_PERIOD from targets.typemapping import LogLevelsCount, LogLevels
from util.BitmapLibrary import GetBitmap
THUMB_SIZE_RATIO = 1. / 8.
-def ArrowPoints(direction, width, height, offset):
+def ArrowPoints(direction, width, height, xoffset, yoffset): - return [wx.Point(1, offset + height - 2),
- wx.Point(width / 2, offset + 1),
- wx.Point(width - 1, offset + height - 2)]
+ return [wx.Point(xoffset + 1, yoffset + height - 2), + wx.Point(xoffset + width / 2, yoffset + 1), + wx.Point(xoffset + width - 1, yoffset + height - 2)] - return [wx.Point(1, offset - height + 1),
- wx.Point(width / 2, offset - 2),
- wx.Point(width - 1, offset - height + 1)]
+ return [wx.Point(xoffset + 1, yoffset - height + 1), + wx.Point(xoffset + width / 2, yoffset - 2), + wx.Point(xoffset + width - 1, yoffset - height + 1)] class LogScrollBar(wx.Panel):
@@ -137,14 +137,14 @@
width, height = self.GetClientSize()
- gc.SetPen(wx.Pen(wx.NamedColour("GREY"), 2))
+ gc.SetPen(wx.Pen(wx.NamedColour("GREY"), 3)) gc.SetBrush(wx.GREY_BRUSH)
- gc.DrawLines(ArrowPoints(wx.TOP, width, width * 0.75, 2 * width))
- gc.DrawLines(ArrowPoints(wx.TOP, width, width * 0.75, 2 * width + 6))
+ gc.DrawLines(ArrowPoints(wx.TOP, width * 0.75, width * 0.5, 2, (width + height) / 4 - 3)) + gc.DrawLines(ArrowPoints(wx.TOP, width * 0.75, width * 0.5, 2, (width + height) / 4 + 3)) - gc.DrawLines(ArrowPoints(wx.BOTTOM, width, width * 0.75, height - 2 * width))
- gc.DrawLines(ArrowPoints(wx.BOTTOM, width, width * 0.75, height - 2 * width - 6))
+ gc.DrawLines(ArrowPoints(wx.BOTTOM, width * 0.75, width * 0.5, 2, (height * 3 - width) / 4 + 3)) + gc.DrawLines(ArrowPoints(wx.BOTTOM, width * 0.75, width * 0.5, 2, (height * 3 - width) / 4 - 3)) thumb_rect = self.GetThumbRect()
exclusion_rect = wx.Rect(thumb_rect.x, thumb_rect.y,
@@ -164,9 +164,9 @@
gc.SetBrush(wx.GREY_BRUSH)
- gc.DrawPolygon(ArrowPoints(wx.TOP, width, width, 0))
+ gc.DrawPolygon(ArrowPoints(wx.TOP, width, width, 0, 0)) - gc.DrawPolygon(ArrowPoints(wx.BOTTOM, width, width, height))
+ gc.DrawPolygon(ArrowPoints(wx.BOTTOM, width, width, 0, height)) gc.DrawRectangle(thumb_rect.x, thumb_rect.y,
thumb_rect.width, thumb_rect.height)
@@ -181,10 +181,6 @@
def __init__(self, label, callback):
self.Position = wx.Point(0, 0)
self.Size = wx.Size(*BUTTON_SIZE)
- if wx.Platform == '__WXMSW__':
- self.Font = wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New')
- self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier')
@@ -216,15 +212,13 @@
dc.DrawRectangle(self.Position.x, self.Position.y,
self.Size.width, self.Size.height)
w, h = dc.GetTextExtent(self.Label)
self.Position.x + (self.Size.width - w) / 2,
self.Position.y + (self.Size.height - h) / 2)
@@ -243,6 +237,14 @@
return cmp(self.Seconds, other.Seconds)
return cmp(self.Date, other.Date)
+ date = self.Date.replace(second=int(self.Seconds)) + nsec = (self.Seconds % 1.) * 1e9 + return "%s at %s.%9.9d:\n%s" % ( def Draw(self, dc, offset, width, draw_date):
datetime_text = self.Date.strftime("%d/%m/%y %H:%M")
@@ -257,8 +259,9 @@
bw, bh = self.LevelBitmap.GetWidth(), self.LevelBitmap.GetHeight()
dc.DrawBitmap(self.LevelBitmap, 10 + sw, offset + (MESSAGE_INFO_SIZE - bh) / 2)
- mw, mh = dc.GetTextExtent(self.Message)
- dc.DrawText(self.Message, 15 + sw + bw, offset + (MESSAGE_INFO_SIZE - mh) / 2)
+ text = self.Message.replace("\n", " ") + mw, mh = dc.GetTextExtent(text) + dc.DrawText(text, 15 + sw + bw, offset + (MESSAGE_INFO_SIZE - mh) / 2) def GetHeight(self, draw_date):
@@ -314,11 +317,14 @@
self.MessagePanel = wx.Panel(self)
if wx.Platform == '__WXMSW__':
- self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New')
+ self.Font = wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New') - self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier')
+ self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier') self.MessagePanel.Bind(wx.EVT_LEFT_UP, self.OnMessagePanelLeftUp)
+ self.MessagePanel.Bind(wx.EVT_RIGHT_UP, self.OnMessagePanelRightUp) self.MessagePanel.Bind(wx.EVT_LEFT_DCLICK, self.OnMessagePanelLeftDCLick)
+ self.MessagePanel.Bind(wx.EVT_MOTION, self.OnMessagePanelMotion) + self.MessagePanel.Bind(wx.EVT_LEAVE_WINDOW, self.OnMessagePanelLeaveWindow) self.MessagePanel.Bind(wx.EVT_MOUSEWHEEL, self.OnMessagePanelMouseWheel)
self.MessagePanel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnMessagePanelEraseBackground)
self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint)
@@ -354,6 +360,11 @@
self.LastStartTime = None
self.ScrollTimer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.OnScrollTimer, self.ScrollTimer)
+ self.LastMousePos = None + self.MessageToolTip = None + self.MessageToolTipTimer = wx.Timer(self, -1) + self.Bind(wx.EVT_TIMER, self.OnMessageToolTipTimer, self.MessageToolTipTimer) @@ -411,6 +422,8 @@
self.LogMessagesTimestamp = numpy.append(self.LogMessagesTimestamp, [new_message.Timestamp])
if self.CurrentMessage is None or self.CurrentMessage == old_length - 1:
self.CurrentMessage = len(self.LogMessages) - 1
+ self.ResetMessageToolTip() + self.MessageToolTipTimer.Stop() self.NewDataAvailable(None)
def FilterLogMessage(self, message, timestamp=None):
@@ -485,11 +498,11 @@
if self.CurrentMessage is not None:
for button in self.LeftButtons + self.RightButtons:
message_idx = self.CurrentMessage
message = self.LogMessages[message_idx]
@@ -596,6 +609,34 @@
self.ScrollMessagePanelByTimestamp(duration)
+ def GetCopyMessageToClipboardFunction(self, message): + def CopyMessageToClipboardFunction(event): + self.ParentWindow.SetCopyBuffer(message.GetFullText()) + return CopyMessageToClipboardFunction + def GetMessageByScreenPos(self, posx, posy): + if self.CurrentMessage is not None: + width, height = self.MessagePanel.GetClientSize() + message_idx = self.CurrentMessage + message = self.LogMessages[message_idx] + while offset < height and message is not None: + offset += DATE_INFO_SIZE + if offset <= posy < offset + MESSAGE_INFO_SIZE: + offset += MESSAGE_INFO_SIZE + previous_message, message_idx = self.GetPreviousMessage(message_idx) + if previous_message is not None: + draw_date = message.Date != previous_message.Date + message = previous_message def OnMessagePanelLeftUp(self, event):
if self.CurrentMessage is not None:
posx, posy = event.GetPosition()
@@ -605,31 +646,55 @@
- def OnMessagePanelLeftDCLick(self, event):
- if self.CurrentMessage is not None:
- posx, posy = event.GetPosition()
- width, height = self.MessagePanel.GetClientSize()
- message_idx = self.CurrentMessage
- message = self.LogMessages[message_idx]
+ def OnMessagePanelRightUp(self, event): + message = self.GetMessageByScreenPos(*event.GetPosition()) + if message is not None: + menu = wx.Menu(title='') - while offset < height and message is not None:
- offset += DATE_INFO_SIZE
- if offset <= posy < offset + MESSAGE_INFO_SIZE:
- self.CurrentSearchValue = message.Message
- self.SearchMessage.SetValue(message.Message)
- self.ResetMessagePanel()
- offset += MESSAGE_INFO_SIZE
- previous_message, message_idx = self.GetPreviousMessage(message_idx)
- if previous_message is not None:
- draw_date = message.Date != previous_message.Date
- message = previous_message
+ menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Copy")) + self.Bind(wx.EVT_MENU, self.GetCopyMessageToClipboardFunction(message), id=new_id) + self.MessagePanel.PopupMenu(menu) + def OnMessagePanelLeftDCLick(self, event): + message = self.GetMessageByScreenPos(*event.GetPosition()) + if message is not None: + self.SearchMessage.SetFocus() + self.SearchMessage.SetValue(message.Message) + def ResetMessageToolTip(self): + if self.MessageToolTip is not None: + self.MessageToolTip.Destroy() + self.MessageToolTip = None + def OnMessageToolTipTimer(self, event): + if self.LastMousePos is not None: + message = self.GetMessageByScreenPos(*self.LastMousePos) + if message is not None: + tooltip_pos = self.MessagePanel.ClientToScreen(self.LastMousePos) + self.MessageToolTip = ToolTip(self.MessagePanel, message.GetFullText(), False) + self.MessageToolTip.SetFont(self.Font) + self.MessageToolTip.MoveToolTip(tooltip_pos) + self.MessageToolTip.Show() + def OnMessagePanelMotion(self, event): + if not event.Dragging(): + self.ResetMessageToolTip() + self.LastMousePos = event.GetPosition() + self.MessageToolTipTimer.Start(int(TOOLTIP_WAIT_PERIOD * 1000), oneShot=True) + def OnMessagePanelLeaveWindow(self, event): + self.ResetMessageToolTip() + self.LastMousePos = None + self.MessageToolTipTimer.Stop() def OnMessagePanelMouseWheel(self, event):
--- a/graphics/GraphicCommons.py Thu Mar 21 17:33:50 2013 +0100
+++ b/graphics/GraphicCommons.py Fri Mar 22 00:18:51 2013 +0100
@@ -578,20 +578,27 @@
class ToolTip(wx.PopupWindow):
- def __init__(self, parent, tip):
+ def __init__(self, parent, tip, restricted=True): wx.PopupWindow.__init__(self, parent)
self.CurrentPosition = wx.Point(0, 0)
+ self.Restricted = restricted self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
+ self.Font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) self.Bind(wx.EVT_PAINT, self.OnPaint)
+ def SetFont(self, font): for line in tip.splitlines():
+ if self.Restricted and line != "": @@ -603,7 +610,7 @@
- if len(lines) > TOOLTIP_MAX_LINE:
+ if self.Restricted and len(lines) > TOOLTIP_MAX_LINE: self.Tip = lines[:TOOLTIP_MAX_LINE]
if len(self.Tip[-1]) < TOOLTIP_MAX_CHARACTERS - 3:
@@ -614,14 +621,20 @@
wx.CallAfter(self.RefreshTip)
def MoveToolTip(self, pos):
- self.CurrentPosition = pos
+ screen_size = wx.GetDisplaySize() + w, h = self.GetTipExtent() + self.CurrentPosition = wx.Point( + max(0, min(pos.x, screen_size[0] - w - 4)), + max(0, min(pos.y, screen_size[1] - h - 4))) - w, h = self.GetTextExtent(line)
+ w, h = dc.GetTextExtent(line) max_width = max(max_width, w)
return max_width, max_height
@@ -638,7 +651,7 @@
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.Brush(wx.Colour(255, 238, 170)))
- dc.SetFont(wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]))
w, h = self.GetTipExtent()
dc.DrawRectangle(0, 0, w + 4, h + 4)