2020-11-20 19:43:05 +08:00
|
|
|
from kivy.factory import Factory
|
2020-04-02 13:18:10 +08:00
|
|
|
from kivy.logger import Logger
|
2019-12-19 11:13:47 +08:00
|
|
|
from kivy.uix.textinput import TextInput
|
|
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
|
|
from kivy.core.window import Window
|
2020-03-25 16:28:29 +08:00
|
|
|
from kivy.graphics import Color
|
2020-01-08 18:04:39 +08:00
|
|
|
from kivycalendar import DatePicker
|
|
|
|
from .responsivelayout import VResponsiveLayout
|
2019-12-19 11:13:47 +08:00
|
|
|
from .widgetExt.inputext import FloatInput,IntegerInput, \
|
|
|
|
StrInput,SelectInput, BoolInput, AmountInput, Password
|
|
|
|
from .baseWidget import *
|
|
|
|
from .utils import *
|
2020-12-10 23:47:30 +08:00
|
|
|
from .i18n import I18n
|
2020-01-08 18:04:39 +08:00
|
|
|
from .toolbar import Toolbar
|
2020-04-02 13:18:10 +08:00
|
|
|
from .color_definitions import getColors
|
|
|
|
from .bgcolorbehavior import BGColorBehavior
|
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
"""
|
|
|
|
form options
|
|
|
|
{
|
|
|
|
"toolbar":
|
|
|
|
"dataloader":{
|
|
|
|
"dataurl":
|
|
|
|
"params":
|
|
|
|
"method"
|
|
|
|
}
|
|
|
|
"cols":"1"
|
|
|
|
"labelwidth":
|
|
|
|
"textsize":
|
|
|
|
"inputheight":
|
|
|
|
"inline":True,False
|
|
|
|
"fields":[
|
|
|
|
{
|
|
|
|
"name":
|
|
|
|
"label":
|
|
|
|
"datatype",
|
|
|
|
"uitype",
|
|
|
|
"uiparams",
|
|
|
|
"default",
|
2019-12-21 18:28:00 +08:00
|
|
|
"readonly",
|
2019-12-19 11:13:47 +08:00
|
|
|
"required"
|
|
|
|
},
|
|
|
|
]
|
|
|
|
"binds":[
|
|
|
|
]
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
|
|
|
uitypes = {
|
2020-04-24 18:35:30 +08:00
|
|
|
"str":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":StrInput,
|
|
|
|
},
|
2019-12-19 11:13:47 +08:00
|
|
|
"string":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":StrInput,
|
|
|
|
},
|
2020-01-08 18:04:39 +08:00
|
|
|
"password":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":Password,
|
|
|
|
},
|
2020-04-24 18:35:30 +08:00
|
|
|
"int":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":IntegerInput,
|
|
|
|
},
|
2019-12-19 11:13:47 +08:00
|
|
|
"number":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":IntegerInput,
|
|
|
|
},
|
|
|
|
"float":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":FloatInput,
|
|
|
|
},
|
|
|
|
"amount":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":AmountInput,
|
|
|
|
},
|
|
|
|
"date":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":DatePicker,
|
|
|
|
},
|
|
|
|
"time":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":StrInput,
|
|
|
|
},
|
|
|
|
"bool":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":BoolInput,
|
|
|
|
},
|
|
|
|
"code":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":SelectInput,
|
|
|
|
},
|
|
|
|
"text":{
|
|
|
|
"orientation":"vertical",
|
|
|
|
"wclass":StrInput,
|
|
|
|
"options":{
|
|
|
|
"multiline":True,
|
2020-04-24 18:35:30 +08:00
|
|
|
"height":9,
|
2019-12-19 11:13:47 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"teleno":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":StrInput,
|
|
|
|
},
|
|
|
|
"email":{
|
|
|
|
"orientation":"horizontal",
|
|
|
|
"wclass":StrInput,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
class InputBox(BoxLayout):
|
|
|
|
def __init__(self, form, **options):
|
|
|
|
self.form = form
|
|
|
|
self.options = options
|
2020-01-08 18:04:39 +08:00
|
|
|
self.uitype = options.get('uitype','string')
|
2019-12-19 11:13:47 +08:00
|
|
|
self.uidef = uitypes[self.uitype]
|
|
|
|
orientation = self.uidef['orientation']
|
|
|
|
width = self.form.inputwidth
|
|
|
|
height = self.form.inputheight
|
|
|
|
self.labelwidth = self.form.options['labelwidth']
|
|
|
|
kwargs = {
|
|
|
|
"orientation":orientation,
|
|
|
|
}
|
2020-04-24 18:35:30 +08:00
|
|
|
if height<=1:
|
|
|
|
kwargs['size_hint_y'] = height
|
|
|
|
else:
|
|
|
|
kwargs['size_hint_y'] = None
|
|
|
|
kwargs['height'] = CSize(height)
|
2019-12-19 11:13:47 +08:00
|
|
|
if width <= 1:
|
|
|
|
kwargs['size_hint_x'] = width
|
|
|
|
else:
|
|
|
|
kwargs['size_hint_x'] = None
|
|
|
|
kwargs['width'] = CSize(width)
|
|
|
|
super().__init__(**kwargs)
|
|
|
|
self.initflag = False
|
2020-04-24 18:35:30 +08:00
|
|
|
self.bind(size=self.setSize,
|
2019-12-19 11:13:47 +08:00
|
|
|
pos=self.setSize)
|
|
|
|
self.register_event_type("on_datainput")
|
2020-04-02 13:18:10 +08:00
|
|
|
self.register_event_type("on_ready")
|
2019-12-19 11:13:47 +08:00
|
|
|
|
2020-01-08 18:04:39 +08:00
|
|
|
def on_datainput(self,o,v=None):
|
|
|
|
print('on_datainput fired ...',o,v)
|
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
def init(self):
|
|
|
|
if self.initflag:
|
|
|
|
return
|
2020-04-02 13:18:10 +08:00
|
|
|
i18n = I18n()
|
2020-03-25 16:28:29 +08:00
|
|
|
opts = {
|
2020-04-02 13:18:10 +08:00
|
|
|
"orientation":"horizontal",
|
2020-03-25 16:28:29 +08:00
|
|
|
"size_hint_y":None,
|
|
|
|
"height":CSize(3)
|
|
|
|
}
|
|
|
|
if self.labelwidth<=1:
|
|
|
|
opts['size_hint_x'] = self.labelwidth
|
|
|
|
else:
|
|
|
|
opts['size_hint_x'] = None
|
|
|
|
opts['width'] = self.labelwidth
|
|
|
|
bl = BoxLayout(**opts)
|
2020-04-02 13:18:10 +08:00
|
|
|
Logger.info('kivyblock:labelwidth=%f,opts=%s', self.labelwidth,str(opts))
|
|
|
|
Logger.info('kivyblock:bl.widht=%f,bl.height=%f',bl.width,bl.height)
|
2020-03-25 16:28:29 +08:00
|
|
|
self.add_widget(bl)
|
2019-12-19 11:13:47 +08:00
|
|
|
label = self.options.get('label',self.options.get('name'))
|
|
|
|
kwargs = {
|
2020-12-10 23:47:30 +08:00
|
|
|
"i18n":True,
|
|
|
|
"text":label,
|
2020-01-08 18:04:39 +08:00
|
|
|
"font_size":CSize(1),
|
2020-03-25 16:28:29 +08:00
|
|
|
"size_hint_x":None,
|
|
|
|
"width":CSize(len(label)),
|
2020-01-08 18:04:39 +08:00
|
|
|
"size_hint_y":None,
|
2020-03-25 09:51:22 +08:00
|
|
|
"height":CSize(3)
|
2019-12-19 11:13:47 +08:00
|
|
|
}
|
2020-12-10 23:47:30 +08:00
|
|
|
self.labeltext = Text(**kwargs)
|
2020-03-25 16:28:29 +08:00
|
|
|
bl.add_widget(self.labeltext)
|
2020-04-02 13:18:10 +08:00
|
|
|
Logger.info('kivyblock:label.widht=%f,label.height=%f',
|
|
|
|
self.labeltext.width,self.labeltext.height)
|
2020-03-25 16:28:29 +08:00
|
|
|
if self.options.get('required',False):
|
|
|
|
star = Label(text='*',
|
|
|
|
color=(1,0,0,1),
|
|
|
|
size_hint_x=None,
|
|
|
|
width=CSize(1))
|
|
|
|
bl.add_widget(star)
|
2019-12-19 11:13:47 +08:00
|
|
|
options = self.uidef.get('options',{}).copy()
|
|
|
|
options.update(self.options.get('uiparams',{}))
|
|
|
|
options['allow_copy'] = True
|
2020-12-04 15:29:17 +08:00
|
|
|
options['width'] = options.get('width',20)
|
|
|
|
options['height'] = options.get('height',1)
|
2019-12-19 11:13:47 +08:00
|
|
|
if self.options.get('tip'):
|
|
|
|
options['hint_text'] = i18n(self.options.get('tip'))
|
2019-12-21 18:28:00 +08:00
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
self.input_widget = self.uidef['wclass'](**options)
|
2019-12-21 18:28:00 +08:00
|
|
|
if self.options.get('readonly'):
|
|
|
|
self.input_widget.disabled = True
|
2020-11-19 12:22:16 +08:00
|
|
|
self.input_widget.widget_id = self.options['name']
|
2019-12-19 11:13:47 +08:00
|
|
|
self.add_widget(self.input_widget)
|
|
|
|
self.initflag = True
|
|
|
|
self.input_widget.bind(on_focus=self.on_focus)
|
2020-03-25 16:28:29 +08:00
|
|
|
self.input_widget.setValue(self.options.get('default',''))
|
2020-04-02 13:18:10 +08:00
|
|
|
self.dispatch('on_ready', self)
|
2019-12-19 11:13:47 +08:00
|
|
|
|
2020-04-02 13:18:10 +08:00
|
|
|
def check(self):
|
|
|
|
d = self.getValue()
|
|
|
|
v = d.get(self.options.get('name'))
|
|
|
|
Logger.info('InputWidget() getValue=%s, name=%s',
|
|
|
|
v,self.options.get('name'))
|
|
|
|
if self.options.get('required',False) and \
|
|
|
|
(v == '' or v is None):
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
def on_ready(self, obj):
|
|
|
|
Logger.info('kivyblocks: Form input ready')
|
|
|
|
|
2019-12-21 18:28:00 +08:00
|
|
|
def clear(self):
|
|
|
|
self.input_widget.setValue('')
|
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
def on_focus(self,o,v):
|
|
|
|
if v:
|
|
|
|
self.old_value = o.text
|
|
|
|
else:
|
|
|
|
if self.old_value != o.text:
|
|
|
|
self.dispatch('on_datainput',o.text)
|
|
|
|
|
|
|
|
def setSize(self,o,v=None):
|
|
|
|
self.init()
|
|
|
|
|
|
|
|
def setValue(self,v):
|
|
|
|
self.input_widget.setValue(v)
|
|
|
|
|
|
|
|
def getValue(self):
|
2020-01-08 18:04:39 +08:00
|
|
|
return {self.options.get('name'):self.input_widget.getValue()}
|
2019-12-19 11:13:47 +08:00
|
|
|
|
2020-04-24 18:35:30 +08:00
|
|
|
def disable(self,*args,**kwargs):
|
|
|
|
self.input_widget.disabled = True
|
|
|
|
|
|
|
|
def enable(self,*args,**kwargs):
|
|
|
|
self.input_widget.disabled = False
|
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
def defaultToolbar():
|
|
|
|
return {
|
2020-04-02 13:18:10 +08:00
|
|
|
"img_size":2,
|
|
|
|
"text_size":1,
|
2020-01-08 18:04:39 +08:00
|
|
|
"tools":[
|
2019-12-19 11:13:47 +08:00
|
|
|
{
|
|
|
|
"name":"__submit",
|
2020-01-10 12:05:30 +08:00
|
|
|
"img_src":"/imgs/submit.png",
|
2019-12-19 11:13:47 +08:00
|
|
|
"label":"submit"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name":"__clear",
|
2020-01-10 12:05:30 +08:00
|
|
|
"img_src":"/imgs/clear.png",
|
2019-12-19 11:13:47 +08:00
|
|
|
"label":"clear"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-04-02 13:18:10 +08:00
|
|
|
class Form(BGColorBehavior, BoxLayout):
|
2019-12-19 11:13:47 +08:00
|
|
|
def __init__(self, **options):
|
|
|
|
self.options = options
|
|
|
|
BoxLayout.__init__(self, orientation='vertical')
|
2020-04-02 13:18:10 +08:00
|
|
|
self.color_level = self.options.get('color_level', 0)
|
2020-12-02 12:38:53 +08:00
|
|
|
BGColorBehavior.__init__(self,
|
|
|
|
color_level=self.options.get('color_level',-1),
|
|
|
|
radius=self.options.get('radius',[]))
|
2020-04-02 13:18:10 +08:00
|
|
|
self.readiedInput = 0
|
2020-01-09 17:52:02 +08:00
|
|
|
self.cols = self.options_cols = self.options.get('cols',1)
|
2019-12-19 11:13:47 +08:00
|
|
|
if isHandHold() and Window.width < Window.height:
|
|
|
|
self.cols = 1
|
|
|
|
self.inputwidth = Window.width / self.cols
|
2020-04-24 18:35:30 +08:00
|
|
|
self.inputheight = self.options.get('inputheight',3)
|
|
|
|
self.init()
|
2020-02-26 17:24:58 +08:00
|
|
|
self.register_event_type('on_submit')
|
2019-12-19 11:13:47 +08:00
|
|
|
|
|
|
|
def init(self):
|
2021-01-23 03:49:32 +08:00
|
|
|
self.toolbar = Toolbar(**self.options.get('toolbar',defaultToolbar()))
|
2020-01-09 17:52:02 +08:00
|
|
|
self.fsc = VResponsiveLayout(
|
|
|
|
self.inputwidth,
|
|
|
|
self.cols
|
|
|
|
)
|
|
|
|
print('box_width=%d,cols=%d' % (self.inputwidth, self.cols))
|
2020-01-08 18:04:39 +08:00
|
|
|
self.add_widget(self.toolbar)
|
|
|
|
self.add_widget(self.fsc)
|
2019-12-19 11:13:47 +08:00
|
|
|
self.fieldWidgets=[]
|
|
|
|
for f in self.options['fields']:
|
2020-01-08 18:04:39 +08:00
|
|
|
w = InputBox(self, **f)
|
2019-12-19 11:13:47 +08:00
|
|
|
self.fsc.add_widget(w)
|
|
|
|
self.fieldWidgets.append(w)
|
2020-04-02 13:18:10 +08:00
|
|
|
w.bind(on_ready=self.makeInputLink)
|
2020-11-20 19:43:05 +08:00
|
|
|
wid = Factory.Blocks.getWidgetById('__submit',from_widget=self)
|
2019-12-19 11:13:47 +08:00
|
|
|
wid.bind(on_press=self.on_submit_button)
|
2020-11-20 19:43:05 +08:00
|
|
|
wid = Factory.Blocks.getWidgetById('__clear',from_widget=self)
|
2019-12-19 11:13:47 +08:00
|
|
|
wid.bind(on_press=self.on_clear_button)
|
|
|
|
|
2020-04-02 13:18:10 +08:00
|
|
|
def makeInputLink(self,o,v=None):
|
|
|
|
self.readiedInput += 1
|
|
|
|
if self.readiedInput >= len(self.options['fields']):
|
|
|
|
p = self.fieldWidgets[0]
|
|
|
|
for w in self.fieldWidgets[1:]:
|
|
|
|
p.input_widget.focus_next = w.input_widget
|
|
|
|
w.input_widget.focus_previous = p.input_widget
|
|
|
|
p = w
|
|
|
|
|
2020-12-10 23:47:30 +08:00
|
|
|
def getValue(self):
|
2020-01-08 18:04:39 +08:00
|
|
|
d = {}
|
|
|
|
for f in self.fieldWidgets:
|
|
|
|
v = f.getValue()
|
|
|
|
d.update(v)
|
|
|
|
return d
|
|
|
|
|
2020-04-02 13:18:10 +08:00
|
|
|
def checkData(self):
|
|
|
|
for w in self.fieldWidgets:
|
|
|
|
if not w.check():
|
|
|
|
w.input_widget.focus = True
|
|
|
|
Logger.info('kivyblcks: input check false')
|
|
|
|
return False
|
|
|
|
Logger.info('kivyblcks: input check success')
|
|
|
|
return True
|
|
|
|
|
2020-02-26 17:24:58 +08:00
|
|
|
def on_submit(self,v=None):
|
|
|
|
print('Form():on_submit fired ...',v)
|
|
|
|
return False
|
2020-01-08 18:04:39 +08:00
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
def on_submit_button(self,o,v=None):
|
2020-04-02 13:18:10 +08:00
|
|
|
Logger.info('kivyblcks: submit button press')
|
|
|
|
if not self.checkData():
|
|
|
|
Logger.info('kivyblocks: CheckData False')
|
|
|
|
return
|
2020-12-10 23:47:30 +08:00
|
|
|
d = self.getValue()
|
2020-04-02 13:18:10 +08:00
|
|
|
Logger.info('kivyblocks: fire on_submit')
|
2020-02-26 17:24:58 +08:00
|
|
|
self.dispatch('on_submit',d)
|
2019-12-19 11:13:47 +08:00
|
|
|
|
|
|
|
def on_clear_button(self,o,v=None):
|
|
|
|
for fw in self.fieldWidgets:
|
|
|
|
fw.clear()
|
|
|
|
|
|
|
|
class StrSearchForm(BoxLayout):
|
|
|
|
def __init__(self,img_url=None,**options):
|
|
|
|
self.name = options.get('name','search_string')
|
|
|
|
BoxLayout.__init__(self,orientation='horizontal',size_hint_y=None,height=CSize(3))
|
2020-04-02 13:18:10 +08:00
|
|
|
self.input_widget = TextInput(
|
2019-12-22 22:02:37 +08:00
|
|
|
text='',
|
2019-12-19 11:13:47 +08:00
|
|
|
multiline=False,
|
2020-03-25 09:51:22 +08:00
|
|
|
allow_copy=True,
|
2019-12-19 11:13:47 +08:00
|
|
|
font_size=CSize(1),
|
|
|
|
size_hint_y=None,
|
|
|
|
height=CSize(3))
|
2020-04-02 13:18:10 +08:00
|
|
|
self.add_widget(self.input_widget)
|
2019-12-19 11:13:47 +08:00
|
|
|
self.register_event_type('on_submit')
|
2020-04-02 13:18:10 +08:00
|
|
|
self.input_widget.bind(on_text_validate=self.submit_input)
|
2019-12-19 11:13:47 +08:00
|
|
|
|
2020-12-10 23:47:30 +08:00
|
|
|
def getValue(self):
|
2020-03-19 18:00:35 +08:00
|
|
|
d = {
|
2020-04-02 13:18:10 +08:00
|
|
|
self.name:self.input_widget.text
|
2020-03-19 18:00:35 +08:00
|
|
|
}
|
|
|
|
return d
|
|
|
|
|
2019-12-19 11:13:47 +08:00
|
|
|
def submit_input(self,o,v=None):
|
2020-04-02 13:18:10 +08:00
|
|
|
text = self.input_widget.text
|
2019-12-19 11:13:47 +08:00
|
|
|
if text != '':
|
|
|
|
d = {
|
|
|
|
self.name:text
|
|
|
|
}
|
|
|
|
self.dispatch('on_submit',d)
|
|
|
|
|
2020-02-26 17:24:58 +08:00
|
|
|
def on_submit(self,v=None):
|
2019-12-19 11:13:47 +08:00
|
|
|
print('StrSearchForm():on_submit fired ..........')
|
|
|
|
|