File: tagcloud.py

package info (click to toggle)
gpodder 3.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 6,588 kB
  • ctags: 2,559
  • sloc: python: 16,511; ansic: 479; makefile: 158; sh: 78
file content (141 lines) | stat: -rw-r--r-- 4,088 bytes parent folder | download
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()