-
Notifications
You must be signed in to change notification settings - Fork 2
/
accordion.py
68 lines (56 loc) · 2.33 KB
/
accordion.py
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
from gi.repository import Gtk
class Accordion :
"""
A manager which turns a container widget with an alternating sequence of buttons and
other widgets into an accordion.
"""
def __init__(self, widget, add_end_padding):
"""
Turns the selected widget into an accordion with any button direct descendant as
headers for the widgets that follow.
:param widget: The container that has the buttons and content widgets.
:param add_end_padding: If true, an extra empty label will be appendded to the container to provide padding
"""
self.widget = widget
self.subscription = dict()
self.first = None
owner = None
for child in widget :
if isinstance(child, Gtk.Button) : # header
owner = child
self.first = self.first or child
self.subscription[owner] = list()
continue
if owner is not None : # non-header at the beginning
self.subscription[owner].append(child)
for owner in tuple(self.subscription) :
if not self.subscription[owner] :
del self.subscription[owner]
self.toggle_buttons = list()
for owner in self.subscription :
if isinstance(owner, Gtk.ToggleButton) :
self.toggle_buttons.append(owner)
owner.connect('clicked', self.on_header_click)
self.set(self.first, True)
if add_end_padding:
label = Gtk.Label()
widget.pack_start(label, True, True, 0)
label.get_style_context().add_class('accordion_end_padding')
label.show()
def set(self, button, is_active):
for child in self.subscription[button] :
child.show() if is_active else child.hide()
# turn off others
for owner in self.subscription:
if owner == button :
continue
if owner in self.toggle_buttons :
owner.set_active(False)
for child in self.subscription[owner] :
child.hide()
def on_header_click(self, button):
if button in self.toggle_buttons :
is_active = button.get_active()
else :
is_active = not self.subscription[button][0].is_visible()
return self.set(button, is_active)