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
|
import gtk
import gobject
import cgi
tags = (
('Electronica', 5),
('Reggae', 5),
('Electro', 20),
('Detroit Techno', 4),
('Funk', 14),
('Jazz', 4),
('Minimal', 20),
('Soulful Drum and Bass', 6),
('Dub', 7),
('Drum and Bass', 23),
('Deep Techno', 7),
('Deephouse', 27),
('Soulful', 9),
('Minimal Techno', 30),
('Downtempo', 17),
('House', 29),
('Dubstep', 14),
('Techno', 32),
('Electrotech', 8),
('Techhouse', 28),
('Disco', 15),
('Downbeat', 28),
('Electrohouse', 14),
('Hiphop', 25),
('Trance', 6),
('Freestyle', 14),
('Funky House', 3),
('Minimal House', 4),
('Nu Jazz', 11),
('Chill-Out', 6),
('Breaks', 10),
('UK Garage', 4),
('Soul', 10),
('Progressive House', 3),
('Lounge', 6),
)
class TagCloud(gtk.Layout):
__gsignals__ = {
'selected': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_STRING,))
}
def __init__(self, tags, min_size=20, max_size=36):
self.__gobject_init__()
gtk.Layout.__init__(self)
self._tags = tags
self._min_size = min_size
self._max_size = max_size
self._min_weight = min(weight for tag, weight in self._tags)
self._max_weight = max(weight for tag, weight in self._tags)
self._size = 0, 0
self._alloc_id = self.connect('size-allocate', self._on_size_allocate)
self._init_tags()
self._in_relayout = False
def _on_size_allocate(self, widget, allocation):
self._size = (allocation.width, allocation.height)
if not self._in_relayout:
self.relayout()
def _init_tags(self):
for tag, weight in self._tags:
label = gtk.Label()
markup = '<span size="%d">%s</span>' % (1000*self._scale(weight), cgi.escape(tag))
label.set_markup(markup)
button = gtk.ToolButton(label)
button.connect('clicked', lambda b: self.emit('selected', tag))
self.put(button, 1, 1)
def _scale(self, weight):
weight_range = float(self._max_weight-self._min_weight)
ratio = float(weight-self._min_weight)/weight_range
return int(self._min_size + (self._max_size-self._min_size)*ratio)
def relayout(self):
self._in_relayout = True
x, y, max_h = 0, 0, 0
current_row = []
pw, ph = self._size
def fixup_row(widgets, x, y, max_h):
residue = (pw - x)
x = int(residue/2)
for widget in widgets:
cw, ch = widget.size_request()
self.move(widget, x, y+max(0, int((max_h-ch)/2)))
x += cw + 10
for child in self.get_children():
w, h = child.size_request()
if x + w > pw:
fixup_row(current_row, x, y, max_h)
y += max_h + 10
max_h, x = 0, 0
current_row = []
self.move(child, x, y)
x += w + 10
max_h = max(max_h, h)
current_row.append(child)
fixup_row(current_row, x, y, max_h)
self.set_size(pw, y+max_h)
def unrelayout():
self._in_relayout = False
return False
gobject.idle_add(unrelayout)
gobject.type_register(TagCloud)
if __name__ == '__main__':
l = TagCloud(tags)
try:
import hildon
w = hildon.StackableWindow()
sw = hildon.PannableArea()
except:
w = gtk.Window()
w.set_default_size(600, 300)
sw = gtk.ScrolledWindow()
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
w.set_title('Tag cloud Demo')
w.add(sw)
sw.add(l)
def on_tag_selected(cloud, tag):
print 'tag selected:', tag
l.connect('selected', on_tag_selected)
w.show_all()
w.connect('destroy', gtk.main_quit)
gtk.main()
|