electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

gridview.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()