This commit is contained in:
yumoqing 2022-01-20 23:19:05 +08:00
parent 27b5057d33
commit 4e8e183307
2 changed files with 43 additions and 201 deletions

View File

@ -1,5 +1,6 @@
from appPublic.timeUtils import curDateString, monthMaxDay from appPublic.timeUtils import curDateString, monthMaxDay
from kivy.clock import Clock
from kivy.factory import Factory from kivy.factory import Factory
from kivy.properties import NumericProperty from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
@ -16,6 +17,8 @@ class YearInput(SelectInput):
self.showed_max = None self.showed_max = None
self.valueField = self.dropdown.valueField self.valueField = self.dropdown.valueField
self.textField = self.dropdown.textField self.textField = self.dropdown.textField
self.reopen = False
self.dropdown.bind(on_dismiss=self.reopen_dropdown)
def e_year_change(self, y): def e_year_change(self, y):
self.e_year = y self.e_year = y
@ -44,6 +47,11 @@ class YearInput(SelectInput):
}) })
return d return d
def reopen_dropdown(self, *args):
if not self.reopen:
return
self.dropdown.open(self)
def dropdown_select(self, o, d): def dropdown_select(self, o, d):
if d[0] == -10000: if d[0] == -10000:
smin = self.showed_min - self.show_years smin = self.showed_min - self.show_years
@ -51,6 +59,7 @@ class YearInput(SelectInput):
smin = 0 smin = 0
smax = smin + self.show_years smax = smin + self.show_years
self.set_selectable_data(self.years_data(smin, smax)) self.set_selectable_data(self.years_data(smin, smax))
self.reopen = True
return return
if d[0] == 10000: if d[0] == 10000:
smax = self.showed_max + self.show_years smax = self.showed_max + self.show_years
@ -58,9 +67,10 @@ class YearInput(SelectInput):
smax = 9999 smax = 9999
smin = smax - self.show_years smin = smax - self.show_years
self.set_selectable_data(self.years_data(smin, smax)) self.set_selectable_data(self.years_data(smin, smax))
self.dropdown.open() self.reopen = True
return return
super().dropdown_select(o,d) super().dropdown_select(o,d)
self.reopen = False
def setValue(self, v): def setValue(self, v):
super().setValue(v) super().setValue(v)
@ -69,17 +79,14 @@ class YearInput(SelectInput):
class DateInput(HBox): class DateInput(HBox):
def __init__(self, allow_copy=True, **kw): def __init__(self, allow_copy=True, **kw):
print('DateInput():kw=', kw) print('DateInput():kw=', kw)
kw['size_hint_y'] = None self.datetype = 'yyyy-mm-dd'
kw['height'] = CSize(3)
kw['size_hint_x'] = None kw['size_hint_x'] = None
kw['width'] = 10 kw['width'] = 10
super(DateInput, self).__init__(**kw) super(DateInput, self).__init__(**kw)
self.register_event_type('on_changed') self.register_event_type('on_changed')
self.old_datestr = None self.old_datestr = None
value = kw.get('value',kw.get('defautvalue',curDateString())) value = kw.get('value',kw.get('defautvalue',curDateString()))
y = int(value[:4]) y, m, d = self.str2ymd(value)
m = int(value[5:7])
d = int(value[9:10])
months_data = [] months_data = []
days_data = [] days_data = []
for i in range(12): for i in range(12):
@ -96,7 +103,7 @@ class DateInput(HBox):
}) })
self.days_data = days_data self.days_data = days_data
self.yw = YearInput(data=[], self.yw = YearInput(data=[],
size_hint_x=None, width=4) size_hint_x=None, width=3.6)
self.mw = SelectInput(size_hint_x=None, width=2, self.mw = SelectInput(size_hint_x=None, width=2,
data=months_data) data=months_data)
self.dw = SelectInput( size_hint_x=None, width=2, self.dw = SelectInput( size_hint_x=None, width=2,
@ -114,6 +121,32 @@ class DateInput(HBox):
self.yw.bind(on_changed=self.data_changed) self.yw.bind(on_changed=self.data_changed)
self.mw.bind(on_changed=self.data_changed) self.mw.bind(on_changed=self.data_changed)
self.dw.bind(on_changed=self.data_changed) self.dw.bind(on_changed=self.data_changed)
self.on_size()
def on_size(self, *args):
if not hasattr(self, 'yw'):
return
self.yw.height = self.height
self.mw.height = self.height
self.dw.height = self.height
def str2ymd(self, datestr):
if len(datestr) == 8:
self.datetype = 'yyyymmdd'
y = int(datestr[:4])
m = int(datestr[4:6])
d = int(datestr[6:8])
return y, m, d
self.datetype = 'yyyy-mm-dd'
y = int(datestr[:4])
m = int(datestr[5:7])
d = int(datestr[9:10])
return y, m, d
def ymd2str(self, y, m, d):
if self.datetype == 'yyyymmdd':
return '%4d%02d%02d' % (y,m,d)
return '%04d-%02d-%02d' % (y, m, d)
def data_changed(self, o, d): def data_changed(self, o, d):
y = self.yw.getValue() y = self.yw.getValue()
@ -124,7 +157,7 @@ class DateInput(HBox):
data = self.days_data[:mdays] data = self.days_data[:mdays]
self.dw.set_selectable_data(data) self.dw.set_selectable_data(data)
if d <= mdays and d>0: if d <= mdays and d>0:
datestr = '%d-%02d-%02d' % (y,m,d) datestr = self.ymd2str(y,m,d)
if self.old_datestr != datestr: if self.old_datestr != datestr:
self.old_datestr = datestr self.old_datestr = datestr
self.dispatch('on_changed', datestr) self.dispatch('on_changed', datestr)
@ -138,14 +171,12 @@ class DateInput(HBox):
d = self.dw.getValue() d = self.dw.getValue()
mdays = monthMaxDay(y,m) mdays = monthMaxDay(y,m)
if d <= mdays and d>0: if d <= mdays and d>0:
return '%d-%02d-%02d' % (y,m,d) return self.ymd2str(y,m,d)
return None return None
def setValue(self, datestr): def setValue(self, datestr):
self.old_value = datestr self.old_value = datestr
y = int(datestr[:4]) y, m, d = self.str2ymd(datestr)
m = int(datestr[5:7])
d = int(datestr[9:10])
self.yw.setValue(y) self.yw.setValue(y)
self.mw.setValue(m) self.mw.setValue(m)
self.dw.setValue(d) self.dw.setValue(d)

View File

@ -1,189 +0,0 @@
import traceback
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.properties import ListProperty, BooleanProperty, \
StringProperty, DictProperty, NumericProperty
from kivy.uix.treeview import TreeView, TreeViewNode, TreeViewLabel
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from .threadcall import HttpClient
from .scrollpanel import ScrollPanel
from .clickable import SingleCheckBox
from .baseWidget import Text
from .utils import CSize
class TreeViewComplexNode(BoxLayout, TreeViewLabel):
otext = StringProperty(None)
checkbox = BooleanProperty(False)
icon = StringProperty(None)
data = DictProperty(None)
def __init__(self, **kw):
super(TreeViewComplexNode, self).__init__(**kw)
self.orientation = 'horizontal'
self.size_hint_x = None
if self.checkbox:
cb = SingleCheckBox(size_hint=(None,None))
cb.bind(on_press=self.set_checked)
self.add_widget(cb)
if self.icon:
img = AsyncImage(source=self.icon, size_hint=(None,None))
img.size = CSize(1,1)
self.add_widget(img)
txt = Text(otext=self.otext, i18n=True)
txt.texture_update()
txt.size_hint = (None, None)
txt.size = txt.texture_size
self.add_widget(txt)
def set_checked(self, o):
if not self.data:
return
if o.state():
self.data['checked'] = True
else:
self.data['checked'] = False
class Hirarchy(ScrollPanel):
url = StringProperty(None)
params = DictProperty(None)
method = StringProperty('get')
idField = StringProperty(None)
textField = StringProperty(None)
data = ListProperty(None)
checkbox = BooleanProperty(False)
icon = StringProperty(None)
single_expand = BooleanProperty(False)
def __init__(self, **kw):
self.register_event_type('on_press')
self.tree = TreeView(hide_root=True)
self.tree.size_hint = (None, None)
self.tree.bind(on_node_expand=self.check_load_subnodes)
self.tree.bind(selected_node=self.node_selected)
super(Hirarchy, self).__init__(inner=self.tree, **kw)
if self.url:
self.data = self.get_remote_data()
def on_press(self, node):
print('selected node=', node)
def node_selected(self, o, v):
if self.tree.selected_node:
self.dispatch('on_press', o.selected_node)
def collapse_others(self, node):
for n in self.tree.iterate_open_nodes(node=node.parent_node):
if n != node and n !=node.parent_node and n.is_open:
self.tree.toggle_node(n)
def check_load_subnodes(self, treeview, node):
if self.single_expand:
self.collapse_others(node)
if node.is_loaded:
return
if not self.url:
node.is_loaded = True
return
data = self.get_remote_data(node)
for d in data:
self.create_new_node(d, node)
node.is_loaded = True
def create_new_node(self, data, node=None):
n = TreeViewComplexNode(otext=data[self.textField],
checkbox=self.checkbox,
icon=data.get('icon') or self.icon
)
n.data = data
n.width = self.tree.indent_start + \
self.tree.indent_level * n.level \
+ sum([i.width for i in n.children])
if node:
self.tree.add_node(n, node)
else:
self.tree.add_node(n)
children = data.get('children')
if not children:
return
for c in children:
self.create_new_node(c, n)
n.is_loaded = True
def get_remote_data(self, node=None):
if not self.url:
return
hc = HttpClient()
params = self.params.copy() if self.params else {}
if node:
params['id'] = node.data[self.idField]
print('params=', params)
d = hc(self.url, method=self.method, params=params)
if isinstance(d, list):
return d
if isinstance(d, dict):
return d['rows']
return None
def on_data(self, o, d=None):
if not self.data:
return
for d in self.data:
self.create_new_node(d)
class Menu(Hirarchy):
target = StringProperty(None)
def __init__(self, **kw):
self.target_w = None
super(Menu, self).__init__(**kw)
def on_press(self, node):
self.tree.deselect_node()
data = {}
dw = node.data.get('datawidget')
if dw:
data_widget = Factory.Blocks.getWidgetById(dw)
if data_widget:
vn = node.data.get('datamethod', 'getValue')
if hasattr(data_widget, vn):
f = getattr(data_widget, vn)
data = f()
if not isinstance(data, dict):
data = {}
url = node.data.get('url')
target = Factory.Blocks.getWidgetById(node.data.get('target',self.target),self)
if url:
params = node.data.get('params',{})
params.update(data)
blocks = Factory.Blocks()
desc = {
"widgettype":"urlwidget",
"options":{
"url":url,
"params":params
}
}
w = blocks.widgetBuild(desc)
if w and target:
target.add_widget(w)
return
rfname = node.data.get('rfname')
if rfname:
f = getRegisterFunctionByName(rfname)
if f:
f(self, **data)
return
script = node.data.get('script')
if script:
target_name = node.data.get('target', self.target)
target = Factory.Blocks.getWidgetById(target_name, self)
data.update({'self':target})
if target:
eval(script,data)
return
Factory.register('Hirarchy', Hirarchy)
Factory.register('Menu', Menu)