This commit is contained in:
yumoqing 2020-11-12 14:28:46 +08:00
parent 1f5a8d93de
commit 9333cd9bd4
2 changed files with 567 additions and 571 deletions

View File

@ -1,164 +1,167 @@
""" """
BoxViewer options: BoxViewer options:
{ {
"dataloader":{ "dataloader":{
"url", "url",
"method", "method",
"params" "params"
"filter":{ "filter":{
} }
} }
"boxwidth", "boxwidth",
"boxheight", "boxheight",
"viewer" "viewer"
"toolbar":{ "toolbar":{
} }
} }
""" """
from traceback import print_exc from traceback import print_exc
from functools import partial from functools import partial
from kivy.app import App from kivy.app import App
from kivy.factory import Factory from kivy.factory import Factory
from kivy.utils import platform from kivy.utils import platform
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from .responsivelayout import VResponsiveLayout from .responsivelayout import VResponsiveLayout
from .toolbar import Toolbar from .toolbar import Toolbar
from .paging import Paging, RelatedLoader from .paging import Paging, RelatedLoader
from .utils import CSize from .utils import CSize
class BoxViewer(BoxLayout): class BoxViewer(BoxLayout):
def __init__(self, **options): def __init__(self, **options):
self.toolbar = None self.toolbar = None
self.parenturl = None self.parenturl = None
self.dataloader = None self.dataloader = None
self.initflag = False self.initflag = False
self.selected_box = None self.selected_box = None
remind = ['toolbar', remind = ['toolbar',
'dataloader', 'dataloader',
'orientation', 'orientation',
'viewer', 'viewer',
'boxwidth', 'boxwidth',
'boxheight'] 'boxheight']
kwargs = {k:v for k,v in options.items() if k not in remind } kwargs = {k:v for k,v in options.items() if k not in remind }
BoxLayout.__init__(self, orientation='vertical', **kwargs) BoxLayout.__init__(self, orientation='vertical', **kwargs)
self.selected_data = None self.selected_data = None
self.options = options self.options = options
self.box_width = CSize(options['boxwidth']) self.box_width = CSize(options['boxwidth'])
self.box_height = CSize(options['boxheight']) self.box_height = CSize(options['boxheight'])
self.viewContainer = VResponsiveLayout(cols=2,box_width=self.box_width) self.viewContainer = VResponsiveLayout(cols=2,box_width=self.box_width)
if options.get('toolbar'): if options.get('toolbar'):
self.toolbar = Toolbar(options['toolbar']) self.toolbar = Toolbar(options['toolbar'])
lopts = options['dataloader'].copy() lopts = options['dataloader'].copy()
self.dataloader = RelatedLoader(target=self,**lopts['options']) if lopts.get('options'):
self.dataloader.bind(on_deletepage=self.deleteWidgets) lopts = lopts.get('options')
self.dataloader.bind(on_pageloaded=self.addPageWidgets) self.dataloader = RelatedLoader(target=self,**lopts)
self.dataloader.bind(on_newbegin=self.deleteAllWidgets) self.dataloader.bind(on_deletepage=self.deleteWidgets)
self.params = self.options['dataloader']['options'].get('params',{}) self.dataloader.bind(on_pageloaded=self.addPageWidgets)
self.dataloader.bind(on_newbegin=self.deleteAllWidgets)
if self.toolbar: self.params = self.options['dataloader']['options'].get('params',{})
self.add_widget(self.toolbar)
if self.dataloader.widget: if self.toolbar:
self.add_widget(self.dataloader.widget) self.add_widget(self.toolbar)
self.dataloader.bind(on_submit=self.getParams) if self.dataloader.widget:
self.add_widget(self.viewContainer) self.add_widget(self.dataloader.widget)
self.register_event_type('on_selected') self.dataloader.bind(on_submit=self.getParams)
self.viewContainer.bind(size=self.resetCols, self.add_widget(self.viewContainer)
pos=self.resetCols) self.register_event_type('on_selected')
self.viewContainer.bind(on_scroll_stop=self.on_scroll_stop) self.viewContainer.bind(size=self.resetCols,
pos=self.resetCols)
def getParams(self,o,p): self.viewContainer.bind(on_scroll_stop=self.on_scroll_stop)
self.params = p
def getParams(self,o,p):
def deleteAllWidgets(self,o): self.params = p
self.viewContainer.clear_widgets()
def deleteAllWidgets(self,o):
def addPageWidgets(self,o,data): self.viewContainer.clear_widgets()
widgets = []
recs = data['data'] def addPageWidgets(self,o,data):
dir = data['dir'] widgets = []
idx = 0 recs = data['data']
if dir == 'up': page = data['page']
recs.reverse() dir = data['dir']
idx = -1 idx = 0
for r in recs: if dir == 'up':
self.showObject(widgets, r, index=idx) recs.reverse()
idx = -1
self.dataloader.bufferObjects(widgets) for r in recs:
x = self.dataloader.getLocater() self.showObject(widgets, r, index=idx)
self.locater(x)
self.dataloader.bufferObjects(page, widgets)
def deleteWidgets(self,o,data): x = self.dataloader.getLocater()
for w in data: self.locater(x)
self.viewContainer.remove_widget(w)
def deleteWidgets(self,o,data):
def on_selected(self, o, v=None): for w in data:
pass self.viewContainer.remove_widget(w)
def locater(self, pos): def on_selected(self, o, v=None):
self.viewContainer.scroll_y = pos pass
def resetCols(self,o=None, v=None): def locater(self, pos):
h = 0 self.viewContainer.scroll_y = pos
if self.toolbar:
h += self.toolbar.height def resetCols(self,o=None, v=None):
if self.dataloader.widget: h = 0
h += self.dataloader.widget.height if self.toolbar:
self.viewContainer.height = self.height - h h += self.toolbar.height
if self.dataloader.widget:
self.viewContainer.setCols() h += self.dataloader.widget.height
if not self.initflag: self.viewContainer.height = self.height - h
self.dataloader.loadPage(1)
self.initflag = True self.viewContainer.setCols()
if not self.initflag:
def showObject(self, holders, rec,index=0): self.dataloader.loadPage(1)
def doit(self,holders,idx,o,w): self.initflag = True
w.bind(on_press=self.select_record)
self.viewContainer.add_widget(w,index=idx) def showObject(self, holders, rec,index=0):
holders.append(w) def doit(self,holders,idx,o,w):
w.bind(on_press=self.select_record)
def doerr(o,e): self.viewContainer.add_widget(w,index=idx)
print_exc() holders.append(w)
print('showObject(),error=',e)
raise e def doerr(o,e):
options = self.options['viewer'].copy() print_exc()
options['options']['record'] = rec print('showObject(),error=',e)
options['options']['ancestor'] = self raise e
options['options']['size_hint'] = None,None options = self.options['viewer'].copy()
options['options']['width'] = self.box_width options['options']['record'] = rec
options['options']['height'] = self.box_height options['options']['ancestor'] = self
blocks = Factory.Blocks() options['options']['size_hint'] = None,None
blocks.bind(on_built=partial(doit,self,holders,index)) options['options']['width'] = self.box_width
blocks.bind(on_failed=doerr) options['options']['height'] = self.box_height
blocks.widgetBuild(options, ancestor=self) blocks = Factory.Blocks()
blocks.bind(on_built=partial(doit,self,holders,index))
def on_scroll_stop(self,o,v=None): blocks.bind(on_failed=doerr)
if o.scroll_y <= 0.001: blocks.widgetBuild(options, ancestor=self)
self.dataloader.loadNextPage()
if o.scroll_y >= 0.999: def on_scroll_stop(self,o,v=None):
self.dataloader.loadPreviousPage() if o.scroll_y <= 0.001:
self.dataloader.loadNextPage()
def select_record(self,o,v=None): if o.scroll_y >= 0.999:
if self.selected_box: self.dataloader.loadPreviousPage()
self.selected_box.unselected()
o.selected() def select_record(self,o,v=None):
self.selected_box = o if self.selected_box:
self.selected_box.unselected()
self.selected_data = o.getRecord() o.selected()
d = { self.selected_box = o
"target":self.selected_box,
"page_rows":1, self.selected_data = o.getRecord()
"page":self.selected_data['__posInSet__'], d = {
"dataurl":self.options['dataloader']['options']['dataurl'], "target":self.selected_box,
"params":self.params "page_rows":1,
} "page":self.selected_data['__posInSet__'],
self.dispatch('on_selected',d) "dataurl":self.options['dataloader']['options']['dataurl'],
"params":self.params
def getData(self): }
d = { self.dispatch('on_selected',d)
"caller":self,
"page_rows":1, def getData(self):
"page":self.selected_data['__posInSet__'], d = {
"dataurl":self.options['dataloader']['options']['dataurl'], "caller":self,
"params":self.params "page_rows":1,
} "page":self.selected_data['__posInSet__'],
return d "dataurl":self.options['dataloader']['options']['dataurl'],
"params":self.params
}
return d

