tgridview.py - electrum - Electrum Bitcoin wallet
HTML git clone https://git.parazyd.org/electrum
DIR Log
DIR Files
DIR Refs
DIR Submodules
---
tgridview.py (6337B)
---
1 from kivy.uix.boxlayout import BoxLayout
2 from kivy.adapters.dictadapter import DictAdapter
3 from kivy.adapters.listadapter import ListAdapter
4 from kivy.properties import ObjectProperty, ListProperty, AliasProperty
5 from kivy.uix.listview import (ListItemButton, ListItemLabel, CompositeListItem,
6 ListView)
7 from kivy.lang import Builder
8 from kivy.metrics import dp, sp
9
10 Builder.load_string('''
11 <GridView>
12 header_view: header_view
13 content_view: content_view
14 BoxLayout:
15 orientation: 'vertical'
16 padding: '0dp', '2dp'
17 BoxLayout:
18 id: header_box
19 orientation: 'vertical'
20 size_hint: 1, None
21 height: '30dp'
22 ListView:
23 id: header_view
24 BoxLayout:
25 id: content_box
26 orientation: 'vertical'
27 ListView:
28 id: content_view
29
30 <-HorizVertGrid>
31 header_view: header_view
32 content_view: content_view
33 ScrollView:
34 id: scrl
35 do_scroll_y: False
36 RelativeLayout:
37 size_hint_x: None
38 width: max(scrl.width, dp(sum(root.widths)))
39 BoxLayout:
40 orientation: 'vertical'
41 padding: '0dp', '2dp'
42 BoxLayout:
43 id: header_box
44 orientation: 'vertical'
45 size_hint: 1, None
46 height: '30dp'
47 ListView:
48 id: header_view
49 BoxLayout:
50 id: content_box
51 orientation: 'vertical'
52 ListView:
53 id: content_view
54
55 ''')
56
57 class GridView(BoxLayout):
58 """Workaround solution for grid view by using 2 list view.
59 Sometimes the height of lines is shown properly."""
60
61 def _get_hd_adpt(self):
62 return self.ids.header_view.adapter
63
64 header_adapter = AliasProperty(_get_hd_adpt, None)
65 '''
66 '''
67
68 def _get_cnt_adpt(self):
69 return self.ids.content_view.adapter
70
71 content_adapter = AliasProperty(_get_cnt_adpt, None)
72 '''
73 '''
74
75 headers = ListProperty([])
76 '''
77 '''
78
79 widths = ListProperty([])
80 '''
81 '''
82
83 data = ListProperty([])
84 '''
85 '''
86
87 getter = ObjectProperty(lambda item, i: item[i])
88 '''
89 '''
90 on_context_menu = ObjectProperty(None)
91
92 def __init__(self, **kwargs):
93 self._from_widths = False
94 super(GridView, self).__init__(**kwargs)
95 #self.on_headers(self, self.headers)
96
97 def on_widths(self, instance, value):
98 if not self.get_root_window():
99 return
100 self._from_widths = True
101 self.on_headers(instance, self.headers)
102 self._from_widths = False
103
104 def on_headers(self, instance, value):
105 if not self._from_widths:
106 return
107 if not (value and self.canvas and self.headers):
108 return
109 widths = self.widths
110 if len(self.widths) != len(value):
111 return
112 #if widths is not None:
113 # widths = ['%sdp' % i for i in widths]
114
115 def generic_args_converter(row_index,
116 item,
117 is_header=True,
118 getter=self.getter):
119 cls_dicts = []
120 _widths = self.widths
121 getter = self.getter
122 on_context_menu = self.on_context_menu
123
124 for i, header in enumerate(self.headers):
125 kwargs = {
126 'padding': ('2dp','2dp'),
127 'halign': 'center',
128 'valign': 'middle',
129 'size_hint_y': None,
130 'shorten': True,
131 'height': '30dp',
132 'text_size': (_widths[i], dp(30)),
133 'text': getter(item, i),
134 }
135
136 kwargs['font_size'] = '9sp'
137 if is_header:
138 kwargs['deselected_color'] = kwargs['selected_color'] =\
139 [0, 1, 1, 1]
140 else: # this is content
141 kwargs['deselected_color'] = 1, 1, 1, 1
142 if on_context_menu is not None:
143 kwargs['on_press'] = on_context_menu
144
145 if widths is not None: # set width manually
146 kwargs['size_hint_x'] = None
147 kwargs['width'] = widths[i]
148
149 cls_dicts.append({
150 'cls': ListItemButton,
151 'kwargs': kwargs,
152 })
153
154 return {
155 'id': item[-1],
156 'size_hint_y': None,
157 'height': '30dp',
158 'cls_dicts': cls_dicts,
159 }
160
161 def header_args_converter(row_index, item):
162 return generic_args_converter(row_index, item)
163
164 def content_args_converter(row_index, item):
165 return generic_args_converter(row_index, item, is_header=False)
166
167
168 self.ids.header_view.adapter = ListAdapter(data=[self.headers],
169 args_converter=header_args_converter,
170 selection_mode='single',
171 allow_empty_selection=False,
172 cls=CompositeListItem)
173
174 self.ids.content_view.adapter = ListAdapter(data=self.data,
175 args_converter=content_args_converter,
176 selection_mode='single',
177 allow_empty_selection=False,
178 cls=CompositeListItem)
179 self.content_adapter.bind_triggers_to_view(self.ids.content_view._trigger_reset_populate)
180
181 class HorizVertGrid(GridView):
182 pass
183
184
185 if __name__ == "__main__":
186 from kivy.app import App
187 class MainApp(App):
188
189 def build(self):
190 data = []
191 for i in range(90):
192 data.append((str(i), str(i)))
193 self.data = data
194 return Builder.load_string('''
195 BoxLayout:
196 orientation: 'vertical'
197 HorizVertGrid:
198 on_parent: if args[1]: self.content_adapter.data = app.data
199 headers:['Address', 'Previous output']
200 widths: [400, 500]
201
202 <Label>
203 font_size: '16sp'
204 ''')
205 MainApp().run()