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