248 lines
6.5 KiB
Python
248 lines
6.5 KiB
Python
"""
|
|
BoxViewer options:
|
|
{
|
|
"dataloader":{
|
|
"url",
|
|
"method",
|
|
"params"
|
|
"filter":{
|
|
}
|
|
}
|
|
"boxwidth",
|
|
"boxheight",
|
|
"viewer"
|
|
"toolbar":{
|
|
}
|
|
}
|
|
"""
|
|
from functools import partial
|
|
|
|
from traceback import print_exc
|
|
from functools import partial
|
|
from appPublic.dictExt import dictExtend
|
|
from kivy.app import App
|
|
from kivy.factory import Factory
|
|
from kivy.clock import Clock
|
|
from kivy.utils import platform
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
from kivy.graphics import Fbo, Color, Rectangle
|
|
from kivy.properties import NumericProperty, StringProperty, DictProperty
|
|
from .responsivelayout import VResponsiveLayout
|
|
from .toolbar import Toolbar
|
|
from .paging import Paging, RelatedLoader
|
|
from .utils import CSize, SUPER
|
|
from .ready import WidgetReady
|
|
from .baseWidget import VBox
|
|
|
|
|
|
class BoxViewer(VBox):
|
|
toolbar = DictProperty(None)
|
|
dataloader = DictProperty(None)
|
|
boxwidth = NumericProperty(None)
|
|
boxwidth_c = NumericProperty(None)
|
|
boxheight = NumericProperty(None)
|
|
boxheight_c = NumericProperty(None)
|
|
viewer = DictProperty(None)
|
|
viewer_url = StringProperty(None)
|
|
viewer_css = StringProperty('viewer_css')
|
|
def __init__(self, **options):
|
|
self.subwidgets = []
|
|
self.toolbar_w = None
|
|
self._dataloader = None
|
|
self.initflag = False
|
|
SUPER(BoxViewer, self, options)
|
|
self.selected_data = None
|
|
self.viewContainer = VResponsiveLayout(box_width=self.box_width)
|
|
if self.toolbar:
|
|
self.toolbar_w = Toolbar(self.toolbar)
|
|
lopts = self.dataloader.get('options', {}).copy()
|
|
self._dataloader = RelatedLoader(target=self,**lopts)
|
|
self._dataloader.bind(on_deletepage=self.deleteWidgets)
|
|
self._dataloader.bind(on_pageloaded=self.addPageWidgets)
|
|
self._dataloader.bind(on_newbegin=self.deleteAllWidgets)
|
|
self.params = lopts.get('params',{})
|
|
|
|
if self.toolbar_w:
|
|
self.add_widget(self.toolbar_w)
|
|
if self._dataloader.widget:
|
|
self.add_widget(self._dataloader.widget)
|
|
self._dataloader.widget.bind(on_submit=self.getParams)
|
|
self.add_widget(self.viewContainer)
|
|
self.register_event_type('on_selected')
|
|
self.bind(size=self.resetCols,
|
|
pos=self.resetCols)
|
|
self.viewContainer.bind(on_scroll_stop=self.on_scroll_stop)
|
|
|
|
def on_boxheight(self, *args):
|
|
self.box_height = self.boxheight
|
|
|
|
def on_boxheight_c(self, *args):
|
|
self.box_height = CSize(self.boxheight_c)
|
|
|
|
def on_boxwidth_c(self, *args):
|
|
self.box_width = CSize(self.boxwidth_c)
|
|
|
|
def on_boxwidth(self, *args):
|
|
self.box_width = self.boxwidth
|
|
|
|
def key_handle(self,keyinfo):
|
|
print('keyinfo=',keyinfo,'...................')
|
|
|
|
def getParams(self,o,p):
|
|
self.params = p
|
|
|
|
def deleteAllWidgets(self,o):
|
|
self.viewContainer.clear_widgets()
|
|
self.subwidgets = []
|
|
|
|
def getShowRows(self):
|
|
wc = self.viewContainer.get_cols()
|
|
hc = int(self.viewContainer.height / self.box_height)
|
|
self.show_rows = wc * hc
|
|
|
|
def addPageWidgets(self,o,data):
|
|
widgets = []
|
|
recs = data['data']
|
|
page = data['page']
|
|
dir = data['dir']
|
|
idx = 0
|
|
if dir == 'up':
|
|
recs.reverse()
|
|
idx = -1
|
|
recs1 = recs[:self.show_rows]
|
|
recs2 = recs[self.show_rows:]
|
|
self._fbo = Fbo(size=self.size)
|
|
with self._fbo:
|
|
self._background_color = Color(0,0,0,1)
|
|
self._background_rect = Rectangle(size=self.size)
|
|
for r in recs1:
|
|
self.showObject(widgets, r, index=idx)
|
|
with self.canvas:
|
|
self._fbo_rect = Rectangle(size=self.size,
|
|
texture=self._fbo.texture)
|
|
|
|
data['widgets'] = widgets
|
|
data['idx'] = idx
|
|
data['data'] = recs2
|
|
f = partial(self.add_page_delay, data)
|
|
Clock.schedule_once(f, 0)
|
|
|
|
def add_page_delay(self, data, *args):
|
|
recs = data['data']
|
|
page = data['page']
|
|
idx = data['idx']
|
|
widgets = data['widgets']
|
|
|
|
self._fbo = Fbo(size=self.size)
|
|
with self._fbo:
|
|
self._background_color = Color(0,0,0,1)
|
|
self._background_rect = Rectangle(size=self.size)
|
|
for r in recs:
|
|
self.showObject(widgets, r, index=idx)
|
|
with self.canvas:
|
|
self._fbo_rect = Rectangle(size=self.size,
|
|
texture=self._fbo.texture)
|
|
|
|
self.subwidgets += widgets
|
|
|
|
self._dataloader.bufferObjects(page, widgets)
|
|
x = self._dataloader.getLocater()
|
|
self.locater(x)
|
|
|
|
def loadData(self, **kw):
|
|
self.params = kw
|
|
self.deleteAllWidgets(None)
|
|
self._dataloader.loadPage(1)
|
|
self.initflag = True
|
|
|
|
def deleteWidgets(self,o,data):
|
|
for w in data:
|
|
self.viewContainer.remove_widget(w)
|
|
self.subwidget = [i for i in self.subwidgets if i in data]
|
|
|
|
def on_selected(self, data=None):
|
|
pass
|
|
|
|
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()
|
|
self.getShowRows()
|
|
if not self.initflag:
|
|
self._dataloader.loadPage(1)
|
|
self.initflag = True
|
|
|
|
def showObject(self, holders, rec,index=0):
|
|
opts = {
|
|
"size_hint":[None,None],
|
|
"height":self.box_height,
|
|
"width":self.box_width,
|
|
"color_level":self.color_level,
|
|
"radius":self.radius
|
|
}
|
|
desc = {
|
|
"widgettype":"PressableBox",
|
|
"options":opts
|
|
}
|
|
blocks = Factory.Blocks()
|
|
box = blocks.w_build(desc)
|
|
box.setValue(rec)
|
|
box.bind(on_press=self.select_record)
|
|
self.viewContainer.add_widget(box,index=index)
|
|
self.subwidgets.append(box)
|
|
holders.append(box)
|
|
desc = {}
|
|
if self.viewer_url:
|
|
desc = {
|
|
"widgettype":"urlwidget",
|
|
"options":{
|
|
"params":rec,
|
|
"method":"GET",
|
|
"url":self.viewer_url
|
|
}
|
|
}
|
|
else:
|
|
desc = self.viewer.copy()
|
|
if desc['widgettype'] == 'urlwidget':
|
|
desc = dictExtend(desc,{'options':{'params':rec}})
|
|
else:
|
|
desc = dictExtend(desc,{'options':{'record':rec}})
|
|
def add2box(p,o,w):
|
|
p.add_widget(w)
|
|
|
|
blocks = Factory.Blocks()
|
|
blocks.bind(on_built=partial(add2box,box))
|
|
blocks.widgetBuild(desc)
|
|
|
|
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):
|
|
for w in self.subwidgets:
|
|
w.box_actived = False
|
|
o.box_actived = True
|
|
self.selected_data = o.getValue()
|
|
self.dispatch('on_selected',self.selected_data)
|
|
|
|
def getValue(self):
|
|
return self.selected_data
|
|
d = {
|
|
"caller":self,
|
|
"page_rows":1,
|
|
"page":self.selected_data['__posInSet__'],
|
|
"dataurl":self.dataloader['options']['dataurl'],
|
|
"params":self.params
|
|
}
|
|
return d
|