Update year to 2009 in various places
[zeroinstall/zeroinstall-rsl.git] / zeroinstall / gtkui / treetips.py
blob1ec030794241979cab8f6b7fbce3017718e992be
1 """Add tooltips to a TreeView."""
2 # Copyright (C) 2009, Thomas Leonard
3 # See the README file for details, or visit http://0install.net.
5 import time, gobject, gtk
7 class TreeTips:
8 """This object allows you to set location-dependent tooltips on a TreeView.
9 Connect your TreeView's leave-notify-event to the L{hide} method.
10 In your motion-notify-event handler, call L{prime} when the pointer moves
11 to an area with a new message. The message will be shown after a delay.
12 If calculation of the message is expensive, override L{get_tooltip_text}
13 instead.
14 """
15 timeout = None
16 widget = None
17 item = None
18 time = 0
20 def show(self, parent):
21 if self.timeout:
22 gobject.source_remove(self.timeout)
23 self.timeout = None
25 if self.widget:
26 self.widget.destroy()
27 self.widget = None
29 if self.item is None:
30 return
32 text = self.get_tooltip_text()
33 if not text:
34 return
36 self.widget = gtk.Window(gtk.WINDOW_POPUP)
37 self.widget.set_app_paintable(True)
38 self.widget.set_name('gtk-tooltips')
40 self.widget.connect('expose-event', self.tooltip_draw)
42 label = gtk.Label(text)
43 label.set_line_wrap(True)
44 label.set_padding(4, 2)
45 self.widget.add(label)
46 label.show()
48 w, h = self.widget.size_request()
49 if hasattr(parent, 'get_screen'):
50 screen = parent.get_screen()
51 root = screen.get_root_window()
52 else:
53 root = gtk.gdk.get_default_root_window()
54 px, py, mask = gtk.gdk.Window.get_pointer(root)
56 #m = gtk.gdk.screen_get_default().get_monitor_at_point(px, py)
58 x = px - w / 2
59 y = py + 12
61 # Test if pointer is over the tooltip window
62 if py >= y and py <= y + h:
63 y = py - h - 2
64 self.widget.move(x, y)
65 self.widget.show()
67 self.widget.connect('destroy', self.tooltip_destroyed)
68 self.time = time.time()
70 def prime(self, parent, item):
71 """Call this whenever the pointer moves to an area with a different
72 tooltip.
73 @param parent: the TreeView widget
74 @param item: the text to display
75 @see L{get_tooltip_text}"""
76 self.hide()
77 assert self.timeout is None
78 self.item = item
80 now = time.time()
81 if now - self.time > 2:
82 delay = 1000
83 else:
84 delay = 100
86 self.timeout = gobject.timeout_add(delay, lambda: self.show(parent))
88 def tooltip_draw(self, widget, ev):
89 widget.window.draw_rectangle(widget.style.fg_gc[widget.state],
90 False, 0, 0,
91 widget.allocation.width - 1,
92 widget.allocation.height - 1)
94 def tooltip_destroyed(self, widget):
95 pass
97 def hide(self):
98 """Hide the tooltip, if any.
99 Sets L{item} to None."""
100 self.item = None
101 self.show(None)
103 def get_tooltip_text(self):
104 """"Converts the object passed to L{prime} to a string for display.
105 The default implementation just calls C{str}, but subclasses can override it.
106 @return: the tooltip message"""
107 return str(self.item)