bugfix
This commit is contained in:
parent
1f5a8d93de
commit
9333cd9bd4
@ -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
|
||||||
|
807
kivyblocks/dg.py
807
kivyblocks/dg.py
@ -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*************')
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user