全部を閉じれないアコーディオンの方が普通なのかな?
アコーディオンしかやりたいことに近いものがなかったんである。説明しずらいな…、絵としてこういうこと:
これまであんまし GUI 作ってこなかったヒトなんで、この kivy Accordion の振る舞いが普通なのかどうかはわからないんだけれど、とにかくこやつは必ず一つは collapse=False になる。つまり一つは必ず開いてしまう。一個しかアイテムのないアコーディオンなんてなんに使うんだ、てのは、アタシのキャプチャからわかってくれると思う。きっと本来はアコーディオンのテリトリーじゃないんだろうとは思うんだけれど、ほかに相応しいのがないのよね。
答えはここに。
ちょっとばかし気持ち悪い派生なんだけれど、一応こんなんで目的の「全閉じ可能なアコーディオン」:
1 __all__ = ('AllCollapsableAccordionItem', 'AllCollapsableAccordion')
2
3 from kivy.logger import Logger
4 from kivy.uix.accordion import AccordionException, AccordionItem, Accordion
5
6 class AllCollapsableAccordionItem(AccordionItem):
7
8 def __init__(self, **kwargs):
9 super(AllCollapsableAccordionItem, self).__init__(**kwargs)
10
11 def on_touch_down(self, touch):
12 if not self.collide_point(*touch.pos):
13 return
14 if self.disabled:
15 return True
16 if self.collapse:
17 self.collapse = False
18 return True
19 else:
20 if self.container_title.collide_point(*touch.pos):
21 self.collapse = True
22 else:
23 self.collapse = False
24 return super(AccordionItem, self).on_touch_down(touch)
25
26
27 class AllCollapsableAccordion(Accordion):
28
29 def __init__(self, **kwargs):
30 super(AllCollapsableAccordion, self).__init__(**kwargs)
31
32 def _do_layout(self, dt):
33 children = self.children
34 if children:
35 all_collapsed = all(x.collapse for x in children)
36 else:
37 all_collapsed = False
38
39 if all_collapsed:
40 children[0].collapse = True
41
42 orientation = self.orientation
43 min_space = self.min_space
44 min_space_total = len(children) * self.min_space
45 w, h = self.size
46 x, y = self.pos
47 if orientation == 'horizontal':
48 display_space = self.width - min_space_total
49 else:
50 display_space = self.height - min_space_total
51
52 if display_space <= 0:
53 Logger.warning('Accordion: not enough space '
54 'for displaying all children')
55 Logger.warning('Accordion: need %dpx, got %dpx' % (
56 min_space_total, min_space_total + display_space))
57 Logger.warning('Accordion: layout aborted.')
58 return
59
60 if orientation == 'horizontal':
61 children = reversed(children)
62
63 for child in children:
64 child_space = min_space
65 child_space += display_space * (1 - child.collapse_alpha)
66 child._min_space = min_space
67 child.x = x
68 child.y = y
69 child.orientation = self.orientation
70 if orientation == 'horizontal':
71 child.content_size = display_space, h
72 child.width = child_space
73 child.height = h
74 x += child_space
75 else:
76 child.content_size = w, display_space
77 child.width = w
78 child.height = child_space
79 y += child_space
あとは普通に kivy.uix.accordion.Accordion
、kivy.uix.accordion.AccordionItem
を使うのと同じノリで:
1 from my_accordion import (
2 AllCollapsableAccordion, AllCollapsableAccordionItem)
3
4 kv = '''
5 #(...snip...)
6
7 AllCollapsableAccordion:
8 id: extra
9 orientation: 'vertical'
10
11 AllCollapsableAccordionItem:
12 collapse: True
13 title: 'Magnetic Declination Config'
14
15 #(...snip...)
16 '''
17 Builder.load_string(kv)