--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/CustomToolTip.py Thu May 23 18:47:44 2013 +0200
@@ -0,0 +1,200 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard.
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import wx
+
+from controls.CustomStyledTextCtrl import faces
+
+TOOLTIP_MAX_CHARACTERS = 30 # Maximum number of characters by line in ToolTip
+TOOLTIP_MAX_LINE = 5 # Maximum number of line in ToolTip
+TOOLTIP_WAIT_PERIOD = 0.5 # Wait period before displaying tooltip in second
+
+#-------------------------------------------------------------------------------
+# Custom ToolTip
+#-------------------------------------------------------------------------------
+
+"""
+Class that implements a custom tool tip
+"""
+
+class CustomToolTip(wx.PopupWindow):
+
+ def __init__(self, parent, tip, restricted=True):
+ """
+ Constructor
+ @param parent: Parent window
+ @param tip: Tip text (may be multiline)
+ @param restricted: Tool tip must follow size restriction in line and
+ characters number defined (default True)
+ """
+ wx.PopupWindow.__init__(self, parent)
+
+ self.CurrentPosition = wx.Point(0, 0)
+ self.Restricted = restricted
+
+ self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
+ self.SetTip(tip)
+
+ # Initialize text font style
+ 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):
+ """
+ Set tool tip text font style
+ @param font: wx.Font object containing font style
+ """
+ self.Font = font
+ self.RefreshTip()
+
+ def SetTip(self, tip):
+ """
+ Set tool tip text
+ @param tip: Tool tip text
+ """
+ if self.Restricted:
+ # Compute tip text line return
+ self.Tip = []
+ for line in tip.splitlines():
+ if line != "":
+ words = line.split()
+ new_line = words[0]
+ for word in words[1:]:
+ # Add word to line
+ if len(new_line + " " + word) <= \
+ TOOLTIP_MAX_CHARACTERS:
+ new_line += " " + word
+ # Create new line
+ else:
+ self.Tip.append(new_line)
+ new_line = word
+ self.Tip.append(new_line)
+ else:
+ self.Tip.append(line)
+
+ # Restrict number of lines
+ if len(self.Tip) > TOOLTIP_MAX_LINE:
+ self.Tip = self.Tip[:TOOLTIP_MAX_LINE]
+
+ # Add ... to the end of last line to indicate that tool tip
+ # text is too long
+ if len(self.Tip[-1]) < TOOLTIP_MAX_CHARACTERS - 3:
+ self.Tip[-1] += "..."
+ else:
+ self.Tip[-1] = self.Tip[-1]\
+ [:TOOLTIP_MAX_CHARACTERS - 3] + "..."
+ else:
+ self.Tip = tip.splitlines()
+
+ # Prevent to call wx method in non-wx threads
+ wx.CallAfter(self.RefreshTip)
+
+ def MoveToolTip(self, pos):
+ """
+ Move tool tip
+ @param pos: New tool tip position
+ """
+ # Get screen size to prevent tool tip to go out of the screen
+ screen_width, screen_height = wx.GetDisplaySize()
+
+ # Calculate position of tool tip to stay in screen limits
+ tip_width, tip_height = self.GetToolTipSize()
+ self.CurrentPosition = wx.Point(
+ max(0, min(pos.x, screen_width - tip_width)),
+ max(0, min(pos.y, screen_height - tip_height)))
+
+ self.SetPosition(pos)
+
+ def GetToolTipSize(self):
+ """
+ Get tool tip size according to tip text and restriction
+ @return: wx.Size(tool_tip_width, tool_tip_height)
+ """
+ max_width = max_height = 0
+
+ # Create a memory DC for calculating text extent
+ dc = wx.MemoryDC()
+ dc.SetFont(self.Font)
+
+ # Compute max tip text size
+ for line in self.Tip:
+ w, h = dc.GetTextExtent(line)
+ max_width = max(max_width, w)
+ max_height += h
+
+ return wx.Size(max_width + 4, max_height + 4)
+
+ def RefreshTip(self):
+ """
+ Refresh tip on screen
+ """
+ # Prevent to call this function if tool tip destroyed
+ if self:
+ # Refresh tool tip size and position
+ self.SetSize(self.GetToolTipSize())
+ self.SetPosition(self.CurrentPosition)
+
+ # Redraw tool tip
+ self.Refresh()
+
+ def OnPaint(self, event):
+ """
+ Callback for Paint Event
+ @param event: Paint event
+ """
+ # Get buffered paint DC for tool tip
+ dc = wx.AutoBufferedPaintDC(self)
+ dc.Clear()
+
+ # Set DC drawing style
+ pen = wx.Pen(wx.BLACK)
+ pen.SetJoin(wx.JOIN_MITER)
+ pen.SetCap(wx.CAP_PROJECTING)
+ dc.SetPen(pen)
+ dc.SetBrush(wx.Brush(wx.Colour(255, 238, 170)))
+ dc.SetFont(self.Font)
+
+ # Draw Tool tip
+ dc.BeginDrawing()
+ tip_width, tip_height = self.GetToolTipSize()
+
+ # Draw background rectangle
+ dc.DrawRectangle(0, 0, tip_width, tip_height)
+
+ # Draw tool tip text
+ line_offset = 0
+ for line in self.Tip:
+ dc.DrawText(line, 2, line_offset + 2)
+ line_width, line_height = dc.GetTextExtent(line)
+ line_offset += line_height
+
+ dc.EndDrawing()
+
+ event.Skip()
--- a/controls/LogViewer.py Fri May 17 20:58:34 2013 +0200
+++ b/controls/LogViewer.py Thu May 23 18:47:44 2013 +0200
@@ -28,7 +28,8 @@
import wx
-from graphics import DebugViewer, REFRESH_PERIOD, ToolTip, TOOLTIP_WAIT_PERIOD
+from controls.CustomToolTip import CustomToolTip, TOOLTIP_WAIT_PERIOD
+from graphics import DebugViewer, REFRESH_PERIOD
from targets.typemapping import LogLevelsCount, LogLevels
from util.BitmapLibrary import GetBitmap
@@ -699,7 +700,7 @@
tooltip_pos = self.MessagePanel.ClientToScreen(self.LastMousePos)
tooltip_pos.x += 10
tooltip_pos.y += 10
- self.MessageToolTip = ToolTip(self.MessagePanel, message.GetFullText(), False)
+ self.MessageToolTip = CustomToolTip(self.MessagePanel, message.GetFullText(), False)
self.MessageToolTip.SetFont(self.Font)
self.MessageToolTip.MoveToolTip(tooltip_pos)
self.MessageToolTip.Show()
--- a/graphics/GraphicCommons.py Fri May 17 20:58:34 2013 +0200
+++ b/graphics/GraphicCommons.py Thu May 23 18:47:44 2013 +0200
@@ -29,6 +29,8 @@
import datetime
from threading import Lock,Timer
+from controls.CustomToolTip import CustomToolTip, TOOLTIP_WAIT_PERIOD
+
#-------------------------------------------------------------------------------
# Common constants
#-------------------------------------------------------------------------------
@@ -102,9 +104,6 @@
# Define highlight refresh inhibition period in second
REFRESH_HIGHLIGHT_PERIOD = 0.1
-# Define tooltip wait for displaying period in second
-TOOLTIP_WAIT_PERIOD = 0.5
-
HANDLE_CURSORS = {
(1, 1) : 2,
(3, 3) : 2,
@@ -555,119 +554,6 @@
dc.SetUserScale(scalex, scaley)
#-------------------------------------------------------------------------------
-# Viewer ToolTip
-#-------------------------------------------------------------------------------
-
-"""
-Class that implements a custom tool tip
-"""
-
-if wx.Platform == '__WXMSW__':
- faces = { 'times': 'Times New Roman',
- 'mono' : 'Courier New',
- 'helv' : 'Arial',
- 'other': 'Comic Sans MS',
- 'size' : 10,
- }
-else:
- faces = { 'times': 'Times',
- 'mono' : 'Courier',
- 'helv' : 'Helvetica',
- 'other': 'new century schoolbook',
- 'size' : 12,
- }
-
-TOOLTIP_MAX_CHARACTERS = 30
-TOOLTIP_MAX_LINE = 5
-
-class ToolTip(wx.PopupWindow):
-
- 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.SetTip(tip)
-
- 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):
- self.Font = font
- self.RefreshTip()
-
- def SetTip(self, tip):
- lines = []
- for line in tip.splitlines():
- if self.Restricted and line != "":
- words = line.split()
- new_line = words[0]
- for word in words[1:]:
- if len(new_line + " " + word) <= TOOLTIP_MAX_CHARACTERS:
- new_line += " " + word
- else:
- lines.append(new_line)
- new_line = word
- lines.append(new_line)
- else:
- lines.append(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:
- self.Tip[-1] += "..."
- else:
- self.Tip[-1] = self.Tip[-1][:TOOLTIP_MAX_CHARACTERS - 3] + "..."
- else:
- self.Tip = lines
- wx.CallAfter(self.RefreshTip)
-
- def MoveToolTip(self, 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)))
- self.SetPosition(pos)
-
- def GetTipExtent(self):
- max_width = 0
- max_height = 0
- for line in self.Tip:
- dc = wx.MemoryDC()
- dc.SetFont(self.Font)
- w, h = dc.GetTextExtent(line)
- max_width = max(max_width, w)
- max_height += h
- return max_width, max_height
-
- def RefreshTip(self):
- if self:
- w, h = self.GetTipExtent()
- self.SetSize(wx.Size(w + 4, h + 4))
- self.SetPosition(self.CurrentPosition)
- self.Refresh()
-
- def OnPaint(self, event):
- dc = wx.AutoBufferedPaintDC(self)
- dc.Clear()
- dc.SetPen(MiterPen(wx.BLACK))
- dc.SetBrush(wx.Brush(wx.Colour(255, 238, 170)))
- dc.SetFont(self.Font)
- dc.BeginDrawing()
- w, h = self.GetTipExtent()
- dc.DrawRectangle(0, 0, w + 4, h + 4)
- offset = 0
- for line in self.Tip:
- dc.DrawText(line, 2, offset + 2)
- w, h = dc.GetTextExtent(line)
- offset += h
- dc.EndDrawing()
- event.Skip()
-
-#-------------------------------------------------------------------------------
# Helpers for highlighting text
#-------------------------------------------------------------------------------
@@ -1107,7 +993,7 @@
def OnToolTipTimer(self, event):
value = self.GetToolTipValue()
if value is not None and self.ToolTipPos is not None:
- self.ToolTip = ToolTip(self.Parent, value)
+ self.ToolTip = CustomToolTip(self.Parent, value)
self.ToolTip.MoveToolTip(self.ToolTipPos)
self.ToolTip.Show()