/usr/lib/python2.7/dist-packages/chaco/tooltip.py is in python-chaco 4.1.0-1ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | """ Defines the ToolTip class.
"""
from __future__ import with_statement
from numpy import array
# Enthought library imports
from enable.api import black_color_trait, white_color_trait
from enable.font_metrics_provider import font_metrics_provider
from kiva.trait_defs.kiva_font_trait import KivaFont
from traits.api import Any, Bool, List, Int, Float, on_trait_change
# Local imports
from abstract_overlay import AbstractOverlay
from plot_component import PlotComponent
from label import Label
class ToolTip(AbstractOverlay):
""" An overlay that is a toolip.
"""
# The font to render the tooltip.
font = KivaFont('modern 10')
# The color of the text in the tooltip
text_color = black_color_trait
# The ammount of space between the border and the text.
border_padding = Int(4)
# The number of pixels between lines.
line_spacing = Int(4)
# List of text strings to put in the tooltip.
lines = List
# Angle to rotate (counterclockwise) in degrees. NB this will *only*
# currently affect text, so probably only useful if borders and background
# are disabled
rotate_angle = Float(0.0)
# Should the tooltip automatically reposition itself to remain visible
# and unclipped on its overlaid component?
auto_adjust = Bool(True)
# The tooltip is a fixed size. (Overrides PlotComponent.)
resizable = ""
# Use a visible border. (Overrides Enable Component.)
border_visible = True
# Use a white background color (overrides AbstractOverlay).
bgcolor = white_color_trait
#----------------------------------------------------------------------
# Private Traits
#----------------------------------------------------------------------
_font_metrics_provider = Any()
_text_props_valid = Bool(False)
_max_line_width = Float(0.0)
_total_line_height = Float(0.0)
def draw(self, gc, view_bounds=None, mode='normal'):
""" Draws the plot component.
Overrides PlotComponent.
"""
self.overlay(self, gc, view_bounds=view_bounds, mode='normal')
return
def overlay(self, component, gc, view_bounds=None, mode='normal'):
""" Draws the tooltip overlaid on another component.
Overrides AbstractOverlay.
"""
self.do_layout()
PlotComponent._draw(self, gc, view_bounds, mode)
return
def _draw_overlay(self, gc, view_bounds=None, mode='normal'):
""" Draws the overlay layer of a component.
Overrides PlotComponent.
"""
with gc:
edge_space = self.border_width + self.border_padding
gc.translate_ctm(self.x + edge_space, self.y)
y = self.height - edge_space
for i, label in enumerate(self._cached_labels):
label_height = self._cached_line_sizes[i][1]
y -= label_height
gc.translate_ctm(0,y)
label.draw(gc)
gc.translate_ctm(0,-y)
y -= self.line_spacing
return
def _do_layout(self):
"""Computes the size of the tooltip, and creates the label objects
for each line.
Overrides PlotComponent.
"""
if not self._text_props_valid:
self._recompute_text()
outer_bounds = [self._max_line_width + 2*self.border_padding + self.hpadding,
self._total_line_height + 2*self.border_padding + self.vpadding]
self.outer_bounds = outer_bounds
if self.auto_adjust and self.component is not None:
new_pos = list(self.outer_position)
for dimindex in (0,1):
pos = self.position[dimindex]
extent = outer_bounds[dimindex]
c_min = self.component.position[dimindex]
c_max = c_min + self.component.bounds[dimindex]
# Is the tooltip just too wide/tall?
if extent > (c_max - c_min):
new_pos[dimindex] = c_min
# Does it extend over the c_max edge? (right/top)
elif pos + extent > c_max:
new_pos[dimindex] = c_max - extent
# Does it extend over the c_min edge? This is not an elif so
# that we can fix the situation where the c_max edge adjustment
# above pushes the position negative.
if new_pos[dimindex] < c_min:
new_pos[dimindex] = c_min
self.outer_position = new_pos
self._layout_needed = False
def _recompute_text(self):
labels = [Label(text=line, font=self.font, margin=0,
bgcolor='transparent', border_width=0,
color=self.text_color, rotate_angle=self.rotate_angle)
for line in self.lines]
dummy_gc = self._font_metrics_provider
line_sizes = array([label.get_width_height(dummy_gc)
for label in labels])
self._cached_labels = labels
self._cached_line_sizes = line_sizes
self._max_line_width = max(line_sizes[:,0])
self._total_line_height = sum(line_sizes[:,1]) + \
len(line_sizes-1)*self.line_spacing
self._layout_needed = True
return
def __font_metrics_provider_default(self):
return font_metrics_provider()
@on_trait_change("font,text_color,lines,lines_items")
def _invalidate_text_props(self):
self._text_props_valid = False
self._layout_needed = True
@on_trait_change("border_padding,line_spacing,lines,lines_items,padding")
def _invalidate_layout(self):
self._layout_needed = True
self.request_redraw()
|