bugfix
This commit is contained in:
parent
97372e8ad2
commit
e11a398439
@ -1,4 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
|
from traceback import print_exc
|
||||||
|
from kivy.app import App
|
||||||
from kivy.utils import platform
|
from kivy.utils import platform
|
||||||
from kivy.uix.button import Button, ButtonBehavior
|
from kivy.uix.button import Button, ButtonBehavior
|
||||||
from kivy.uix.accordion import Accordion,AccordionItem
|
from kivy.uix.accordion import Accordion,AccordionItem
|
||||||
@ -46,6 +48,7 @@ from kivy.uix.codeinput import CodeInput
|
|||||||
from kivy.graphics import Color, Rectangle
|
from kivy.graphics import Color, Rectangle
|
||||||
from kivy.properties import ListProperty
|
from kivy.properties import ListProperty
|
||||||
from kivycalendar import DatePicker
|
from kivycalendar import DatePicker
|
||||||
|
from kivy.factory import Factory
|
||||||
|
|
||||||
from appPublic.dictObject import DictObject
|
from appPublic.dictObject import DictObject
|
||||||
|
|
||||||
@ -57,52 +60,66 @@ from .widgetExt.inputext import FloatInput,IntegerInput, \
|
|||||||
from .widgetExt.messager import Messager
|
from .widgetExt.messager import Messager
|
||||||
from .charts.bar import Bar
|
from .charts.bar import Bar
|
||||||
from .bgcolorbehavior import BGColorBehavior
|
from .bgcolorbehavior import BGColorBehavior
|
||||||
|
from .utils import NeedLogin, InsufficientPrivilege, HTTPError
|
||||||
|
from .login import LoginForm
|
||||||
if platform == 'android':
|
if platform == 'android':
|
||||||
from .widgetExt.phonebutton import PhoneButton
|
from .widgetExt.phonebutton import PhoneButton
|
||||||
from .widgetExt.androidwebview import AWebView
|
from .widgetExt.androidwebview import AWebView
|
||||||
|
|
||||||
|
class Text(BGColorBehavior, Label):
|
||||||
|
def __init__(self,bgcolor=[],fgcolor=[],color_level=-1,**kw):
|
||||||
|
self.options = DictObject(**kw)
|
||||||
|
kwargs = kw.copy()
|
||||||
|
Label.__init__(self,**kwargs)
|
||||||
|
BGColorBehavior.__init__(self,bgcolor=bgcolor,
|
||||||
|
fgcolor=fgcolor,
|
||||||
|
color_level=color_level)
|
||||||
|
|
||||||
class PressableImage(ButtonBehavior,AsyncImage):
|
class PressableImage(ButtonBehavior,AsyncImage):
|
||||||
def on_press(self):
|
def on_press(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Text(BGColorBehavior, Label):
|
|
||||||
def __init__(self,bgcolor=[0,0,0,1],**kw):
|
|
||||||
self.options = DictObject(**kw)
|
|
||||||
kwargs = kw.copy()
|
|
||||||
if kwargs.get('bgColor'):
|
|
||||||
self.bgColor = kwargs['bgColor']
|
|
||||||
del kwargs['bgColor']
|
|
||||||
Label.__init__(self,**kwargs)
|
|
||||||
BGColorBehavior.__init__(self,bgcolor=bgcolor)
|
|
||||||
|
|
||||||
class PressableLabel(ButtonBehavior, Text):
|
class PressableLabel(ButtonBehavior, Text):
|
||||||
def on_press(self):
|
def on_press(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class HTTPDataHandler(EventDispatcher):
|
class HTTPDataHandler(EventDispatcher):
|
||||||
def __init__(self, url,method='GET',params={},headers={}):
|
def __init__(self, url,method='GET',params={},
|
||||||
EventDispatcher.__init__()
|
headers={},
|
||||||
self.opts = opts
|
files={}
|
||||||
|
):
|
||||||
|
EventDispatcher.__init__(self)
|
||||||
self.url = url
|
self.url = url
|
||||||
self.method = method
|
self.method = method
|
||||||
self.params = params
|
self.params = params
|
||||||
self.headers = headers
|
self.headers = headers
|
||||||
|
self.files=files
|
||||||
self.hc = App.get_running_app().hc
|
self.hc = App.get_running_app().hc
|
||||||
self.register_event_type('on_sucess')
|
self.register_event_type('on_success')
|
||||||
self.register_event_type('on_error')
|
self.register_event_type('on_error')
|
||||||
|
|
||||||
def on_success(self,o,v):
|
def on_success(self,v):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_error(self,o,e):
|
def on_error(self,e):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def onSuccess(self,o,v):
|
def onSuccess(self,o,v):
|
||||||
self.dispatch('on_sucess',v)
|
print(__file__,'onSuccess():v=',v)
|
||||||
|
self.dispatch('on_success',v)
|
||||||
|
|
||||||
def onError(self,o,e):
|
def onError(self,o,e):
|
||||||
|
if isinstance(e,NeedLogin):
|
||||||
|
lf = LoginForm()
|
||||||
|
lf.bind(on_setupuser=self.redo)
|
||||||
|
lf.open()
|
||||||
|
return
|
||||||
self.dispatch('on_error',e)
|
self.dispatch('on_error',e)
|
||||||
|
print_exc()
|
||||||
|
print('[****][*********] onError Called',e)
|
||||||
|
|
||||||
|
def redo(self,o,v=None):
|
||||||
|
self.handle()
|
||||||
|
|
||||||
def handle(self,params={},headers={}):
|
def handle(self,params={},headers={}):
|
||||||
p = self.params
|
p = self.params
|
||||||
|
@ -1,27 +1,87 @@
|
|||||||
from kivy.logger import Logger
|
from kivy.logger import Logger
|
||||||
from kivy.graphics import Color, Rectangle
|
from kivy.graphics import Color, Rectangle
|
||||||
from kivy.properties import ListProperty
|
from kivy.properties import ListProperty
|
||||||
|
from .color_definitions import getColors
|
||||||
|
|
||||||
_logcnt = 0
|
_logcnt = 0
|
||||||
class BGColorBehavior(object):
|
class BGColorBehavior(object):
|
||||||
bgcolor = ListProperty([])
|
def __init__(self, bgcolor=[],fgcolor=[], color_level=-1,**kwargs):
|
||||||
def __init__(self, bgcolor=[0,0,0,1],**kwargs):
|
self.color_level = color_level
|
||||||
self.bgcolor = bgcolor
|
self.bgcolor = bgcolor
|
||||||
|
self.fgcolor = fgcolor
|
||||||
|
self.normal_bgcolor = bgcolor
|
||||||
|
self.normal_fgcolor = fgcolor
|
||||||
|
self.selected_bgcolor = bgcolor
|
||||||
|
self.selected_fgcolor = fgcolor
|
||||||
|
self.useOwnColor = False
|
||||||
|
self.useOwnBG = False
|
||||||
|
self.useOwnFG = False
|
||||||
|
if color_level != -1:
|
||||||
|
fg,bg= getColors(color_level)
|
||||||
|
self.fgcolor = fg
|
||||||
|
self.bgcolor = bg
|
||||||
|
self.normal_bgcolor = bg
|
||||||
|
self.normal_fgcolor = fg
|
||||||
|
fg,bg= getColors(color_level,selected=True)
|
||||||
|
self.selected_bgcolor = bg
|
||||||
|
self.selected_fgcolor = fg
|
||||||
|
self.useOwnColor = True
|
||||||
|
else:
|
||||||
|
if bgcolor != [] and fgcolor != []:
|
||||||
|
self.useOwnColor = True
|
||||||
|
elif bgcolor != []:
|
||||||
|
self.useOwnBG = True
|
||||||
|
elif fgcolor != []:
|
||||||
|
self.useOwnFG = True
|
||||||
|
if self.fgcolor!=[]:
|
||||||
|
self.color = self.fgcolor
|
||||||
self.bind(size=self.onSize_bgcolor_behavior,
|
self.bind(size=self.onSize_bgcolor_behavior,
|
||||||
pos=self.onSize_bgcolor_behavior)
|
pos=self.onSize_bgcolor_behavior)
|
||||||
|
self.bind(parent=self.useAcestorColor)
|
||||||
self.on_bgcolor()
|
self.on_bgcolor()
|
||||||
|
|
||||||
|
def useAcestorColor(self,o,v=None):
|
||||||
|
if self.useOwnColor:
|
||||||
|
return
|
||||||
|
|
||||||
|
p = self.parent
|
||||||
|
cnt = 0
|
||||||
|
while p:
|
||||||
|
if isinstance(p,BGColorBehavior):
|
||||||
|
break
|
||||||
|
p = p.parent
|
||||||
|
cnt += 1
|
||||||
|
if cnt > 100:
|
||||||
|
return
|
||||||
|
if not self.useOwnBG and p:
|
||||||
|
self.bgcolor = p.bgcolor
|
||||||
|
self.on_bgcolor()
|
||||||
|
if not self.useOwnFG and p:
|
||||||
|
self.fgcolor = p.bgcolor
|
||||||
|
self.color = self.fgcolor
|
||||||
|
|
||||||
def onSize_bgcolor_behavior(self,o,v=None):
|
def onSize_bgcolor_behavior(self,o,v=None):
|
||||||
if not hasattr(self,'rect'):
|
if not hasattr(self,'rect'):
|
||||||
self.on_bgcolor()
|
self.on_bgcolor()
|
||||||
else:
|
else:
|
||||||
self.rect.pos = o.pos
|
self.rect.pos = self.pos
|
||||||
self.rect.size = o.size
|
self.rect.size = self.size
|
||||||
|
|
||||||
def on_bgcolor(self,o=None,v=None):
|
def on_bgcolor(self,o=None,v=None):
|
||||||
|
if self.bgcolor == []:
|
||||||
|
return
|
||||||
if self.canvas:
|
if self.canvas:
|
||||||
with self.canvas.before:
|
with self.canvas.before:
|
||||||
Color(*self.bgcolor)
|
Color(*self.bgcolor)
|
||||||
self.rect = Rectangle(pos=self.pos,
|
self.rect = Rectangle(pos=self.pos,
|
||||||
size=self.size)
|
size=self.size)
|
||||||
|
|
||||||
|
def selected(self):
|
||||||
|
self.bgcolor = self.selected_bgcolor
|
||||||
|
Logger.info('selected:color=%s',self.bgcolor)
|
||||||
|
self.on_bgcolor()
|
||||||
|
|
||||||
|
def unselected(self):
|
||||||
|
self.bgcolor = self.normal_bgcolor
|
||||||
|
Logger.info('unselected:color=%s',self.bgcolor)
|
||||||
|
self.on_bgcolor()
|
||||||
|
@ -10,6 +10,7 @@ from appPublic.dictExt import dictExtend
|
|||||||
from appPublic.folderUtils import ProgramPath
|
from appPublic.folderUtils import ProgramPath
|
||||||
from appPublic.dictObject import DictObject
|
from appPublic.dictObject import DictObject
|
||||||
from appPublic.Singleton import SingletonDecorator
|
from appPublic.Singleton import SingletonDecorator
|
||||||
|
from appPublic.datamapping import keyMapping
|
||||||
|
|
||||||
from kivy.config import Config
|
from kivy.config import Config
|
||||||
from kivy.metrics import sp,dp,mm
|
from kivy.metrics import sp,dp,mm
|
||||||
@ -17,14 +18,11 @@ from kivy.core.window import WindowBase
|
|||||||
from kivy.properties import BooleanProperty
|
from kivy.properties import BooleanProperty
|
||||||
from kivy.uix.widget import Widget
|
from kivy.uix.widget import Widget
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
|
from kivy.factory import Factory
|
||||||
from .baseWidget import *
|
from .baseWidget import *
|
||||||
from .widgetExt import Messager
|
|
||||||
from .externalwidgetmanager import ExternalWidgetManager
|
|
||||||
from .threadcall import HttpClient
|
|
||||||
from .toolbar import *
|
from .toolbar import *
|
||||||
from .dg import DataGrid
|
from .dg import DataGrid
|
||||||
from .utils import *
|
from .utils import *
|
||||||
from .ready import WidgetReady
|
|
||||||
from .serverImageViewer import ServerImageViewer
|
from .serverImageViewer import ServerImageViewer
|
||||||
from .vplayer import VPlayer
|
from .vplayer import VPlayer
|
||||||
from .form import InputBox, Form, StrSearchForm
|
from .form import InputBox, Form, StrSearchForm
|
||||||
@ -113,10 +111,12 @@ def registerWidget(name,widget):
|
|||||||
globals()[name] = widget
|
globals()[name] = widget
|
||||||
|
|
||||||
|
|
||||||
class Blocks:
|
class Blocks(EventDispatcher):
|
||||||
registedWidgets = {}
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
EventDispatcher.__init__(self)
|
||||||
self.action_id = 0
|
self.action_id = 0
|
||||||
|
self.register_event_type('on_built')
|
||||||
|
self.register_event_type('on_failed')
|
||||||
|
|
||||||
def register_widget(self,name,widget):
|
def register_widget(self,name,widget):
|
||||||
globals()[name] = widget
|
globals()[name] = widget
|
||||||
@ -140,8 +140,6 @@ class Blocks:
|
|||||||
raise Exception('None Function')
|
raise Exception('None Function')
|
||||||
func =partial(f,widget)
|
func =partial(f,widget)
|
||||||
return func
|
return func
|
||||||
setattr(widget,fname,f)
|
|
||||||
return getattr(widget,fname)
|
|
||||||
|
|
||||||
def eval(self,s,l):
|
def eval(self,s,l):
|
||||||
g = {}
|
g = {}
|
||||||
@ -163,23 +161,22 @@ class Blocks:
|
|||||||
|
|
||||||
return eval(s,g,l)
|
return eval(s,g,l)
|
||||||
|
|
||||||
def getUrlData(self,kw,parenturl=None):
|
def getUrlData(self,url,method='GET',params={}, files={},
|
||||||
url = kw.get('url')
|
callback=None,
|
||||||
method = kw.get('method','GET')
|
errback=None,**kw):
|
||||||
params = kw.get('params',{})
|
|
||||||
if url is None:
|
|
||||||
print('kw=',kw)
|
|
||||||
raise ArgumentError('url','getUrlData() miss a url argument')
|
|
||||||
url = absurl(url,parenturl)
|
|
||||||
if url.startswith('file://'):
|
if url.startswith('file://'):
|
||||||
filename = url[7:]
|
filename = url[7:]
|
||||||
print(filename)
|
print(filename)
|
||||||
with codecs.open(filename,'r','utf-8') as f:
|
with codecs.open(filename,'r','utf-8') as f:
|
||||||
b = f.read()
|
b = f.read()
|
||||||
dic = json.loads(b)
|
dic = json.loads(b)
|
||||||
|
callback(None,dic)
|
||||||
else:
|
else:
|
||||||
dic = App.get_running_app().hc(url,method=method,params=params)
|
h = HTTPDataHandler(url,method=method,params=params,
|
||||||
return dic, url
|
files=files)
|
||||||
|
h.bind(on_success=callback)
|
||||||
|
h.bind(on_error=errback)
|
||||||
|
h.handle()
|
||||||
|
|
||||||
def strValueExpr(self,s:str,localnamespace:dict={}):
|
def strValueExpr(self,s:str,localnamespace:dict={}):
|
||||||
if not s.startswith('py::'):
|
if not s.startswith('py::'):
|
||||||
@ -239,7 +236,6 @@ class Blocks:
|
|||||||
|
|
||||||
def __build(self,desc:dict,ancestor=None):
|
def __build(self,desc:dict,ancestor=None):
|
||||||
def checkReady(w,o):
|
def checkReady(w,o):
|
||||||
print('checkReady():w=',w,'o=',o)
|
|
||||||
w.children_ready[o] = True
|
w.children_ready[o] = True
|
||||||
if all(w.children_ready.values()):
|
if all(w.children_ready.values()):
|
||||||
w.ready = True
|
w.ready = True
|
||||||
@ -250,8 +246,10 @@ class Blocks:
|
|||||||
|
|
||||||
widgetClass = desc['widgettype']
|
widgetClass = desc['widgettype']
|
||||||
opts = desc.get('options',{})
|
opts = desc.get('options',{})
|
||||||
klass = globals().get(widgetClass)
|
try:
|
||||||
if not klass:
|
klass = Factory.get(widgetClass)
|
||||||
|
except Exception as e:
|
||||||
|
print('Error:',widgetClass,'not registered')
|
||||||
raise NotExistsObject(widgetClass)
|
raise NotExistsObject(widgetClass)
|
||||||
widget = klass(**opts)
|
widget = klass(**opts)
|
||||||
if desc.get('parenturl'):
|
if desc.get('parenturl'):
|
||||||
@ -270,23 +268,34 @@ class Blocks:
|
|||||||
|
|
||||||
widget.build_desc = desc
|
widget.build_desc = desc
|
||||||
self.build_rest(widget,desc,ancestor)
|
self.build_rest(widget,desc,ancestor)
|
||||||
# f = partial(self.build_rest,widget,desc,ancestor)
|
|
||||||
# event = Clock.schedule_once(f,0)
|
|
||||||
return widget
|
return widget
|
||||||
|
|
||||||
def build_rest(self, widget,desc,ancestor,t=None):
|
def build_rest(self, widget,desc,ancestor,t=None):
|
||||||
for sw in desc.get('subwidgets',[]):
|
bcnt = 0
|
||||||
w = self.widgetBuild(sw, ancestor=ancestor)
|
btotal = len(desc.get('subwidgets',[]))
|
||||||
if w is None:
|
def doit(self,widget,bcnt,btotal,desc,o,w):
|
||||||
continue
|
bcnt += 1
|
||||||
w.parenturl = widget.parenturl
|
w.parenturl = widget.parenturl
|
||||||
widget.add_widget(w)
|
widget.add_widget(w)
|
||||||
if hasattr(widget,'addChild'):
|
if hasattr(widget,'addChild'):
|
||||||
widget.addChild(w)
|
widget.addChild(w)
|
||||||
for b in desc.get('binds',[]):
|
if bcnt >= btotal:
|
||||||
self.buildBind(widget,b)
|
for b in desc.get('binds',[]):
|
||||||
if hasattr(widget, 'built'):
|
self.buildBind(widget,b)
|
||||||
widget.built()
|
|
||||||
|
def doerr(o,e):
|
||||||
|
raise e
|
||||||
|
|
||||||
|
f = partial(doit,self,widget,bcnt,btotal,desc)
|
||||||
|
for sw in desc.get('subwidgets',[]):
|
||||||
|
b = Blocks()
|
||||||
|
b.bind(on_built=f)
|
||||||
|
b.bind(on_failed=doerr)
|
||||||
|
w = b.widgetBuild(sw, ancestor=ancestor)
|
||||||
|
|
||||||
|
if btotal == 0:
|
||||||
|
for b in desc.get('binds',[]):
|
||||||
|
self.buildBind(widget,b)
|
||||||
|
|
||||||
def buildBind(self,widget,desc):
|
def buildBind(self,widget,desc):
|
||||||
wid = desc.get('wid','self')
|
wid = desc.get('wid','self')
|
||||||
@ -309,7 +318,7 @@ class Blocks:
|
|||||||
return self.scriptAction(widget, desc)
|
return self.scriptAction(widget, desc)
|
||||||
if acttype == 'method':
|
if acttype == 'method':
|
||||||
return self.methodAction(widget, desc)
|
return self.methodAction(widget, desc)
|
||||||
alert(msg="actiontype invalid",title=acttype)
|
alert("actiontype(%s) invalid" % acttype,title='error')
|
||||||
|
|
||||||
def blocksAction(widget,desc):
|
def blocksAction(widget,desc):
|
||||||
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
|
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
|
||||||
@ -319,13 +328,18 @@ class Blocks:
|
|||||||
p = opts.get('options',{})
|
p = opts.get('options',{})
|
||||||
p.update(d)
|
p.update(d)
|
||||||
opts['options'] = p
|
opts['options'] = p
|
||||||
x = self.widgetBuild(opts,ancestor=widget)
|
def doit(target,add_mode,o,w):
|
||||||
if x is None:
|
if add_mode == 'replace':
|
||||||
alert(str(opts), title='widugetBuild error')
|
target.clear_widgets()
|
||||||
return
|
target.add_widget(w)
|
||||||
if add_mode == 'replace':
|
|
||||||
target.clear_widgets()
|
def doerr(o,e):
|
||||||
target.add_widget(x)
|
raise e
|
||||||
|
|
||||||
|
b = Blocks()
|
||||||
|
b.bind(on_built=partial(doit,target,add_mode))
|
||||||
|
b.bind(on_failed=doerr)
|
||||||
|
b.widgetBuild(opts,ancestor=widget)
|
||||||
|
|
||||||
def urlwidgetAction(self,widget,desc):
|
def urlwidgetAction(self,widget,desc):
|
||||||
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
|
target = self.getWidgetByIdPath(widget, desc.get('target','self'))
|
||||||
@ -339,12 +353,19 @@ class Blocks:
|
|||||||
'widgettype' : 'urlwidget'
|
'widgettype' : 'urlwidget'
|
||||||
}
|
}
|
||||||
d['options'] = opts
|
d['options'] = opts
|
||||||
x = self.widgetBuild(d,ancestor=widget)
|
|
||||||
if x is None:
|
def doit(target,add_mode,o,w):
|
||||||
return
|
if add_mode == 'replace':
|
||||||
if add_mode == 'replace':
|
target.clear_widgets()
|
||||||
target.clear_widgets()
|
target.add_widget(w)
|
||||||
target.add_widget(x)
|
|
||||||
|
def doerr(o,e):
|
||||||
|
raise e
|
||||||
|
|
||||||
|
b = Blocks()
|
||||||
|
b.bind(on_built=partial(doit,target,add_mode))
|
||||||
|
b.bind(on_failed=doerr)
|
||||||
|
b.widgetBuild(d,ancestor=widget)
|
||||||
|
|
||||||
def getActionData(self,widget,desc):
|
def getActionData(self,widget,desc):
|
||||||
data = {}
|
data = {}
|
||||||
@ -352,6 +373,8 @@ class Blocks:
|
|||||||
dwidget = self.getWidgetByIdPath(widget,
|
dwidget = self.getWidgetByIdPath(widget,
|
||||||
desc.get('datawidget'))
|
desc.get('datawidget'))
|
||||||
data = dwidget.getData()
|
data = dwidget.getData()
|
||||||
|
if desc.get('keymapping'):
|
||||||
|
data = keyMapping(data, desc.get('keymapping'))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def registedfunctionAction(self, widget, desc):
|
def registedfunctionAction(self, widget, desc):
|
||||||
@ -361,7 +384,7 @@ class Blocks:
|
|||||||
params = desc.get(params,{})
|
params = desc.get(params,{})
|
||||||
d = self.getActionData(widget,desc)
|
d = self.getActionData(widget,desc)
|
||||||
params.update(d)
|
params.update(d)
|
||||||
func(params)
|
func(**params)
|
||||||
|
|
||||||
def scriptAction(self, widget, desc):
|
def scriptAction(self, widget, desc):
|
||||||
script = desc.get('script')
|
script = desc.get('script')
|
||||||
@ -400,28 +423,44 @@ class Blocks:
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
def doit(desc):
|
||||||
|
desc = self.valueExpr(desc)
|
||||||
|
try:
|
||||||
|
widget = self.__build(desc,ancestor=ancestor)
|
||||||
|
self.dispatch('on_built',widget)
|
||||||
|
print('widgetBuild():&&&&&&&&&&&&&&&&&',widget)
|
||||||
|
except Exception as e:
|
||||||
|
print('&&&&&&&&&&&&&&&&&',e)
|
||||||
|
doerr(None,e)
|
||||||
|
print('&&&&&&&&&&&&&&&&&',e)
|
||||||
|
return
|
||||||
|
|
||||||
|
def doerr(o,e):
|
||||||
|
self.dispatch('on_failed',e)
|
||||||
|
|
||||||
name = desc['widgettype']
|
name = desc['widgettype']
|
||||||
if name == 'urlwidget':
|
if name == 'urlwidget':
|
||||||
opts = desc.get('options')
|
opts = desc.get('options')
|
||||||
parenturl = None
|
parenturl = None
|
||||||
|
url=''
|
||||||
if ancestor:
|
if ancestor:
|
||||||
parenturl = ancestor.parenturl
|
parenturl = ancestor.parenturl
|
||||||
desc, parenturl = self.getUrlData(opts,parenturl)
|
try:
|
||||||
if not isinstance(desc,dict):
|
url = absurl(opts.get('url'),parenturl)
|
||||||
print("getUrlData() return error data",opts,parenturl)
|
except Exception as e:
|
||||||
# alert(str(desc) + 'format error',title='widgetBuild()')
|
self.dispatch('on_failed',e)
|
||||||
return None
|
|
||||||
desc = self.valueExpr(desc)
|
|
||||||
desc['parenturl'] = parenturl
|
|
||||||
|
|
||||||
try:
|
def cb(o,d):
|
||||||
widget = self.__build(desc,ancestor=ancestor)
|
try:
|
||||||
return widget
|
d['parenturl'] = url
|
||||||
except:
|
doit(d)
|
||||||
print('widgetBuild() Error',desc)
|
except Exception as e:
|
||||||
print_exc()
|
doerr(None,e)
|
||||||
alert(str(desc))
|
|
||||||
return None
|
del opts['url']
|
||||||
|
self.getUrlData(url,callback=cb,errback=doerr,**opts)
|
||||||
|
return
|
||||||
|
doit(desc)
|
||||||
|
|
||||||
def getWidgetByIdPath(self,widget,path):
|
def getWidgetByIdPath(self,widget,path):
|
||||||
ids = path.split('/')
|
ids = path.split('/')
|
||||||
@ -438,3 +477,10 @@ class Blocks:
|
|||||||
raise WidgetNotFoundById(id)
|
raise WidgetNotFoundById(id)
|
||||||
return widget
|
return widget
|
||||||
|
|
||||||
|
def on_built(self,v=None):
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_failed(self,e=None):
|
||||||
|
return
|
||||||
|
|
||||||
|
Factory.register('Blocks',Blocks)
|
||||||
|
@ -15,7 +15,10 @@ BoxViewer options:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
from traceback import print_exc
|
||||||
|
from functools import partial
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
|
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
|
||||||
@ -38,16 +41,11 @@ class BoxViewer(BoxLayout):
|
|||||||
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()
|
||||||
lopts['options']['adder'] = self.showObject
|
self.dataloader = RelatedLoader(target=self,**lopts['options'])
|
||||||
lopts['options']['remover'] = self.viewContainer.remove_widget
|
self.dataloader.bind(on_deletepage=self.deleteWidgets)
|
||||||
lopts['options']['clearer'] = self.viewContainer.clear_widgets
|
self.dataloader.bind(on_pageloaded=self.addPageWidgets)
|
||||||
lopts['options']['target'] = self
|
self.dataloader.bind(on_newbegin=self.deleteAllWidgets)
|
||||||
lopts['options']['locater'] = self.locater
|
|
||||||
LClass = RelatedLoader
|
|
||||||
if lopts['widgettype'] == 'paging':
|
|
||||||
LClass = Paging
|
|
||||||
|
|
||||||
self.dataloader = LClass(**lopts['options'])
|
|
||||||
if self.toolbar:
|
if self.toolbar:
|
||||||
self.add_widget(self.toolbar)
|
self.add_widget(self.toolbar)
|
||||||
if self.dataloader.widget:
|
if self.dataloader.widget:
|
||||||
@ -58,6 +56,30 @@ class BoxViewer(BoxLayout):
|
|||||||
pos=self.resetCols)
|
pos=self.resetCols)
|
||||||
self.viewContainer.bind(on_scroll_stop=self.on_scroll_stop)
|
self.viewContainer.bind(on_scroll_stop=self.on_scroll_stop)
|
||||||
|
|
||||||
|
def deleteAllWidgets(self,o):
|
||||||
|
self.viewContainer.clear_widgets()
|
||||||
|
|
||||||
|
def addPageWidgets(self,o,data):
|
||||||
|
widgets = []
|
||||||
|
recs = data['data']
|
||||||
|
dir = data['dir']
|
||||||
|
idx = 0
|
||||||
|
if dir == 'up':
|
||||||
|
recs.reverse()
|
||||||
|
idx = -1
|
||||||
|
print('addPageWidgets(),begin')
|
||||||
|
for r in recs:
|
||||||
|
self.showObject(widgets, r, index=idx)
|
||||||
|
|
||||||
|
print('addPageWidgets(),widgets=',len(widgets))
|
||||||
|
self.dataloader.bufferObjects(widgets)
|
||||||
|
x = self.dataloader.getLocater()
|
||||||
|
self.locater(x)
|
||||||
|
|
||||||
|
def deleteWidgets(self,o,data):
|
||||||
|
for w in data:
|
||||||
|
self.viewContainer.remove_widget(w)
|
||||||
|
|
||||||
def on_selected(self, o, v=None):
|
def on_selected(self, o, v=None):
|
||||||
print('BoxViewer(): on_selected fired....')
|
print('BoxViewer(): on_selected fired....')
|
||||||
|
|
||||||
@ -77,20 +99,29 @@ class BoxViewer(BoxLayout):
|
|||||||
self.dataloader.loadPage(1)
|
self.dataloader.loadPage(1)
|
||||||
self.initflag = True
|
self.initflag = True
|
||||||
|
|
||||||
def showObject(self, rec,**kw):
|
def showObject(self, holders, rec,index=0):
|
||||||
blocks = App.get_running_app().blocks
|
def doit(self,holders,idx,o,w):
|
||||||
|
print('showObject()...doit(),w=',w,o)
|
||||||
|
w.bind(on_press=self.select_record)
|
||||||
|
self.viewContainer.add_widget(w,index=idx)
|
||||||
|
holders.append(w)
|
||||||
|
|
||||||
|
def doerr(o,e):
|
||||||
|
print_exc()
|
||||||
|
print('showObject(),error=',e)
|
||||||
|
raise e
|
||||||
options = self.options['viewer'].copy()
|
options = self.options['viewer'].copy()
|
||||||
options['options']['record'] = rec
|
options['options']['record'] = rec
|
||||||
options['options']['ancestor'] = self
|
options['options']['ancestor'] = self
|
||||||
options['options']['size_hint'] = None,None
|
options['options']['size_hint'] = None,None
|
||||||
options['options']['width'] = self.box_width
|
options['options']['width'] = self.box_width
|
||||||
options['options']['height'] = self.box_height
|
options['options']['height'] = self.box_height
|
||||||
w = blocks.widgetBuild(options, ancestor=self)
|
blocks = Factory.Blocks()
|
||||||
if w is None:
|
blocks.bind(on_built=partial(doit,self,holders,index))
|
||||||
return None
|
blocks.bind(on_failed=doerr)
|
||||||
w.bind(on_press=self.select_record)
|
print('showObject():********here***********')
|
||||||
self.viewContainer.add_widget(w,**kw)
|
blocks.widgetBuild(options, ancestor=self)
|
||||||
return w
|
print('showObject():********end ***********')
|
||||||
|
|
||||||
def on_scroll_stop(self,o,v=None):
|
def on_scroll_stop(self,o,v=None):
|
||||||
if o.scroll_y <= 0.001:
|
if o.scroll_y <= 0.001:
|
||||||
|
@ -46,6 +46,10 @@ form options
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
uitypes = {
|
uitypes = {
|
||||||
|
"str":{
|
||||||
|
"orientation":"horizontal",
|
||||||
|
"wclass":StrInput,
|
||||||
|
},
|
||||||
"string":{
|
"string":{
|
||||||
"orientation":"horizontal",
|
"orientation":"horizontal",
|
||||||
"wclass":StrInput,
|
"wclass":StrInput,
|
||||||
@ -54,6 +58,10 @@ uitypes = {
|
|||||||
"orientation":"horizontal",
|
"orientation":"horizontal",
|
||||||
"wclass":Password,
|
"wclass":Password,
|
||||||
},
|
},
|
||||||
|
"int":{
|
||||||
|
"orientation":"horizontal",
|
||||||
|
"wclass":IntegerInput,
|
||||||
|
},
|
||||||
"number":{
|
"number":{
|
||||||
"orientation":"horizontal",
|
"orientation":"horizontal",
|
||||||
"wclass":IntegerInput,
|
"wclass":IntegerInput,
|
||||||
@ -87,7 +95,7 @@ uitypes = {
|
|||||||
"wclass":StrInput,
|
"wclass":StrInput,
|
||||||
"options":{
|
"options":{
|
||||||
"multiline":True,
|
"multiline":True,
|
||||||
"height":CSize(9),
|
"height":9,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"teleno":{
|
"teleno":{
|
||||||
@ -111,9 +119,12 @@ class InputBox(BoxLayout):
|
|||||||
self.labelwidth = self.form.options['labelwidth']
|
self.labelwidth = self.form.options['labelwidth']
|
||||||
kwargs = {
|
kwargs = {
|
||||||
"orientation":orientation,
|
"orientation":orientation,
|
||||||
"size_hint_y":None,
|
|
||||||
"height":height
|
|
||||||
}
|
}
|
||||||
|
if height<=1:
|
||||||
|
kwargs['size_hint_y'] = height
|
||||||
|
else:
|
||||||
|
kwargs['size_hint_y'] = None
|
||||||
|
kwargs['height'] = CSize(height)
|
||||||
if width <= 1:
|
if width <= 1:
|
||||||
kwargs['size_hint_x'] = width
|
kwargs['size_hint_x'] = width
|
||||||
else:
|
else:
|
||||||
@ -121,7 +132,7 @@ class InputBox(BoxLayout):
|
|||||||
kwargs['width'] = CSize(width)
|
kwargs['width'] = CSize(width)
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.initflag = False
|
self.initflag = False
|
||||||
self.bind(on_size=self.setSize,
|
self.bind(size=self.setSize,
|
||||||
pos=self.setSize)
|
pos=self.setSize)
|
||||||
self.register_event_type("on_datainput")
|
self.register_event_type("on_datainput")
|
||||||
self.register_event_type("on_ready")
|
self.register_event_type("on_ready")
|
||||||
@ -169,8 +180,8 @@ class InputBox(BoxLayout):
|
|||||||
options = self.uidef.get('options',{}).copy()
|
options = self.uidef.get('options',{}).copy()
|
||||||
options.update(self.options.get('uiparams',{}))
|
options.update(self.options.get('uiparams',{}))
|
||||||
options['allow_copy'] = True
|
options['allow_copy'] = True
|
||||||
options['size_hint_y'] = None
|
options['width'] = 1
|
||||||
options['height'] = CSize(3)
|
options['height'] = 2.5
|
||||||
if self.options.get('tip'):
|
if self.options.get('tip'):
|
||||||
options['hint_text'] = i18n(self.options.get('tip'))
|
options['hint_text'] = i18n(self.options.get('tip'))
|
||||||
|
|
||||||
@ -217,6 +228,12 @@ class InputBox(BoxLayout):
|
|||||||
def getValue(self):
|
def getValue(self):
|
||||||
return {self.options.get('name'):self.input_widget.getValue()}
|
return {self.options.get('name'):self.input_widget.getValue()}
|
||||||
|
|
||||||
|
def disable(self,*args,**kwargs):
|
||||||
|
self.input_widget.disabled = True
|
||||||
|
|
||||||
|
def enable(self,*args,**kwargs):
|
||||||
|
self.input_widget.disabled = False
|
||||||
|
|
||||||
def defaultToolbar():
|
def defaultToolbar():
|
||||||
return {
|
return {
|
||||||
"img_size":2,
|
"img_size":2,
|
||||||
@ -241,23 +258,18 @@ class Form(BGColorBehavior, BoxLayout):
|
|||||||
self.options = options
|
self.options = options
|
||||||
BoxLayout.__init__(self, orientation='vertical')
|
BoxLayout.__init__(self, orientation='vertical')
|
||||||
self.color_level = self.options.get('color_level', 0)
|
self.color_level = self.options.get('color_level', 0)
|
||||||
textcolor, bgcolor = getColors(self.color_level)
|
BGColorBehavior.__init__(self,color_level=self.color_level)
|
||||||
BGColorBehavior.__init__(self,bgcolor=bgcolor)
|
|
||||||
self.widget_ids = {}
|
self.widget_ids = {}
|
||||||
self.readiedInput = 0
|
self.readiedInput = 0
|
||||||
self.cols = self.options_cols = self.options.get('cols',1)
|
self.cols = self.options_cols = self.options.get('cols',1)
|
||||||
if isHandHold() and Window.width < Window.height:
|
if isHandHold() and Window.width < Window.height:
|
||||||
self.cols = 1
|
self.cols = 1
|
||||||
self.inputwidth = Window.width / self.cols
|
self.inputwidth = Window.width / self.cols
|
||||||
self.inputheight = CSize(self.options.get('inputheight',3))
|
self.inputheight = self.options.get('inputheight',3)
|
||||||
self.initflag = False
|
self.init()
|
||||||
self.register_event_type('on_submit')
|
self.register_event_type('on_submit')
|
||||||
self.bind(size=self.on_size,
|
|
||||||
pos=self.on_size)
|
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
if self.initflag:
|
|
||||||
return
|
|
||||||
self.toolbar = Toolbar(ancestor=self,**self.options.get('toolbar',defaultToolbar()))
|
self.toolbar = Toolbar(ancestor=self,**self.options.get('toolbar',defaultToolbar()))
|
||||||
self.fsc = VResponsiveLayout(
|
self.fsc = VResponsiveLayout(
|
||||||
self.inputwidth,
|
self.inputwidth,
|
||||||
@ -279,7 +291,6 @@ class Form(BGColorBehavior, BoxLayout):
|
|||||||
wid = blocks.getWidgetByIdPath(self,'__clear')
|
wid = blocks.getWidgetByIdPath(self,'__clear')
|
||||||
# wid = self.widget_ids['__clear']
|
# wid = self.widget_ids['__clear']
|
||||||
wid.bind(on_press=self.on_clear_button)
|
wid.bind(on_press=self.on_clear_button)
|
||||||
self.initflag = True
|
|
||||||
|
|
||||||
def makeInputLink(self,o,v=None):
|
def makeInputLink(self,o,v=None):
|
||||||
self.readiedInput += 1
|
self.readiedInput += 1
|
||||||
@ -323,10 +334,6 @@ class Form(BGColorBehavior, BoxLayout):
|
|||||||
for fw in self.fieldWidgets:
|
for fw in self.fieldWidgets:
|
||||||
fw.clear()
|
fw.clear()
|
||||||
|
|
||||||
def on_size(self,o, v=None):
|
|
||||||
self.init()
|
|
||||||
textcolor, self.bgcolor = getColors(self.color_level)
|
|
||||||
|
|
||||||
class StrSearchForm(BoxLayout):
|
class StrSearchForm(BoxLayout):
|
||||||
def __init__(self,img_url=None,**options):
|
def __init__(self,img_url=None,**options):
|
||||||
self.name = options.get('name','search_string')
|
self.name = options.get('name','search_string')
|
||||||
|
@ -28,6 +28,8 @@ class I18n:
|
|||||||
if lang is None:
|
if lang is None:
|
||||||
lang = self.lang
|
lang = self.lang
|
||||||
d = self.kvlang.get(lang,{})
|
d = self.kvlang.get(lang,{})
|
||||||
|
if d is None:
|
||||||
|
return msg
|
||||||
return d.get(msg,msg)
|
return d.get(msg,msg)
|
||||||
|
|
||||||
def changeLang(self,lang):
|
def changeLang(self,lang):
|
||||||
|
@ -41,18 +41,15 @@ class KivySizes:
|
|||||||
return self.unitedSize(x,y=y,name=name)
|
return self.unitedSize(x,y=y,name=name)
|
||||||
|
|
||||||
def getScreenSize(self):
|
def getScreenSize(self):
|
||||||
#root = App.get_running_app().root
|
|
||||||
#return root.width, root.height
|
|
||||||
return Window.width, Window.height
|
return Window.width, Window.height
|
||||||
|
|
||||||
def getWindowPhysicalSize(self,w):
|
def getWindowPhysicalSize(self):
|
||||||
h_phy = float(w.height) / mm(1)
|
h_phy = float(Window.height) / mm(1)
|
||||||
w_phy = float(w.width) / mm(1)
|
w_phy = float(Window.width) / mm(1)
|
||||||
return w_phy, h_phy
|
return w_phy, h_phy
|
||||||
|
|
||||||
def getScreenPhysicalSize(self):
|
def getScreenPhysicalSize(self):
|
||||||
return self.getWindowPhysicalSize(App.get_running_app().root)
|
return self.getWindowPhysicalSize()
|
||||||
return self.getWindowPhysicalSize(Window)
|
|
||||||
|
|
||||||
def isHandHold(self):
|
def isHandHold(self):
|
||||||
return min(self.getScreenPhysicalSize()) <= 75.0
|
return min(self.getScreenPhysicalSize()) <= 75.0
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
from traceback import print_exc
|
||||||
from kivy.logger import Logger
|
from kivy.logger import Logger
|
||||||
|
from kivy.factory import Factory
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
@ -35,21 +37,14 @@ class LoginForm(Popup):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(size_hint=(0.8,0.8))
|
super().__init__(size_hint=(0.8,0.8))
|
||||||
self.title = 'login'
|
self.title = 'login'
|
||||||
self.initflag = False
|
self.buildContent(None,None)
|
||||||
self.bind(size=self.buildContent,
|
self.register_event_type('on_setupuser')
|
||||||
pos=self.buildContent)
|
|
||||||
|
|
||||||
|
def on_setupuser(self,o=None):
|
||||||
|
return
|
||||||
|
|
||||||
def buildContent(self,o,size):
|
def buildContent(self,o,size):
|
||||||
print('build Content. ....')
|
self.content = Factory.Form(**logformdesc['options'])
|
||||||
if self.initflag:
|
|
||||||
return
|
|
||||||
print('build Content ....... ....')
|
|
||||||
self.initflag = True
|
|
||||||
app = App.get_running_app()
|
|
||||||
try:
|
|
||||||
self.content = app.blocks.widgetBuild(logformdesc)
|
|
||||||
except Exception as e:
|
|
||||||
Logger.info('login: Error %s', e)
|
|
||||||
self.content.bind(on_submit=self.on_submit)
|
self.content.bind(on_submit=self.on_submit)
|
||||||
|
|
||||||
def on_submit(self,o,userinfo):
|
def on_submit(self,o,userinfo):
|
||||||
@ -61,10 +56,7 @@ class LoginForm(Popup):
|
|||||||
if userinfo.get('passwd',False):
|
if userinfo.get('passwd',False):
|
||||||
userinfo['authmethod'] = 'password'
|
userinfo['authmethod'] = 'password'
|
||||||
authinfo = app.serverinfo.encode(userinfo)
|
authinfo = app.serverinfo.encode(userinfo)
|
||||||
config = getConfig()
|
self.dispatch('on_setupuser')
|
||||||
login_url = '%s%s' % (config.uihome, config.login_url)
|
|
||||||
x = app.hc.get(login_url)
|
|
||||||
print('login return=', x, login_url, authinfo)
|
|
||||||
|
|
||||||
def on_cancel(self,o,v):
|
def on_cancel(self,o,v):
|
||||||
print('login() on_cancel fired .....')
|
print('login() on_cancel fired .....')
|
||||||
|
75
kivyblocks/newwidget.py
Normal file
75
kivyblocks/newwidget.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
from kivy.logger import Logger
|
||||||
|
from kivy.graphics import Color, Rectangle
|
||||||
|
from kivy.properties import ListProperty, NumericProperty
|
||||||
|
from kivy.factory import Factory
|
||||||
|
from kivy.uix.widget import Widget
|
||||||
|
|
||||||
|
from .color_definitions import getColors
|
||||||
|
|
||||||
|
class NewWidget(Widget):
|
||||||
|
bgcolor = ListProperty([])
|
||||||
|
fcolor = ListProperty([])
|
||||||
|
color_level = NumericProperty(-1)
|
||||||
|
def __init__(self, color_level=-1,bgcolor=[],fcolor=[],**kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
self.fcolor = fcolor
|
||||||
|
self.color_level = color_level
|
||||||
|
self.initColors()
|
||||||
|
self.bind(size=self.onSize_bgcolor_behavior,
|
||||||
|
pos=self.onSize_bgcolor_behavior)
|
||||||
|
|
||||||
|
def initColors(self):
|
||||||
|
if self.color_level != -1:
|
||||||
|
fcolor, bgcolor = getColors(self.color_level)
|
||||||
|
if self.bgcolor == []:
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
if self.fcolor == []:
|
||||||
|
self.fcolor = fcolor
|
||||||
|
|
||||||
|
def getParentColorLevel(self):
|
||||||
|
if not self.parent:
|
||||||
|
self.fcolor, self.bgcolor = getColors(self.color_level):
|
||||||
|
|
||||||
|
def on_color_level(self,o,v=None):
|
||||||
|
if bgcolor != [] and fcolor != []:
|
||||||
|
return
|
||||||
|
|
||||||
|
if color_level != -1:
|
||||||
|
fcolor, bgcolor = getColors(self.color_level)
|
||||||
|
if self.bgcolor == []:
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
if self.fcolor == []:
|
||||||
|
self.fcolor = fcolor
|
||||||
|
|
||||||
|
def on_fcolor(self,o,v=None):
|
||||||
|
self.color = self.fcolor
|
||||||
|
|
||||||
|
def on_parent(self,o,v=None):
|
||||||
|
if self.color_level != -1:
|
||||||
|
self.fcolor, self.bgcolor = getColors(self.color_level)
|
||||||
|
|
||||||
|
if self.color_level == -1:
|
||||||
|
self.setColorsFromAncestor()
|
||||||
|
|
||||||
|
def onSize_bgcolor_behavior(self,o,v=None):
|
||||||
|
if not hasattr(self,'rect'):
|
||||||
|
self.on_bgcolor()
|
||||||
|
else:
|
||||||
|
self.rect.pos = o.pos
|
||||||
|
self.rect.size = o.size
|
||||||
|
|
||||||
|
def on_bgcolor(self,o=None,v=None):
|
||||||
|
if self.bgcolor == []:
|
||||||
|
return
|
||||||
|
if self.canvas:
|
||||||
|
with self.canvas.before:
|
||||||
|
Color(*self.bgcolor)
|
||||||
|
self.rect = Rectangle(pos=self.pos,
|
||||||
|
size=self.size)
|
||||||
|
|
||||||
|
try:
|
||||||
|
Factory.unregister('Widget')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
Factory.register('Widget',cls=NewWidget)
|
@ -2,6 +2,7 @@ import traceback
|
|||||||
import math
|
import math
|
||||||
|
|
||||||
from kivy.logger import Logger
|
from kivy.logger import Logger
|
||||||
|
from kivy.event import EventDispatcher
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.uix.button import Button
|
from kivy.uix.button import Button
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
@ -9,7 +10,7 @@ from kivy.app import App
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
from appPublic.dictObject import DictObject
|
from appPublic.dictObject import DictObject
|
||||||
from appPublic.jsonConfig import getConfig
|
from appPublic.jsonConfig import getConfig
|
||||||
from .baseWidget import Text
|
from .baseWidget import Text, HTTPDataHandler
|
||||||
from .utils import CSize, absurl, alert
|
from .utils import CSize, absurl, alert
|
||||||
from .form import StrSearchForm
|
from .form import StrSearchForm
|
||||||
|
|
||||||
@ -28,37 +29,22 @@ class PagingButton(Button):
|
|||||||
locater
|
locater
|
||||||
filter
|
filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageLoader load data in a page size once.
|
||||||
|
it fires two type of event
|
||||||
|
'on_newbegin':fire when start a new parameters loading series
|
||||||
|
'on_pageloaded':fire when a page data loads success
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class HttpLoader:
|
class PageLoader(EventDispatcher):
|
||||||
def __init__(self, url, method, params,page_rows=60):
|
def __init__(self,target=None, **options):
|
||||||
self.page_rows = page_rows
|
|
||||||
self.url = url
|
|
||||||
self.method = method
|
|
||||||
self.params = params
|
|
||||||
|
|
||||||
def setParams(self,params, url=None, page_rows=60):
|
|
||||||
self.params = params
|
|
||||||
if url is not None:
|
|
||||||
self.url = url
|
|
||||||
self.page_rows = page_rows
|
|
||||||
|
|
||||||
def load(self, callback, errback=None):
|
|
||||||
hc = App.get_running_app().hc
|
|
||||||
x = hc(self.url,
|
|
||||||
method=self.method,
|
|
||||||
params=self.params,
|
|
||||||
callback=callback,
|
|
||||||
errback=errback)
|
|
||||||
|
|
||||||
class PageLoader:
|
|
||||||
def __init__(self, **options):
|
|
||||||
self.loading = False
|
self.loading = False
|
||||||
|
self.target = target
|
||||||
|
self.options = options
|
||||||
self.filter = None
|
self.filter = None
|
||||||
if options.get('filter'):
|
if options.get('filter'):
|
||||||
self.filter = StrSearchForm(**options['filter'])
|
self.filter = StrSearchForm(**options['filter'])
|
||||||
self.filter.bind(on_submit=self.do_search)
|
self.filter.bind(on_submit=self.do_search)
|
||||||
|
|
||||||
self.params = options.get('params',{})
|
self.params = options.get('params',{})
|
||||||
self.method = options.get('method','GET')
|
self.method = options.get('method','GET')
|
||||||
self.url = options.get('dataurl')
|
self.url = options.get('dataurl')
|
||||||
@ -66,14 +52,34 @@ class PageLoader:
|
|||||||
self.total_cnt = 0
|
self.total_cnt = 0
|
||||||
self.total_page = 0
|
self.total_page = 0
|
||||||
self.curpage = 0
|
self.curpage = 0
|
||||||
Logger.info('kivyblocks: method=%s,type=%s',str(self.method),type(self.method))
|
self.dir = 'down'
|
||||||
self.loader = HttpLoader(self.url, self.method, self.params )
|
self.register_event_type('on_newbegin')
|
||||||
|
self.register_event_type('on_pageloaded')
|
||||||
|
|
||||||
|
def getLocater(self):
|
||||||
|
x = 1 / self.MaxbufferPage
|
||||||
|
if self.dir != 'down':
|
||||||
|
x = 1 - x
|
||||||
|
print('getLocater(),x=%f,dir=%s,self.curpage=%d' % (x,self.dir,self.curpage))
|
||||||
|
return x
|
||||||
|
|
||||||
|
def on_newbegin(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_pageloaded(self,d):
|
||||||
|
"""
|
||||||
|
d={
|
||||||
|
page:
|
||||||
|
data:[]
|
||||||
|
dir:'up' or 'down'
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def do_search(self,o,params):
|
def do_search(self,o,params):
|
||||||
print('PageLoader().do_search(), on_submit handle....',params)
|
print('PageLoader().do_search(), on_submit handle....',params)
|
||||||
self.clearer()
|
self.dispatch('on_newbegin')
|
||||||
self.params.update(params)
|
self.params.update(params)
|
||||||
self.loader.setParams(self.params)
|
|
||||||
self.loadPage(1)
|
self.loadPage(1)
|
||||||
|
|
||||||
def calculateTotalPage(self):
|
def calculateTotalPage(self):
|
||||||
@ -94,22 +100,20 @@ class PageLoader:
|
|||||||
self.curpage = 1
|
self.curpage = 1
|
||||||
self.loadPage(self.curpage)
|
self.loadPage(self.curpage)
|
||||||
|
|
||||||
def setDir(self):
|
|
||||||
pages = self.objectPages.keys()
|
|
||||||
if len(pages)==0:
|
|
||||||
self.dir = 'down'
|
|
||||||
return
|
|
||||||
if self.curpage >= max(self.objectPages.keys()):
|
|
||||||
self.dir = 'down'
|
|
||||||
else:
|
|
||||||
self.dir = 'up'
|
|
||||||
|
|
||||||
def show_page(self,o,d):
|
def show_page(self,o,d):
|
||||||
p = (self.curpage - 1) * self.page_rows + 1
|
p = (self.curpage - 1) * self.page_rows + 1
|
||||||
for r in d['rows']:
|
for r in d['rows']:
|
||||||
r['__posInSet__'] = p
|
r['__posInSet__'] = p
|
||||||
p += 1
|
p += 1
|
||||||
|
self.total_cnt = d['total']
|
||||||
|
self.calculateTotalPage()
|
||||||
|
d = {
|
||||||
|
"page":self.curpage,
|
||||||
|
"dir":self.dir,
|
||||||
|
"data":d['rows']
|
||||||
|
}
|
||||||
|
self.dispatch('on_pageloaded',d)
|
||||||
|
|
||||||
def httperror(self,o,e):
|
def httperror(self,o,e):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
alert(str(e),title='alert')
|
alert(str(e),title='alert')
|
||||||
@ -117,6 +121,12 @@ class PageLoader:
|
|||||||
def loadPage(self,p):
|
def loadPage(self,p):
|
||||||
if not self.url:
|
if not self.url:
|
||||||
raise Exception('dataurl must be present:options=%s' % str(options))
|
raise Exception('dataurl must be present:options=%s' % str(options))
|
||||||
|
if self.curpage > p:
|
||||||
|
self.dir = 'up'
|
||||||
|
elif self.curpage == p:
|
||||||
|
self.dir = 'reload'
|
||||||
|
else:
|
||||||
|
self.dir = 'down'
|
||||||
self.curpage = p
|
self.curpage = p
|
||||||
self.loading = True
|
self.loading = True
|
||||||
params = self.params.copy()
|
params = self.params.copy()
|
||||||
@ -124,9 +134,11 @@ class PageLoader:
|
|||||||
"page":self.curpage,
|
"page":self.curpage,
|
||||||
"rows":self.page_rows
|
"rows":self.page_rows
|
||||||
})
|
})
|
||||||
url = absurl(self.url,self.target.parenturl)
|
realurl = absurl(self.url,self.target.parenturl)
|
||||||
self.loader.setParams(params,url=url)
|
loader = HTTPDataHandler(realurl,params=params)
|
||||||
self.loader.load(self.show_page,self.httperror)
|
loader.bind(on_success=self.show_page)
|
||||||
|
loader.bind(on_failed=self.httperror)
|
||||||
|
loader.handle()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
@ -139,22 +151,25 @@ class PageLoader:
|
|||||||
method,
|
method,
|
||||||
filter
|
filter
|
||||||
}
|
}
|
||||||
|
events:
|
||||||
|
'on_bufferraise': erase
|
||||||
|
|
||||||
"""
|
"""
|
||||||
class RelatedLoader(PageLoader):
|
class RelatedLoader(PageLoader):
|
||||||
def __init__(self, **options):
|
def __init__(self, **options):
|
||||||
super().__init__(**options)
|
super().__init__(**options)
|
||||||
self.adder = options.get('adder')
|
|
||||||
self.locater = options.get('locater',None)
|
|
||||||
self.remover = options.get('remover')
|
|
||||||
self.clearer = options.get('clearer')
|
|
||||||
self.target = options.get('target')
|
|
||||||
self.objectPages = {}
|
self.objectPages = {}
|
||||||
self.totalObj = 0
|
self.totalObj = 0
|
||||||
self.MaxbufferPage = 3
|
self.MaxbufferPage = 3
|
||||||
|
self.locater = 1/self.MaxbufferPage
|
||||||
if self.filter:
|
if self.filter:
|
||||||
self.widget = self.filter
|
self.widget = self.filter
|
||||||
else:
|
else:
|
||||||
self.widget = None
|
self.widget = None
|
||||||
|
self.register_event_type('on_deletepage')
|
||||||
|
|
||||||
|
def on_deletepage(self,d):
|
||||||
|
pass
|
||||||
|
|
||||||
def setPageRows(self,row_cnt):
|
def setPageRows(self,row_cnt):
|
||||||
if self.total_cnt != 0:
|
if self.total_cnt != 0:
|
||||||
@ -171,42 +186,21 @@ class RelatedLoader(PageLoader):
|
|||||||
self.deleteBuffer(p)
|
self.deleteBuffer(p)
|
||||||
|
|
||||||
def deleteBuffer(self,page):
|
def deleteBuffer(self,page):
|
||||||
for w in self.objectPages[page]:
|
d = self.objectPages[page]
|
||||||
self.remover(w)
|
self.dispatch('on_deletepage',d)
|
||||||
self.totalObj -= len(self.objectPages[page])
|
self.totalObj -= len(self.objectPages[page])
|
||||||
del self.objectPages[page]
|
del self.objectPages[page]
|
||||||
|
|
||||||
|
def bufferObjects(self,objects):
|
||||||
|
self.objectPages[self.curpage] = objects
|
||||||
|
|
||||||
def show_page(self,o,data):
|
def show_page(self,o,data):
|
||||||
super().show_page(o,data)
|
|
||||||
if self.objectPages.get(self.curpage):
|
if self.objectPages.get(self.curpage):
|
||||||
self.deleteBuffer(self.curpage)
|
self.deleteBuffer(self.curpage)
|
||||||
else:
|
else:
|
||||||
self.setDir()
|
|
||||||
self.doBufferMaintain()
|
self.doBufferMaintain()
|
||||||
self.total_cnt = data['total']
|
self.totalObj += len(data['rows'])
|
||||||
self.calculateTotalPage()
|
super().show_page(o,data)
|
||||||
widgets = []
|
|
||||||
rows = data['rows']
|
|
||||||
if self.dir == 'up':
|
|
||||||
rows.reverse()
|
|
||||||
for r in rows:
|
|
||||||
if self.dir == 'up':
|
|
||||||
w = self.adder(r,index=self.totalObj)
|
|
||||||
else:
|
|
||||||
w = self.adder(r)
|
|
||||||
widgets.append(w)
|
|
||||||
self.totalObj += 1
|
|
||||||
self.objectPages[self.curpage] = widgets
|
|
||||||
pages = len(self.objectPages.keys())
|
|
||||||
loc = 1.0 / float(pages)
|
|
||||||
if self.locater:
|
|
||||||
if pages == 1:
|
|
||||||
self.locater(1)
|
|
||||||
elif self.dir == 'up':
|
|
||||||
self.locater(1 - loc)
|
|
||||||
else:
|
|
||||||
self.locater(loc)
|
|
||||||
|
|
||||||
self.loading = False
|
self.loading = False
|
||||||
print('buffer pages=',len(self.objectPages.keys()),'pages=',self.objectPages.keys())
|
print('buffer pages=',len(self.objectPages.keys()),'pages=',self.objectPages.keys())
|
||||||
|
|
||||||
@ -218,12 +212,12 @@ class RelatedLoader(PageLoader):
|
|||||||
if len(pages) < 1:
|
if len(pages) < 1:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.curpage = min(pages)
|
page = min(pages)
|
||||||
if self.curpage <= 1:
|
if page <= 1:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.curpage -= 1
|
page -= 1
|
||||||
self.loadPage(self.curpage)
|
self.loadPage(page)
|
||||||
|
|
||||||
def loadNextPage(self):
|
def loadNextPage(self):
|
||||||
if self.loading:
|
if self.loading:
|
||||||
@ -231,11 +225,11 @@ class RelatedLoader(PageLoader):
|
|||||||
pages = self.objectPages.keys()
|
pages = self.objectPages.keys()
|
||||||
if len(pages) == 0:
|
if len(pages) == 0:
|
||||||
return
|
return
|
||||||
self.curpage = max(pages)
|
page = max(pages)
|
||||||
if self.curpage>=self.total_page:
|
if page>=self.total_page:
|
||||||
return
|
return
|
||||||
self.curpage += 1
|
page += 1
|
||||||
self.loadPage(self.curpage)
|
self.loadPage(page)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
{
|
{
|
||||||
|
41
kivyblocks/register.py
Normal file
41
kivyblocks/register.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
from kivy.utils import platform
|
||||||
|
from .baseWidget import *
|
||||||
|
from .tree import Tree, TextTree, PopupMenu
|
||||||
|
from .toolbar import ToolPage, Toolbar
|
||||||
|
from .dg import DataGrid
|
||||||
|
from .vplayer import VPlayer
|
||||||
|
from .form import Form, StrSearchForm
|
||||||
|
from .boxViewer import BoxViewer
|
||||||
|
from .pagescontainer import PageContainer
|
||||||
|
|
||||||
|
r = Factory.register
|
||||||
|
r('PageContainer', PageContainer)
|
||||||
|
r('BoxViewer', BoxViewer)
|
||||||
|
r('Form', Form)
|
||||||
|
r('StrSearchForm', StrSearchForm)
|
||||||
|
r('VPlayer', VPlayer)
|
||||||
|
r('DataGrid', DataGrid)
|
||||||
|
r('Toolbar', Toolbar)
|
||||||
|
r('ToolPage',ToolPage)
|
||||||
|
r('HTTPDataHandler',HTTPDataHandler)
|
||||||
|
r('Text',Text)
|
||||||
|
r('ScrollWidget',ScrollWidget)
|
||||||
|
r('BinStateImage',BinStateImage)
|
||||||
|
r('JsonCodeInput',JsonCodeInput)
|
||||||
|
r('FloatInput',FloatInput)
|
||||||
|
r('IntegerInput',IntegerInput)
|
||||||
|
r('StrInput',StrInput)
|
||||||
|
r('SelectInput',SelectInput)
|
||||||
|
r('BoolInput',BoolInput)
|
||||||
|
r('AmountInput',AmountInput)
|
||||||
|
r('Messager',Messager)
|
||||||
|
r('Bar',Bar)
|
||||||
|
r('LoginForm',LoginForm)
|
||||||
|
r('PressableImage', PressableImage)
|
||||||
|
r('PressableLabel', PressableLabel)
|
||||||
|
r('Tree',Tree)
|
||||||
|
r('TextTree',TextTree)
|
||||||
|
r('PopupMenu',PopupMenu)
|
||||||
|
if platform == 'android':
|
||||||
|
r('PhoneButton',PhoneButton)
|
||||||
|
r('AWebView',AWebView)
|
35
kivyblocks/tab.py
Normal file
35
kivyblocks/tab.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"""
|
||||||
|
{
|
||||||
|
"widgettype":"BLKTabbedPanel",
|
||||||
|
"tab_pos":"top_left",
|
||||||
|
"color_level":0,
|
||||||
|
"width",
|
||||||
|
"height",
|
||||||
|
"size_hint",
|
||||||
|
"tabs":[
|
||||||
|
{
|
||||||
|
"text":"tab1",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidegt",
|
||||||
|
"url":"reggtY",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
class BLKTabItem(BGColorBehavior, TabbedPanelItem):
|
||||||
|
def __init__(self,parent,color_level=0,text="",content={}):
|
||||||
|
self.parent=parent
|
||||||
|
self.color_level = color_level
|
||||||
|
|
||||||
|
class BLKTabedPanel(BGColorBehavior, TabbedPanel):
|
||||||
|
def __init__(self,color_level=0, tabs=[], **kwargs):
|
||||||
|
self.tabs_desc = tabs
|
||||||
|
self.color_level = color_level
|
||||||
|
TabbedPanel.__init__(**kwargs)
|
||||||
|
BGColorBehavior.__init__(self)
|
||||||
|
|
||||||
|
class
|
@ -6,9 +6,7 @@ from kivy.event import EventDispatcher
|
|||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
from .login import LoginForm
|
from .login import LoginForm
|
||||||
|
from .utils import NeedLogin, InsufficientPrivilege, HTTPError
|
||||||
class NeedLogin(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ThreadCall(Thread,EventDispatcher):
|
class ThreadCall(Thread,EventDispatcher):
|
||||||
def __init__(self,target, args=(), kwargs={}):
|
def __init__(self,target, args=(), kwargs={}):
|
||||||
@ -95,7 +93,11 @@ class HttpClient:
|
|||||||
app = App.get_running_app()
|
app = App.get_running_app()
|
||||||
domain = self.url2domain(url)
|
domain = self.url2domain(url)
|
||||||
sessionid = hostsessions.get(domain,None)
|
sessionid = hostsessions.get(domain,None)
|
||||||
print('hostsessions=', hostsessions, 'sessionid=',sessionid, 'domain=',domain)
|
print('hostsessions=', hostsessions,
|
||||||
|
'sessionid=',sessionid,
|
||||||
|
'domain=',domain,
|
||||||
|
'url=',url
|
||||||
|
)
|
||||||
if sessionid:
|
if sessionid:
|
||||||
headers.update({'session':sessionid})
|
headers.update({'session':sessionid})
|
||||||
elif app.getAuthHeader():
|
elif app.getAuthHeader():
|
||||||
@ -128,10 +130,16 @@ class HttpClient:
|
|||||||
except:
|
except:
|
||||||
return resp.text
|
return resp.text
|
||||||
if resp.status_code == 401:
|
if resp.status_code == 401:
|
||||||
|
print('NeedLogin:',url)
|
||||||
raise NeedLogin
|
raise NeedLogin
|
||||||
|
|
||||||
print('Error', url, method, params, resp.status_code,type(resp.status_code))
|
if resp.status_code == 403:
|
||||||
raise Exception('error:%s' % url)
|
raise InsufficientPrivilege
|
||||||
|
|
||||||
|
print('Error', url, method,
|
||||||
|
params, resp.status_code,
|
||||||
|
type(resp.status_code))
|
||||||
|
raise HTTPError(resp.status_code)
|
||||||
|
|
||||||
def __call__(self,url,method="GET",params={},headers={},files={},callback=None,errback=None):
|
def __call__(self,url,method="GET",params={},headers={},files={},callback=None,errback=None):
|
||||||
def cb(t,resp):
|
def cb(t,resp):
|
||||||
@ -142,10 +150,8 @@ class HttpClient:
|
|||||||
resp = self.webcall(url, method=method,
|
resp = self.webcall(url, method=method,
|
||||||
params=params, files=files, headers=headers)
|
params=params, files=files, headers=headers)
|
||||||
return cb(None,resp)
|
return cb(None,resp)
|
||||||
except NeedLogin as e:
|
except Exception as e:
|
||||||
lf = LoginForm()
|
raise e
|
||||||
lf.open()
|
|
||||||
return None
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if errback is not None:
|
if errback is not None:
|
||||||
errback(e)
|
errback(e)
|
||||||
|
@ -42,7 +42,7 @@ class Tool(ButtonBehavior, BGColorBehavior, BoxLayout):
|
|||||||
ButtonBehavior.__init__(self)
|
ButtonBehavior.__init__(self)
|
||||||
BoxLayout.__init__(self,
|
BoxLayout.__init__(self,
|
||||||
size_hint_y=None)
|
size_hint_y=None)
|
||||||
BGColorBehavior.__init__(self)
|
BGColorBehavior.__init__(self,color_level=ancestor.color_level)
|
||||||
self.bl = BoxLayout(orientation='vertical',
|
self.bl = BoxLayout(orientation='vertical',
|
||||||
size_hint_y=None)
|
size_hint_y=None)
|
||||||
self.add_widget(self.bl)
|
self.add_widget(self.bl)
|
||||||
@ -62,7 +62,8 @@ class Tool(ButtonBehavior, BGColorBehavior, BoxLayout):
|
|||||||
|
|
||||||
tsize = CSize(self.opts.text_size)
|
tsize = CSize(self.opts.text_size)
|
||||||
label = self.opts.label or self.opts.name
|
label = self.opts.label or self.opts.name
|
||||||
self.lbl = I18nText(otext=label,
|
self.lbl = I18nText(color_level=self.ancestor.color_level,
|
||||||
|
otext=label,
|
||||||
font_size=int(tsize),
|
font_size=int(tsize),
|
||||||
text_size=(CSize(len(label)), tsize),
|
text_size=(CSize(len(label)), tsize),
|
||||||
height=tsize,
|
height=tsize,
|
||||||
@ -71,24 +72,21 @@ class Tool(ButtonBehavior, BGColorBehavior, BoxLayout):
|
|||||||
)
|
)
|
||||||
self.bl.add_widget(self.lbl)
|
self.bl.add_widget(self.lbl)
|
||||||
self.height = (size + tsize)*1.1
|
self.height = (size + tsize)*1.1
|
||||||
self.lbl.color, self.bgcolor = getColors(self.ancestor.color_level,
|
|
||||||
selected=False)
|
|
||||||
self.lbl.bgcolor = self.bgcolor
|
|
||||||
|
|
||||||
def on_size(self,obj,size):
|
def on_size(self,obj,size):
|
||||||
Logger.info('toolbar: Tool() on_size fired')
|
Logger.info('toolbar: Tool() on_size fired')
|
||||||
self.lbl.color, self.bgcolor = getColors(self.ancestor.color_level,
|
#self.lbl.color, self.bgcolor = getColors(self.ancestor.color_level,
|
||||||
selected=False)
|
# selected=False)
|
||||||
self.lbl.bgcolor = self.bgcolor
|
#self.lbl.bgcolor = self.bgcolor
|
||||||
|
|
||||||
def on_press(self):
|
def on_press(self):
|
||||||
print('Tool(). pressed ...............')
|
print('Tool(). pressed ...............')
|
||||||
|
|
||||||
def setActive(self,flag):
|
def setActive(self,flag):
|
||||||
text_color, self.bgcolor = getColors(self.ancestor.color_level,
|
if flag:
|
||||||
selected=flag)
|
self.selected()
|
||||||
self.lbl.bgcolor = self.bgcolor
|
else:
|
||||||
self.lbl.color = text_color
|
self.unselected()
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -106,11 +104,15 @@ toolbar options
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
class Toolbar(GridLayout):
|
class Toolbar(BGColorBehavior, GridLayout):
|
||||||
def __init__(self, ancestor=None,**opts):
|
def __init__(self, ancestor=None,**opts):
|
||||||
self.opts = DictObject(**opts)
|
self.opts = DictObject(**opts)
|
||||||
self.tool_widgets={}
|
self.tool_widgets={}
|
||||||
super().__init__(cols = len(self.opts.tools))
|
GridLayout.__init__(self,cols = len(self.opts.tools))
|
||||||
|
color_level = 0
|
||||||
|
if isinstance(ancestor, BGColorBehavior):
|
||||||
|
color_level = ancestor.color_level + 1
|
||||||
|
BGColorBehavior.__init__(self,color_level=color_level)
|
||||||
self.size_hint = (1,None)
|
self.size_hint = (1,None)
|
||||||
first = True
|
first = True
|
||||||
for opt in self.opts.tools:
|
for opt in self.opts.tools:
|
||||||
@ -175,9 +177,9 @@ class ToolPage(BGColorBehavior, BoxLayout):
|
|||||||
orient = 'vertical'
|
orient = 'vertical'
|
||||||
else:
|
else:
|
||||||
orient = 'horizontal'
|
orient = 'horizontal'
|
||||||
|
color_level=self.opts.color_level or 0
|
||||||
BoxLayout.__init__(self,orientation=orient)
|
BoxLayout.__init__(self,orientation=orient)
|
||||||
BGColorBehavior.__init__(self)
|
BGColorBehavior.__init__(self,color_level=color_level)
|
||||||
self.content = None
|
self.content = None
|
||||||
self.toolbar = None
|
self.toolbar = None
|
||||||
self.init()
|
self.init()
|
||||||
@ -190,7 +192,6 @@ class ToolPage(BGColorBehavior, BoxLayout):
|
|||||||
self.toolbar.width = x
|
self.toolbar.width = x
|
||||||
self.content.width = x
|
self.content.width = x
|
||||||
self.content.height = y - self.toolbar.height
|
self.content.height = y - self.toolbar.height
|
||||||
self.color, self.bgcolor = getColors(self.color_level)
|
|
||||||
|
|
||||||
def showPage(self,obj):
|
def showPage(self,obj):
|
||||||
self._show_page(obj.opts)
|
self._show_page(obj.opts)
|
||||||
@ -211,8 +212,6 @@ class ToolPage(BGColorBehavior, BoxLayout):
|
|||||||
t.img_src = absurl(t.img_src,parenturl)
|
t.img_src = absurl(t.img_src,parenturl)
|
||||||
|
|
||||||
opts = self.opts
|
opts = self.opts
|
||||||
self.color_level = self.opts.color_level or 0
|
|
||||||
self.color, self.bgcolor = getColors(self.color_level)
|
|
||||||
self.toolbar = Toolbar(ancestor=self, **self.opts)
|
self.toolbar = Toolbar(ancestor=self, **self.opts)
|
||||||
if self.opts.tool_at in ['top','left']:
|
if self.opts.tool_at in ['top','left']:
|
||||||
self.add_widget(self.toolbar)
|
self.add_widget(self.toolbar)
|
||||||
|
@ -285,7 +285,7 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
def __init__(self,**options):
|
def __init__(self,**options):
|
||||||
self.color_level = options.get('color_level',0)
|
self.color_level = options.get('color_level',0)
|
||||||
ScrollWidget.__init__(self)
|
ScrollWidget.__init__(self)
|
||||||
BGColorBehavior.__init__(self)
|
BGColorBehavior.__init__(self,color_level=self.color_level)
|
||||||
self.options = DictObject(**options)
|
self.options = DictObject(**options)
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
self.initflag = False
|
self.initflag = False
|
||||||
@ -377,21 +377,16 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
self.nodes = [ i for i in self.nodes if i != node ]
|
self.nodes = [ i for i in self.nodes if i != node ]
|
||||||
|
|
||||||
class TextContent(PressableLabel):
|
class TextContent(PressableLabel):
|
||||||
def __init__(self,level=0,**options):
|
def __init__(self,color_level=0,**options):
|
||||||
PressableLabel.__init__(self,**options)
|
PressableLabel.__init__(self,color_level=color_level,**options)
|
||||||
|
|
||||||
def selected(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def unselected(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TextTreeNode(TreeNode):
|
class TextTreeNode(TreeNode):
|
||||||
def buildContent(self):
|
def buildContent(self):
|
||||||
txt = self.data.get(self.treeObj.options.textField,
|
txt = self.data.get(self.treeObj.options.textField,
|
||||||
self.data.get(self.treeObj.options.idField,'defaulttext'))
|
self.data.get(self.treeObj.options.idField,'defaulttext'))
|
||||||
self.content = TextContent( text=txt,
|
self.content = TextContent(color_level=self.treeObj.color_level,
|
||||||
|
text=txt,
|
||||||
size_hint=(None,None),
|
size_hint=(None,None),
|
||||||
font_size=CSize(1),
|
font_size=CSize(1),
|
||||||
text_size=CSize(len(txt)-1,1),
|
text_size=CSize(len(txt)-1,1),
|
||||||
@ -412,18 +407,12 @@ class TextTreeNode(TreeNode):
|
|||||||
self.treeObj.select_row(self)
|
self.treeObj.select_row(self)
|
||||||
|
|
||||||
def selected(self):
|
def selected(self):
|
||||||
Logger.info('content selected ........')
|
if hasattr(self.content,'selected'):
|
||||||
color, bgcolor = getColors(self.treeObj.color_level,
|
self.content.selected()
|
||||||
selected=True)
|
|
||||||
self.content.bgcolor = bgcolor
|
|
||||||
self.content.color = color
|
|
||||||
|
|
||||||
def unselected(self):
|
def unselected(self):
|
||||||
Logger.info('content unselected ........')
|
if hasattr(self.content,'unselected'):
|
||||||
color, bgcolor = getColors(self.treeObj.color_level,
|
self.content.unselected()
|
||||||
selected=False)
|
|
||||||
self.content.bgcolor = bgcolor
|
|
||||||
self.content.color = color
|
|
||||||
|
|
||||||
class TextTree(Tree):
|
class TextTree(Tree):
|
||||||
def __init__(self,**options):
|
def __init__(self,**options):
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from traceback import print_exc
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
from appPublic.jsonConfig import getConfig
|
from appPublic.jsonConfig import getConfig
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
@ -11,6 +12,23 @@ from appPublic.dictObject import DictObject
|
|||||||
|
|
||||||
from .kivysize import KivySizes
|
from .kivysize import KivySizes
|
||||||
|
|
||||||
|
class NeedLogin(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InsufficientPrivilege(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class HTTPError(Exception):
|
||||||
|
def __init__(self,resp_code):
|
||||||
|
self.resp_code = resp_code
|
||||||
|
Exception.__init__(self)
|
||||||
|
|
||||||
|
def __expr__(self):
|
||||||
|
return f'Exception:return code={self.resp_code}'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'Exception:return code={self.resp_code}'
|
||||||
|
|
||||||
alert_widget= None
|
alert_widget= None
|
||||||
|
|
||||||
def blockImage(name):
|
def blockImage(name):
|
||||||
@ -81,6 +99,9 @@ def alert(text,title='alert'):
|
|||||||
x = x + ':hh'
|
x = x + ':hh'
|
||||||
alert_widget.title = str(title) + x
|
alert_widget.title = str(title) + x
|
||||||
alert_widget.open()
|
alert_widget.open()
|
||||||
|
print('************')
|
||||||
|
print_exc()
|
||||||
|
print('************')
|
||||||
|
|
||||||
def StrConvert(s):
|
def StrConvert(s):
|
||||||
if not s.startswith('py::'):
|
if not s.startswith('py::'):
|
||||||
|
@ -47,21 +47,31 @@ class StrInput(TextInput):
|
|||||||
kv = {}
|
kv = {}
|
||||||
a = {
|
a = {
|
||||||
"allow_copy":True,
|
"allow_copy":True,
|
||||||
"font_size":1,
|
"password":False,
|
||||||
"multiline":False,
|
"multiline":False,
|
||||||
"halign":"left",
|
"halign":"left",
|
||||||
"hint_text":"",
|
"hint_text":"",
|
||||||
"size_hint_y":None,
|
|
||||||
"width":20,
|
|
||||||
"height":2.5
|
|
||||||
}
|
}
|
||||||
if kv.get('tip'):
|
if kv.get('tip'):
|
||||||
a['hint_text'] = kv['tip']
|
a['hint_text'] = kv['tip']
|
||||||
a.update(kv)
|
# a.update(kv)
|
||||||
a['width'] = CSize(kv.get('width',20))
|
w = kv.get('width',20)
|
||||||
a['height'] = CSize(kv.get('height',2.5))
|
h = kv.get('height',2.5)
|
||||||
|
if w <= 1:
|
||||||
|
a['size_hint_x'] = w
|
||||||
|
else:
|
||||||
|
a['size_hint_x'] = None
|
||||||
|
a['width'] = CSize(w)
|
||||||
|
if h <= 1:
|
||||||
|
a['size_hint_y'] = h
|
||||||
|
else:
|
||||||
|
a['size_hint_y'] = None
|
||||||
|
a['height'] = CSize(h)
|
||||||
a['font_size'] = CSize(kv.get('font_size',1))
|
a['font_size'] = CSize(kv.get('font_size',1))
|
||||||
|
a['password'] = kv.get('password',False)
|
||||||
|
a['multiline'] = kv.get('multiline',False)
|
||||||
|
|
||||||
|
Logger.info('TextInput:a=%s,h=%d,w=%d,CSize(1)=%d',a,h,w,CSize(1))
|
||||||
super(StrInput,self).__init__(**a)
|
super(StrInput,self).__init__(**a)
|
||||||
self.old_value = None
|
self.old_value = None
|
||||||
self.register_event_type('on_changed')
|
self.register_event_type('on_changed')
|
||||||
@ -149,13 +159,16 @@ class MyDropDown(DropDown):
|
|||||||
def __init__(self,**kw):
|
def __init__(self,**kw):
|
||||||
super(MyDropDown,self).__init__()
|
super(MyDropDown,self).__init__()
|
||||||
self.options = kw
|
self.options = kw
|
||||||
self.textField = kw.get('textField',None)
|
self.textField = kw.get('textField','text')
|
||||||
self.valueField = kw.get('valueField',None)
|
self.valueField = kw.get('valueField','value')
|
||||||
if kw.get('url') is not None:
|
self.loadSelectItems()
|
||||||
self.url = kw.get('url')
|
|
||||||
|
def loadSelectItems(self):
|
||||||
|
if self.options.get('url') is not None:
|
||||||
|
self.url = self.options.get('url')
|
||||||
self.setDataByUrl(self.url)
|
self.setDataByUrl(self.url)
|
||||||
else:
|
else:
|
||||||
self.si_data = kw.get('data')
|
self.si_data = self.options.get('data')
|
||||||
self.setData(self.si_data)
|
self.setData(self.si_data)
|
||||||
self.bind(on_select=lambda instance, x: self.selectfunc(x))
|
self.bind(on_select=lambda instance, x: self.selectfunc(x))
|
||||||
|
|
||||||
@ -179,12 +192,23 @@ class MyDropDown(DropDown):
|
|||||||
def setData(self,data):
|
def setData(self,data):
|
||||||
self.si_data = data
|
self.si_data = data
|
||||||
self.clear_widgets()
|
self.clear_widgets()
|
||||||
|
w = self.options.get('width',10)
|
||||||
|
h = self.options.get('height',2.5)
|
||||||
|
a = {}
|
||||||
|
if w <= 1:
|
||||||
|
a['size_hint_x'] = w
|
||||||
|
else:
|
||||||
|
a['size_hint_x'] = None
|
||||||
|
a['width'] = CSize(w)
|
||||||
|
if h <= 1:
|
||||||
|
a['size_hint_y'] = h
|
||||||
|
else:
|
||||||
|
a['size_hint_y'] = None
|
||||||
|
a['height'] = CSize(h)
|
||||||
|
a['font_size'] = CSize(self.options.get('font_size',1))
|
||||||
for d in data:
|
for d in data:
|
||||||
dd = (d[self.valueField],d[self.textField])
|
dd = (d[self.valueField],d[self.textField])
|
||||||
b = Button(text=d[self.textField],font_size=CSize(1),
|
b = Button(text=d[self.textField],**a)
|
||||||
size_hint=(None,None),
|
|
||||||
width=CSize(10),
|
|
||||||
height=CSize(2.5))
|
|
||||||
setattr(b,'kw_data',dd)
|
setattr(b,'kw_data',dd)
|
||||||
b.bind(on_release=lambda btn: self.select(btn.kw_data))
|
b.bind(on_release=lambda btn: self.select(btn.kw_data))
|
||||||
self.add_widget(b)
|
self.add_widget(b)
|
||||||
@ -205,10 +229,22 @@ class MyDropDown(DropDown):
|
|||||||
|
|
||||||
class SelectInput(BoxLayout):
|
class SelectInput(BoxLayout):
|
||||||
def __init__(self,**kw):
|
def __init__(self,**kw):
|
||||||
|
a={}
|
||||||
|
w = kw.get('width',10)
|
||||||
|
h = kw.get('height',2.5)
|
||||||
|
if w <= 1:
|
||||||
|
a['size_hint_x'] = w
|
||||||
|
else:
|
||||||
|
a['size_hint_x'] = None
|
||||||
|
a['width'] = CSize(w)
|
||||||
|
if h <= 1:
|
||||||
|
a['size_hint_y'] = h
|
||||||
|
else:
|
||||||
|
a['size_hint_y'] = None
|
||||||
|
a['height'] = h
|
||||||
|
|
||||||
super(SelectInput,self).__init__(orientation='horizontal',\
|
super(SelectInput,self).__init__(orientation='horizontal',\
|
||||||
size_hint=(None,None),
|
**a)
|
||||||
width=CSize(kw.get('width',10)),
|
|
||||||
height=CSize(kw.get('height',2.5)))
|
|
||||||
self.tinp = StrInput(size_hint_y=None,height=kw.get('height',2.5))
|
self.tinp = StrInput(size_hint_y=None,height=kw.get('height',2.5))
|
||||||
self.tinp.readonly = True
|
self.tinp.readonly = True
|
||||||
newkw = {}
|
newkw = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user