View File

@ -1,407 +1,400 @@
import time import time
from kivy.uix.gridlayout import GridLayout from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label from kivy.uix.label import Label
from kivy.uix.button import ButtonBehavior from kivy.uix.button import ButtonBehavior
from kivy.clock import Clock from kivy.clock import Clock
from kivy.properties import BooleanProperty from kivy.properties import BooleanProperty
from kivy.properties import ListProperty from kivy.properties import ListProperty
from kivy.graphics import Color, Rectangle from kivy.graphics import Color, Rectangle
from kivy.app import App from kivy.app import App
from kivy.factory import Factory from kivy.factory import Factory
from appPublic.dictObject import DictObject from appPublic.dictObject import DictObject
from appPublic.timecost import TimeCost from appPublic.timecost import TimeCost
from appPublic.uniqueID import getID from appPublic.uniqueID import getID
from .utils import CSize, setSizeOptions, loading, loaded, absurl, alert from .utils import CSize, setSizeOptions, loading, loaded, absurl, alert
from .baseWidget import Text from .baseWidget import Text
from .widgetExt import ScrollWidget from .widgetExt import ScrollWidget
from .paging import Paging, RelatedLoader from .paging import Paging, RelatedLoader
from .ready import WidgetReady from .ready import WidgetReady
from .toolbar import Toolbar from .toolbar import Toolbar
from .i18n import I18nText from .i18n import I18nText
class BLabel(ButtonBehavior, Text): class BLabel(ButtonBehavior, Text):
def __init__(self, **kw): def __init__(self, **kw):
ButtonBehavior.__init__(self) ButtonBehavior.__init__(self)
Text.__init__(self,**kw) Text.__init__(self,**kw)
class Cell(BoxLayout): class Cell(BoxLayout):
def __init__(self,row,desc): def __init__(self,row,desc):
""" """
desc:{ desc:{
width, width,
datatype:fff datatype:fff
value: value:
format: format:
on_press: on_press:
} }
""" """
self.desc = desc self.desc = desc
self.row = row self.row = row
super().__init__(size_hint=(None,None), super().__init__(size_hint=(None,None),
width = self.desc['width'], width = self.desc['width'],
height = self.row.part.datagrid.rowHeight() height = self.row.part.datagrid.rowHeight()
) )
if not self.row.header and self.desc.get('viewer'): if not self.row.header and self.desc.get('viewer'):
viewer = self.desc.get('viewer') viewer = self.desc.get('viewer')
blocks = Factory.Blocks() blocks = Factory.Blocks()
if isinstance(viewer,str): if isinstance(viewer,str):
l = self.desc.copy() l = self.desc.copy()
l['row'] = self.row l['row'] = self.row
viewer = blocks.eval(viewer,l) viewer = blocks.eval(viewer,l)
if isinstance(viewer,dict): if isinstance(viewer,dict):
print('viewer = ', viewer) print('viewer = ', viewer)
w = blocks.widgetBuild(viewer,ancestor=self.row.part.datagrid) w = blocks.widgetBuild(viewer,ancestor=self.row.part.datagrid)
self.add_widget(w) self.add_widget(w)
return return
if desc['header']: if desc['header']:
bl = I18nText(otext=str(desc['value']), bl = I18nText(otext=str(desc['value']),
font_size=CSize(1), font_size=CSize(1),
halign='left' halign='left'
) )
else: else:
bl = BLabel(text = str(desc['value']), bl = BLabel(text = str(desc['value']),
font_size=CSize(1), font_size=CSize(1),
halign='left' halign='left'
) )
self.add_widget(bl) self.add_widget(bl)
bl.bind(on_press=self.cell_press) bl.bind(on_press=self.cell_press)
def cell_press(self,obj): def cell_press(self,obj):
self.row.selected() self.row.selected()
class Row(GridLayout): class Row(GridLayout):
def __init__(self,part, rowdesc,header=False,data=None): def __init__(self,part, rowdesc,header=False,data=None):
""" """
rowdesc=[ rowdesc=[
{ {
width, width,
name name
value value
on_press on_press
} }
""" """
self.part = part self.part = part
self.header = header self.header = header
self.row_data = data self.row_data = data
self.row_id = None self.row_id = None
self.linewidth = 1 self.linewidth = 1
self.rowdesc = rowdesc self.rowdesc = rowdesc
super().__init__(cols=len(self.rowdesc),spacing=self.linewidth) super().__init__(cols=len(self.rowdesc),spacing=self.linewidth)
# Clock.schedule_once(self.init,0) # Clock.schedule_once(self.init,0)
self.init(0) self.init(0)
def init(self,t): def init(self,t):
w = 0 w = 0
h = 0 h = 0
for c in self.rowdesc: for c in self.rowdesc:
c['header'] = self.header c['header'] = self.header
cell = Cell(self,c) cell = Cell(self,c)
self.add_widget(cell) self.add_widget(cell)
w += cell.width w += cell.width
if cell.height > h: if cell.height > h:
h = cell.height h = cell.height
self.size_hint = None,None self.size_hint = None,None
self.width = w + self.linewidth * 2 * len(self.rowdesc) self.width = w + self.linewidth * 2 * len(self.rowdesc)
self.height = h #self.part.datagrid.rowHeight() self.height = h #self.part.datagrid.rowHeight()
def selected(self): def selected(self):
if not hasattr(self,'row_data'): if not hasattr(self,'row_data'):
return # header return # header
print('row selected',self.row_id, self.row_data) print('row selected',self.row_id, self.row_data)
self.part.datagrid.row_selected = True self.part.datagrid.row_selected = True
self.part.datagrid.select_rowid = self.row_id self.part.datagrid.select_rowid = self.row_id
self.part.datagrid.dispatch('on_selected',self) self.part.datagrid.dispatch('on_selected',self)
class Header(WidgetReady, ScrollWidget): class Header(WidgetReady, ScrollWidget):
def __init__(self,part,**kw): def __init__(self,part,**kw):
self.part = part self.part = part
ScrollWidget.__init__(self,**kw) ScrollWidget.__init__(self,**kw)
WidgetReady.__init__(self) WidgetReady.__init__(self)
self.init(1) self.init(1)
self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop) self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop)
def init(self,t): def init(self,t):
rd = [ f.copy() for f in self.part.rowdesc ] rd = [ f.copy() for f in self.part.rowdesc ]
[ f.update({'value':self.part.fields[i]['label']}) for i,f in enumerate(rd) ] [ f.update({'value':self.part.fields[i]['label']}) for i,f in enumerate(rd) ]
self.header = Row(self.part,rd,header=True) self.header = Row(self.part,rd,header=True)
self.add_widget(self.header) self.add_widget(self.header)
self.height = self.header.height self.height = self.header.height
class Body(ScrollWidget): class Body(ScrollWidget):
def __init__(self,part,**kw): def __init__(self,part,**kw):
self.part = part self.part = part
ScrollWidget.__init__(self,**kw) ScrollWidget.__init__(self,**kw)
self.idRow = {} self.idRow = {}
self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop) self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop)
def addRow(self,id, data,index=0): def addRow(self,id, data,index=0):
rd = [ f.copy() for f in self.part.rowdesc ] rd = [ f.copy() for f in self.part.rowdesc ]
[ f.update({'value':data.get(f['name'])}) for f in rd ] [ f.update({'value':data.get(f['name'])}) for f in rd ]
row = Row(self.part,rd,data=data) row = Row(self.part,rd,data=data)
row.row_id = id row.row_id = id
self.add_widget(row,index=index) self.add_widget(row,index=index)
self.idRow[id] = row self.idRow[id] = row
return row
def clearRows(self):
self.idRow = {} def clearRows(self):
self.clear_widgets() self.idRow = {}
self.clear_widgets()
def delRowById(self,id):
row = self.idRow[id] def delRowById(self,id):
self.remove_widget(row) row = self.idRow[id]
del self.idRow[id] self.remove_widget(row)
del self.idRow[id]
def getRowData(self,rowid):
return self.idRow[rowid].row_data def getRowData(self,rowid):
return self.idRow[rowid].row_data
def getRowHeight(self):
return self.part.datagrid.rowHeight() def getRowHeight(self):
return self.part.datagrid.rowHeight()
class DataGridPart(WidgetReady, BoxLayout):
def __init__(self,dg, freeze_flag, fields): class DataGridPart(WidgetReady, BoxLayout):
self.datagrid = dg def __init__(self,dg, freeze_flag, fields):
self.fields = fields self.datagrid = dg
self.freeze_flag = freeze_flag self.fields = fields
self.fields_width = None self.freeze_flag = freeze_flag
BoxLayout.__init__(self, orientation='vertical') self.fields_width = None
WidgetReady.__init__(self) BoxLayout.__init__(self, orientation='vertical')
# Clock.schedule_once(self.init,0.1) WidgetReady.__init__(self)
self.init(0) # Clock.schedule_once(self.init,0.1)
self.init(0)
def setWidth(self):
if self.freeze_flag: def setWidth(self):
self.size_hint_x = None if self.freeze_flag:
self.width = self.getFieldsWidth() self.size_hint_x = None
self.width = self.getFieldsWidth()
def getFieldsWidth(self):
if not self.fields_width: def getFieldsWidth(self):
width = 0 if not self.fields_width:
for f in self.rowdesc: width = 0
width += f['width'] for f in self.rowdesc:
self.fields_width = width width += f['width']
return self.fields_width self.fields_width = width
return self.fields_width
def init(self,t):
rd = [] def init(self,t):
for f in self.fields: rd = []
r = f.copy() for f in self.fields:
r['width'] = CSize(f.get('width',10)) r = f.copy()
rd.append(r) r['width'] = CSize(f.get('width',10))
self.rowdesc = rd rd.append(r)
self.setWidth() self.rowdesc = rd
kw = {} self.setWidth()
if self.freeze_flag: kw = {}
kw['width'] = self.fields_width if self.freeze_flag:
kw['size_hint'] = (None,None) kw['width'] = self.fields_width
else: kw['size_hint'] = (None,None)
kw['size_hint'] = (1,None) else:
kw['size_hint'] = (1,None)
kw['height'] = self.datagrid.rowHeight()
kw['height'] = self.datagrid.rowHeight()
if not self.datagrid.noheader:
self.header = Header(self,**kw) if not self.datagrid.noheader:
self.add_widget(self.header) self.header = Header(self,**kw)
self.body = Body(self) self.add_widget(self.header)
self.add_widget(self.body) self.body = Body(self)
if not self.freeze_flag: self.add_widget(self.body)
self.body.bind(pos=self.datagrid.bodyOnSize, if not self.freeze_flag:
size=self.datagrid.bodyOnSize) self.body.bind(pos=self.datagrid.bodyOnSize,
size=self.datagrid.bodyOnSize)
def clearRows(self):
return self.body.clearRows() def clearRows(self):
return self.body.clearRows()
def addRow(self,id, data):
self.body.addRow(id, data) def addRow(self,id, data):
return self.body.addRow(id, data)
class DataGrid(WidgetReady, BoxLayout):
row_selected = BooleanProperty(False) class DataGrid(WidgetReady, BoxLayout):
def __init__(self,**options): row_selected = BooleanProperty(False)
kw = DictObject() def __init__(self,**options):
kw = setSizeOptions(options,kw) kw = DictObject()
kw.orientation = 'vertical' kw = setSizeOptions(options,kw)
WidgetReady.__init__(self) kw.orientation = 'vertical'
BoxLayout.__init__(self,**kw) WidgetReady.__init__(self)
self.parenturl = options.get('parenturl',None) BoxLayout.__init__(self,**kw)
self.options = options self.parenturl = options.get('parenturl',None)
self.noheader = options.get('noheader',False) self.options = options
self.header_bgcolor = options.get('header_bgcolor',[0.29,0.29,0.29,1]) self.noheader = options.get('noheader',False)
self.body_bgcolor = options.get('body_bgcolor',[0.25,0.25,0.25,1]) self.header_bgcolor = options.get('header_bgcolor',[0.29,0.29,0.29,1])
self.color = options.get('color',[0.91,0.91,0.91,1]) self.body_bgcolor = options.get('body_bgcolor',[0.25,0.25,0.25,1])
self.widget_ids = {} self.color = options.get('color',[0.91,0.91,0.91,1])
self.row_height = None self.widget_ids = {}
self.selected_rowid = None self.row_height = None
self.dataUrl = self.options.get('dataurl') self.selected_rowid = None
self.show_rows = 0 self.dataUrl = self.options.get('dataurl')
self.toolbar = None self.show_rows = 0
self.freeze_part = None self.toolbar = None
self.normal_part = None self.freeze_part = None
self.page_rows = self.options.get('page_rows', 60) self.normal_part = None
self.params = self.options.get('params',{}) self.page_rows = self.options.get('page_rows', 60)
self.total_cnt = 0 self.params = self.options.get('params',{})
self.max_row = 0 self.total_cnt = 0
self.curpage = 0 self.max_row = 0
self.loading = False self.curpage = 0
self.freeze_fields = self.getPartFields(freeze_flag=True) self.loading = False
self.normal_fields = self.getPartFields(freeze_flag=False) self.freeze_fields = self.getPartFields(freeze_flag=True)
self.createDataGridPart() self.normal_fields = self.getPartFields(freeze_flag=False)
self.createToolbar() self.createDataGridPart()
if self.toolbar: self.createToolbar()
self.add_widget(self.toolbar) if self.toolbar:
self.add_widget(self.toolbar)
b = BoxLayout(orientation='horizontal')
if self.freeze_part: b = BoxLayout(orientation='horizontal')
b.add_widget(self.freeze_part) if self.freeze_part:
if self.normal_part: b.add_widget(self.freeze_part)
b.add_widget(self.normal_part) if self.normal_part:
self.add_widget(b) b.add_widget(self.normal_part)
if self.options.get('paging',False): self.add_widget(b)
self.loader = Paging(adder=self.addRow, ldr_desc = options.get('dataloader')
clearer=self.clearRows, if not ldr_desc:
dataurl=self.dataUrl, raise Exception('DataGrid need a DataLoader')
target=self, self.dataloader = RelatedLoader(target=self, **ldr_desc)
params=self.params, self.dataloader.bind(on_deletepage=self.delete_page)
method=self.options.get('method','GET') self.dataloader.bind(on_pageloaded=self.add_page)
) self.dataloader.bind(on_newbegin=self.clearRows)
self.add_widget(self.loader.widget) self.on_sizeTask = None
else: self.register_event_type('on_selected')
self.loader = RelatedLoader(adder=self.addRow, self.register_event_type('on_scrollstop')
remover=self.delRow,
locater=self.setScrollPosition, def locater(self,pos):
page_rows=self.page_rows, self.normal_part.body.scroll_y = pos
dataurl=self.dataUrl, if self.freeze_part:
target=self, self.freeze_part.body.scroll_y = pos
params=self.params,
method=self.options.get('method','GET') def on_scrollstop(self,o,v=None):
) if not self.noheader and o == self.normal_part.header:
self.on_sizeTask = None self.normal_part.body.scroll_x = o.scroll_x
self.register_event_type('on_selected') return
self.register_event_type('on_scrollstop') if o == self.normal_part.body:
if not self.noheader:
def setScrollPosition(self,pos): self.normal_part.header.scroll_x = o.scroll_x
self.normal_part.body.scroll_y = pos if self.freeze_part:
if self.freeze_part: self.freeze_part.body.scroll_y = o.scroll_y
self.freeze_part.body.scroll_y = pos if self.freeze_part and o == self.freeze_part.body:
self.normal_part.body.scroll_y = o.scroll_y
def on_scrollstop(self,o,v=None):
if not self.noheader and o == self.normal_part.header: if o.scroll_y <= 0.001:
self.normal_part.body.scroll_x = o.scroll_x self.loader.loadNextPage()
return if o.scroll_y >= 0.999:
if o == self.normal_part.body: self.loader.loadPreviousPage()
if not self.noheader:
self.normal_part.header.scroll_x = o.scroll_x def getData(self):
if self.freeze_part: if not self.row_selected:
self.freeze_part.body.scroll_y = o.scroll_y return None
if self.freeze_part and o == self.freeze_part.body: return self._getRowData(self.select_rowid)
self.normal_part.body.scroll_y = o.scroll_y
def _getRowData(self, rowid):
if self.options.get('paging'): d = {}
return if self.freeze_part:
if o.scroll_y <= 0.001: d.update(self.freeze_part.body.getRowData(rowid))
self.loader.loadNextPage() d.update(self.normal_part.body.getRowData(rowid))
if o.scroll_y >= 0.999: print('getData() return=',d)
self.loader.loadPreviousPage() return DictObject(**d)
def getData(self): def bodyOnSize(self,o,s):
if not self.row_selected: if self.on_sizeTask is not None:
return None self.on_sizeTask.cancel()
return self._getRowData(self.select_rowid) self.on_sizeTask = Clock.schedule_once(self.calculateShowRows,0.3)
def _getRowData(self, rowid): def rowHeight(self):
d = {} if not self.row_height:
if self.freeze_part: self.row_height = CSize(self.options.get('row_height',1.8))
d.update(self.freeze_part.body.getRowData(rowid))
d.update(self.normal_part.body.getRowData(rowid)) return self.row_height
print('getData() return=',d)
return DictObject(**d) def calculateShowRows(self,t):
print('body height=',self.normal_part.body.height
def bodyOnSize(self,o,s): ,'row_height=',self.rowHeight()
if self.on_sizeTask is not None: )
self.on_sizeTask.cancel() self.show_rows = int(self.normal_part.body.height/self.rowHeight())
self.on_sizeTask = Clock.schedule_once(self.calculateShowRows,0.3) self.loader.setPageRows(self.show_rows)
def rowHeight(self): def getShowRows(self):
if not self.row_height: if self.show_rows == 0:
self.row_height = CSize(self.options.get('row_height',1.8)) return 60
return self.show_rows
return self.row_height
def clearRows(self):
def calculateShowRows(self,t): if self.freeze_part:
print('body height=',self.normal_part.body.height self.freeze_part.body.clearRows()
,'row_height=',self.rowHeight() self.normal_part.body.clearRows()
)
self.show_rows = int(self.normal_part.body.height/self.rowHeight()) def add_page(self,o,data):
self.loader.setPageRows(self.show_rows) ids = []
recs = data['data']
def getShowRows(self): page = data['page']
if self.show_rows == 0: dir = data['dir']
return 60 idx = 0
return self.show_rows if dir == 'up':
recs.reverse()
def init(self,t): idx = -1
if self.options.get('dataurl'): for r in recs:
self.loader.loadPage(1) ids.append(self.addRow(r,index=idx))
else: self.dataloader.bufferObjects(page,ids)
data = self.options.get('data',[]) x = self.dataloader.getLocater()
if len(data) > 0: self.locater(x)
loading(self)
for d in data: def delete_page(self,o,data):
self.addRow() for id in data:
loaded(self) self.delRow(id)
def clearRows(self): def addRow(self,data, **kw):
if self.freeze_part: id = getID()
self.freeze_part.body.clearRows() f_row = None
self.normal_part.body.clearRows() if self.freeze_part:
self.freeze_part.body.addRow(id, data, **kw)
def addRow(self,data, **kw): self.normal_part.body.addRow(id, data, **kw)
id = getID() return id
if self.freeze_part:
self.freeze_part.body.addRow(id, data, **kw) def delRow(self,id,**kw):
self.normal_part.body.addRow(id, data, **kw) if self.freeze_part:
return id self.freeze_part.body.delRowById(id)
self.normal_part.body.delRowById(id)
def setData(self,data):
for d in data: def createToolbar(self):
self.addRow(d) if 'toolbar' in self.options.keys():
tb = self.options['toolbar']
def delRow(self,id,**kw): self.toolbar = Toolbar(ancestor=self,**tb)
if self.freeze_part:
self.freeze_part.body.delRowById(id) def on_selected(self,row):
self.normal_part.body.delRowById(id) self.selected_row = row
def createToolbar(self): def createDataGridPart(self):
if 'toolbar' in self.options.keys(): self.freeze_part = None
tb = self.options['toolbar'] self.normal_part = None
self.toolbar = Toolbar(ancestor=self,**tb) if self.freeze_fields:
self.freeze_part = DataGridPart(self,True, self.freeze_fields)
def on_selected(self,row): if self.normal_fields:
self.selected_row = row self.normal_part = DataGridPart(self, False, self.normal_fields)
def createDataGridPart(self): def getPartFields(self,freeze_flag:bool=False) -> list:
self.freeze_part = None fs = []
self.normal_part = None for f in self.options['fields']:
if self.freeze_fields: if freeze_flag:
self.freeze_part = DataGridPart(self,True, self.freeze_fields) if f.get('freeze',False):
if self.normal_fields: fs.append(f)
self.normal_part = DataGridPart(self, False, self.normal_fields) else:
if not f.get('freeze',False):
def getPartFields(self,freeze_flag:bool=False) -> list: fs.append(f)
fs = [] return fs
for f in self.options['fields']:
if freeze_flag: def on_ready(self,o,v=None):
if f.get('freeze',False): print('***********onRadey*************')
fs.append(f)
else: Factory.register('DataGrid',DataGrid)
if not f.get('freeze',False):
fs.append(f)
return fs
def on_ready(self,o,v=None):
print('***********onRadey*************')