kivyblocks/kivyblocks/boxViewer.py

179 lines
4.6 KiB
Python
Raw Normal View History

2019-12-19 11:13:47 +08:00
"""
BoxViewer options:
{
"dataloader":{
"url",
"method",
"params"
"filter":{
}
}
"boxwidth",
"boxheight",
"viewer"
"toolbar":{
}
}
"""
2020-04-24 18:35:30 +08:00
from traceback import print_exc
from functools import partial
2019-12-19 11:13:47 +08:00
from kivy.app import App
2020-04-24 18:35:30 +08:00
from kivy.factory import Factory
2019-12-19 11:13:47 +08:00
from kivy.utils import platform
from kivy.uix.boxlayout import BoxLayout
from .responsivelayout import VResponsiveLayout
from .toolbar import Toolbar
from .paging import Paging, RelatedLoader
from .utils import CSize
2020-11-13 18:00:26 +08:00
from .ready import WidgetReady
2019-12-19 11:13:47 +08:00
2020-11-13 18:00:26 +08:00
class BoxViewer(WidgetReady, BoxLayout):
2019-12-19 11:13:47 +08:00
def __init__(self, **options):
self.toolbar = None
self.parenturl = None
self.dataloader = None
self.initflag = False
2020-09-19 11:30:14 +08:00
self.selected_box = None
2020-07-12 23:02:07 +08:00
remind = ['toolbar',
'dataloader',
'orientation',
'viewer',
'boxwidth',
'boxheight']
2020-07-13 17:06:55 +08:00
kwargs = {k:v for k,v in options.items() if k not in remind }
2020-07-12 23:02:07 +08:00
BoxLayout.__init__(self, orientation='vertical', **kwargs)
2020-11-13 18:00:26 +08:00
WidgetReady.__init__(self)
2020-11-13 21:56:44 +08:00
self.use_keyboard()
2019-12-19 11:13:47 +08:00
self.selected_data = None
self.options = options
self.box_width = CSize(options['boxwidth'])
self.box_height = CSize(options['boxheight'])
self.viewContainer = VResponsiveLayout(cols=2,box_width=self.box_width)
if options.get('toolbar'):
self.toolbar = Toolbar(options['toolbar'])
lopts = options['dataloader'].copy()
2020-11-12 11:19:47 +08:00
if lopts.get('options'):
lopts = lopts.get('options')
self.dataloader = RelatedLoader(target=self,**lopts)
2020-04-24 18:35:30 +08:00
self.dataloader.bind(on_deletepage=self.deleteWidgets)
self.dataloader.bind(on_pageloaded=self.addPageWidgets)
self.dataloader.bind(on_newbegin=self.deleteAllWidgets)
2020-04-29 10:43:38 +08:00
self.params = self.options['dataloader']['options'].get('params',{})
2020-04-24 18:35:30 +08:00
2019-12-19 11:13:47 +08:00
if self.toolbar:
self.add_widget(self.toolbar)
if self.dataloader.widget:
self.add_widget(self.dataloader.widget)
2020-04-29 10:43:38 +08:00
self.dataloader.bind(on_submit=self.getParams)
2019-12-19 11:13:47 +08:00
self.add_widget(self.viewContainer)
self.register_event_type('on_selected')
self.viewContainer.bind(size=self.resetCols,
pos=self.resetCols)
self.viewContainer.bind(on_scroll_stop=self.on_scroll_stop)
2020-04-29 10:43:38 +08:00
def getParams(self,o,p):
self.params = p
2020-04-24 18:35:30 +08:00
def deleteAllWidgets(self,o):
self.viewContainer.clear_widgets()
def addPageWidgets(self,o,data):
widgets = []
recs = data['data']
2020-11-12 11:19:47 +08:00
page = data['page']
2020-04-24 18:35:30 +08:00
dir = data['dir']
idx = 0
if dir == 'up':
recs.reverse()
idx = -1
for r in recs:
self.showObject(widgets, r, index=idx)
2020-11-12 11:19:47 +08:00
self.dataloader.bufferObjects(page, widgets)
2020-04-24 18:35:30 +08:00
x = self.dataloader.getLocater()
self.locater(x)
def deleteWidgets(self,o,data):
for w in data:
self.viewContainer.remove_widget(w)
2019-12-19 11:13:47 +08:00
def on_selected(self, o, v=None):
2020-07-14 22:10:04 +08:00
pass
2019-12-19 11:13:47 +08:00
def locater(self, pos):
self.viewContainer.scroll_y = pos
def resetCols(self,o=None, v=None):
h = 0
if self.toolbar:
h += self.toolbar.height
if self.dataloader.widget:
h += self.dataloader.widget.height
self.viewContainer.height = self.height - h
self.viewContainer.setCols()
if not self.initflag:
self.dataloader.loadPage(1)
self.initflag = True
2020-11-13 18:00:26 +08:00
def on_key_down(self,keyinfo):
if keyinfo['keyname'] == 'enter':
self.selected_box.on_press()
if keyinfo['keyname'] == 'down':
print('down key entried')
if keyinfo['keyname'] == 'up':
print('up key entried')
2020-04-24 18:35:30 +08:00
def showObject(self, holders, rec,index=0):
def doit(self,holders,idx,o,w):
w.bind(on_press=self.select_record)
self.viewContainer.add_widget(w,index=idx)
holders.append(w)
def doerr(o,e):
print_exc()
print('showObject(),error=',e)
raise e
2019-12-19 11:13:47 +08:00
options = self.options['viewer'].copy()
options['options']['record'] = rec
options['options']['ancestor'] = self
options['options']['size_hint'] = None,None
options['options']['width'] = self.box_width
options['options']['height'] = self.box_height
2020-04-24 18:35:30 +08:00
blocks = Factory.Blocks()
blocks.bind(on_built=partial(doit,self,holders,index))
blocks.bind(on_failed=doerr)
blocks.widgetBuild(options, ancestor=self)
2019-12-19 11:13:47 +08:00
def on_scroll_stop(self,o,v=None):
if o.scroll_y <= 0.001:
self.dataloader.loadNextPage()
if o.scroll_y >= 0.999:
self.dataloader.loadPreviousPage()
def select_record(self,o,v=None):
2020-09-19 11:30:14 +08:00
if self.selected_box:
self.selected_box.unselected()
o.selected()
self.selected_box = o
2019-12-19 11:13:47 +08:00
self.selected_data = o.getRecord()
2020-04-29 10:43:38 +08:00
d = {
2020-09-19 11:30:14 +08:00
"target":self.selected_box,
2020-04-29 10:43:38 +08:00
"page_rows":1,
"page":self.selected_data['__posInSet__'],
"dataurl":self.options['dataloader']['options']['dataurl'],
"params":self.params
}
self.dispatch('on_selected',d)
2019-12-19 11:13:47 +08:00
def getData(self):
2020-04-29 10:43:38 +08:00
d = {
"caller":self,
"page_rows":1,
"page":self.selected_data['__posInSet__'],
"dataurl":self.options['dataloader']['options']['dataurl'],
"params":self.params
}
return d