controls/CustomToolTip.py
branch1.1 Korean release
changeset 1280 72a826dfcfbb
parent 1221 d18ccec78117
child 1571 486f94a8032c
equal deleted inserted replaced
977:c8e008b8cefe 1280:72a826dfcfbb
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 import wx
       
    26 
       
    27 from controls.CustomStyledTextCtrl import faces
       
    28 
       
    29 TOOLTIP_MAX_CHARACTERS = 30 # Maximum number of characters by line in ToolTip
       
    30 TOOLTIP_MAX_LINE = 5        # Maximum number of line in ToolTip
       
    31 TOOLTIP_WAIT_PERIOD = 0.5   # Wait period before displaying tooltip in second
       
    32 
       
    33 #-------------------------------------------------------------------------------
       
    34 #                               Custom ToolTip
       
    35 #-------------------------------------------------------------------------------
       
    36 
       
    37 """
       
    38 Class that implements a custom tool tip
       
    39 """
       
    40 
       
    41 class CustomToolTip(wx.PopupWindow):
       
    42     
       
    43     def __init__(self, parent, tip, restricted=True):
       
    44         """
       
    45         Constructor
       
    46         @param parent: Parent window
       
    47         @param tip: Tip text (may be multiline)
       
    48         @param restricted: Tool tip must follow size restriction in line and 
       
    49             characters number defined (default True)
       
    50         """
       
    51         wx.PopupWindow.__init__(self, parent)
       
    52         
       
    53         self.Restricted = restricted
       
    54         
       
    55         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
       
    56         self.SetTip(tip)
       
    57         
       
    58         # Initialize text font style
       
    59         self.Font = wx.Font(
       
    60             faces["size"], 
       
    61             wx.SWISS, 
       
    62             wx.NORMAL, 
       
    63             wx.NORMAL, 
       
    64             faceName = faces["mono"])
       
    65         
       
    66         self.Bind(wx.EVT_PAINT, self.OnPaint)
       
    67     
       
    68     def SetFont(self, font):
       
    69         """
       
    70         Set tool tip text font style
       
    71         @param font: wx.Font object containing font style
       
    72         """
       
    73         self.Font = font
       
    74         self.RefreshTip()
       
    75     
       
    76     def SetTip(self, tip):
       
    77         """
       
    78         Set tool tip text
       
    79         @param tip: Tool tip text
       
    80         """
       
    81         if self.Restricted:
       
    82             # Compute tip text line return
       
    83             self.Tip = []
       
    84             for line in tip.splitlines():
       
    85                 if line != "":
       
    86                     words = line.split()
       
    87                     new_line = words[0]
       
    88                     for word in words[1:]:
       
    89                         # Add word to line
       
    90                         if len(new_line + " " + word) <= \
       
    91                             TOOLTIP_MAX_CHARACTERS:
       
    92                             new_line += " " + word
       
    93                         # Create new line
       
    94                         else:
       
    95                             self.Tip.append(new_line)
       
    96                             new_line = word
       
    97                     self.Tip.append(new_line)
       
    98                 else:
       
    99                     self.Tip.append(line)
       
   100             
       
   101             # Restrict number of lines
       
   102             if len(self.Tip) > TOOLTIP_MAX_LINE:
       
   103                 self.Tip = self.Tip[:TOOLTIP_MAX_LINE]
       
   104                 
       
   105                 # Add ... to the end of last line to indicate that tool tip
       
   106                 # text is too long
       
   107                 if len(self.Tip[-1]) < TOOLTIP_MAX_CHARACTERS - 3:
       
   108                     self.Tip[-1] += "..."
       
   109                 else:
       
   110                     self.Tip[-1] = self.Tip[-1]\
       
   111                         [:TOOLTIP_MAX_CHARACTERS - 3] + "..."
       
   112         else:
       
   113             self.Tip = tip.splitlines()
       
   114         
       
   115         # Prevent to call wx method in non-wx threads
       
   116         wx.CallAfter(self.RefreshTip)
       
   117     
       
   118     def SetToolTipPosition(self, pos):
       
   119         """
       
   120         Set tool tip position
       
   121         @param pos: New tool tip position
       
   122         """
       
   123         # Get screen size to prevent tool tip to go out of the screen
       
   124         screen_width, screen_height = wx.GetDisplaySize()
       
   125         
       
   126         # Calculate position of tool tip to stay in screen limits
       
   127         tip_width, tip_height = self.GetToolTipSize()
       
   128         self.SetPosition(wx.Point(
       
   129             max(0, min(pos.x, screen_width - tip_width)),
       
   130             max(0, min(pos.y, screen_height - tip_height))))
       
   131     
       
   132     def GetToolTipSize(self):
       
   133         """
       
   134         Get tool tip size according to tip text and restriction
       
   135         @return: wx.Size(tool_tip_width, tool_tip_height)
       
   136         """
       
   137         max_width = max_height = 0
       
   138         
       
   139         # Create a memory DC for calculating text extent
       
   140         dc = wx.MemoryDC()
       
   141         dc.SetFont(self.Font)
       
   142         
       
   143         # Compute max tip text size
       
   144         for line in self.Tip:
       
   145             w, h = dc.GetTextExtent(line)
       
   146             max_width = max(max_width, w)
       
   147             max_height += h
       
   148         
       
   149         return wx.Size(max_width + 4, max_height + 4)
       
   150     
       
   151     def RefreshTip(self):
       
   152         """
       
   153         Refresh tip on screen
       
   154         """
       
   155         # Prevent to call this function if tool tip destroyed
       
   156         if self:
       
   157             # Refresh tool tip size and position
       
   158             self.SetClientSize(self.GetToolTipSize())
       
   159             
       
   160             # Redraw tool tip
       
   161             self.Refresh()
       
   162     
       
   163     def OnPaint(self, event):
       
   164         """
       
   165         Callback for Paint Event
       
   166         @param event: Paint event
       
   167         """
       
   168         # Get buffered paint DC for tool tip
       
   169         dc = wx.AutoBufferedPaintDC(self)
       
   170         dc.Clear()
       
   171         
       
   172         # Set DC drawing style
       
   173         dc.SetPen(wx.BLACK_PEN)
       
   174         dc.SetBrush(wx.Brush(wx.Colour(255, 238, 170)))
       
   175         dc.SetFont(self.Font)
       
   176         
       
   177         # Draw Tool tip
       
   178         dc.BeginDrawing()
       
   179         tip_width, tip_height = self.GetToolTipSize()
       
   180         
       
   181         # Draw background rectangle
       
   182         dc.DrawRectangle(0, 0, tip_width, tip_height)
       
   183         
       
   184         # Draw tool tip text
       
   185         line_offset = 0
       
   186         for line in self.Tip:
       
   187             dc.DrawText(line, 2, line_offset + 2)
       
   188             line_width, line_height = dc.GetTextExtent(line)
       
   189             line_offset += line_height
       
   190         
       
   191         dc.EndDrawing()
       
   192         
       
   193         event.Skip()