This commit is contained in:
yumoqing 2020-12-10 23:47:30 +08:00
parent ae89547b70
commit 1bb2fa02c6
14 changed files with 143 additions and 101 deletions

View File

@ -1,6 +1,7 @@
import sys
from traceback import print_exc
from kivy.properties import ObjectProperty, StringProperty
from kivy.app import App
from kivy.utils import platform
from kivy.uix.button import Button, ButtonBehavior
@ -53,6 +54,7 @@ from kivycalendar import DatePicker
from kivy.factory import Factory
from appPublic.dictObject import DictObject
from appPublic.jsonConfig import getConfig
from appPublic.folderUtils import listFile
from .widgetExt.scrollwidget import ScrollWidget
@ -68,6 +70,7 @@ from .login import LoginForm
from .tab import TabsPanel
from .qrdata import QRCodeWidget
from .threadcall import HttpClient
from .i18n import I18n
if platform == 'android':
from .widgetExt.phonebutton import PhoneButton
@ -79,9 +82,33 @@ class WrapText(Label):
self.bind(width=lambda *x: self.setter('text_size')(self, (self.width, None)),
texture_size=lambda *x: self.setter('height')(self, self.texture_size[1]))
class Text(Label):
pass
lang=StringProperty('')
otext = StringProperty('')
def __init__(self,i18n=False, textype='text', **kw):
self._i18n = i18n
kwargs = kw.copy()
config = getConfig()
if config.texttypes:
attrs = config.texttypes.get('texttype',{})
kwargs.update(attrs)
super().__init__(**kwargs)
if self._i18n:
self.i18n = I18n()
self.i18n.addI18nWidget(self)
self.otext = kw.get('text','')
def on_otext(self,o,v=None):
if self._i18n:
self.text = self.i18n(v)
else:
self.text = v
def changeLang(self,lang):
self.lang = lang
def on_lang(self,o,lang):
self.text = self.i18n(self.otext)
class PressableImage(ButtonBehavior,AsyncImage):
def on_press(self):

View File

@ -32,12 +32,11 @@ from .form import InputBox, Form, StrSearchForm
from .boxViewer import BoxViewer
from .tree import Tree, TextTree
from .newvideo import Video
# from .qrcodereader import QRCodeReader
from .ready import WidgetReady
from .bgcolorbehavior import BGColorBehavior
from .orientationlayout import OrientationLayout
from .threadcall import HttpClient
from .twosides import TwoSides
from .register import *
def showError(e):
print('error',e)
@ -278,11 +277,11 @@ class Blocks(EventDispatcher):
return self.dictValueExpr(obj,localnamespace)
return obj
def __build(self,desc:dict):
# print('__build(),desc=',desc)
def w_build(self,desc:dict):
# print('w_build(),desc=',desc)
widgetClass = desc.get('widgettype',None)
if not widgetClass:
print("__build(), desc invalid", desc)
print("w_build(), desc invalid", desc)
raise Exception(desc)
widgetClass = desc['widgettype']
@ -387,11 +386,14 @@ class Blocks(EventDispatcher):
b.widgetBuild(opts)
def urlwidgetAction(self,widget,desc, *args):
print('urlwidgetAction():args=',args)
target = Blocks.getWidgetById(desc.get('target','self'),widget)
add_mode = desc.get('mode','replace')
opts = desc.get('options').copy()
d = self.getActionData(widget,desc)
p = opts.get('params',{}).copy()
if len(args) >= 1 and isinstance(args[0],dict):
p.update(p)
p.update(d)
opts['params'] = p
d = {
@ -416,8 +418,8 @@ class Blocks(EventDispatcher):
data = {}
if desc.get('datawidget',False):
dwidget = Blocks.getWidgetById(desc.get('datawidget','self'),widget)
if dwidget and hasattr(dwidget,'getData'):
data = dwidget.getData()
if dwidget and hasattr(dwidget,'getValue'):
data = dwidget.getValue()
if desc.get('keymapping'):
data = keyMapping(data, desc.get('keymapping'))
return data
@ -476,6 +478,7 @@ class Blocks(EventDispatcher):
}
"""
name = desc['widgettype']
print('desc=',desc,'type=',type(desc))
def doit(desc):
if not isinstance(desc,dict):
@ -483,7 +486,7 @@ class Blocks(EventDispatcher):
raise Exception('desc must be a dict')
desc = self.valueExpr(desc)
widget = self.__build(desc)
widget = self.w_build(desc)
self.dispatch('on_built',widget)
if hasattr(widget,'ready'):
widget.ready()

View File

@ -17,6 +17,7 @@ BoxViewer options:
"""
from traceback import print_exc
from functools import partial
from appPublic.dictExt import dictExtend
from kivy.app import App
from kivy.factory import Factory
from kivy.utils import platform
@ -27,24 +28,32 @@ from .paging import Paging, RelatedLoader
from .utils import CSize
from .ready import WidgetReady
class BoxViewer(WidgetReady, BoxLayout):
def __init__(self, **options):
self.options = options
self.subwidgets = []
self.toolbar = None
self.parenturl = None
self.dataloader = None
self.initflag = False
self.selected_box = None
remind = ['toolbar',
'dataloader',
'orientation',
'viewer',
'boxwidth',
'boxheight']
'boxheight',
'color_level',
'radius',
'viewer_url'
'viewer'
]
kwargs = {k:v for k,v in options.items() if k not in remind }
BoxLayout.__init__(self, orientation='vertical', **kwargs)
WidgetReady.__init__(self)
self.selected_data = None
self.options = options
self.color_level = self.options.get('color_level',-1)
self.radius = self.options.get('radius',[])
self.box_width = CSize(options['boxwidth'])
self.box_height = CSize(options['boxheight'])
self.viewContainer = VResponsiveLayout(cols=2,box_width=self.box_width)
@ -81,6 +90,7 @@ class BoxViewer(WidgetReady, BoxLayout):
def deleteAllWidgets(self,o):
self.viewContainer.clear_widgets()
self.subwidgets = []
def addPageWidgets(self,o,data):
widgets = []
@ -94,6 +104,8 @@ class BoxViewer(WidgetReady, BoxLayout):
for r in recs:
self.showObject(widgets, r, index=idx)
self.subwidgets += widgets
self.dataloader.bufferObjects(page, widgets)
x = self.dataloader.getLocater()
self.locater(x)
@ -101,8 +113,9 @@ class BoxViewer(WidgetReady, BoxLayout):
def deleteWidgets(self,o,data):
for w in data:
self.viewContainer.remove_widget(w)
self.subwidget = [i for i in self.subwidgets if i in data]
def on_selected(self, o, v=None):
def on_selected(self, data=None):
pass
def locater(self, pos):
@ -122,25 +135,46 @@ class BoxViewer(WidgetReady, BoxLayout):
self.initflag = True
def showObject(self, holders, rec,index=0):
def doit(self,holders,idx,o,w):
w.bind(on_press=self.select_record)
w.boxviewer = self
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['options']['record'] = rec
options['options']['size_hint'] = None,None
options['options']['width'] = self.box_width
options['options']['height'] = self.box_height
opts = {
"size_hint":[None,None],
"height":self.box_height,
"width":self.box_width,
"color_level":self.color_level,
"radius":self.radius
}
desc = {
"widgettype":"PressableBox",
"options":opts
}
blocks = Factory.Blocks()
blocks.bind(on_built=partial(doit,self,holders,index))
blocks.bind(on_failed=doerr)
blocks.widgetBuild(options)
box = blocks.w_build(desc)
box.setValue(rec)
box.bind(on_press=self.select_record)
self.viewContainer.add_widget(box,index=index)
self.subwidgets.append(box)
holders.append(box)
desc = {}
if self.options.get('viewer_url'):
desc = {
"widgettype":"urlwidget",
"optons":{
"params":rec,
"method":"GET",
"url":self.options.get('viewer_url')
}
}
else:
desc = self.options.get('viewer').copy()
if desc['widgettype'] == 'urlwidget':
desc = dictExtend(desc,{'options':{'params':rec}})
else:
desc = dictExtend(desc,{'options':{'record':rec}})
def add2box(p,o,w):
p.add_widget(w)
blocks = Factory.Blocks()
blocks.bind(on_built=partial(add2box,box))
blocks.widgetBuild(desc)
def on_scroll_stop(self,o,v=None):
if o.scroll_y <= 0.001:
@ -149,22 +183,19 @@ class BoxViewer(WidgetReady, BoxLayout):
self.dataloader.loadPreviousPage()
def select_record(self,o,v=None):
if self.selected_box:
self.selected_box.unselected()
print('BoxViewer(),on_selected() called\n',
'normal_bgcolor=',o.normal_bgcolor,'\n',
'selected_bgcolor=',o.selected_bgcolor,'\n',
'bg_color=',o.bgcolor,'\n',
'color_level=',self.color_level)
for w in self.subwidgets:
w.unselected()
o.selected()
self.selected_box = o
self.selected_data = o.getValue()
self.dispatch('on_selected',self.selected_data)
self.selected_data = o.getRecord()
d = {
"target":self.selected_box,
"page_rows":1,
"page":self.selected_data['__posInSet__'],
"dataurl":self.options['dataloader']['options']['dataurl'],
"params":self.params
}
self.dispatch('on_selected',d)
def getData(self):
def getValue(self):
return self.selected_data
d = {
"caller":self,

View File

@ -21,7 +21,6 @@ from .widgetExt import ScrollWidget
from .paging import Paging, RelatedLoader
from .ready import WidgetReady
from .toolbar import Toolbar
from .i18n import I18nText
from .bgcolorbehavior import BGColorBehavior
class BLabel(ButtonBehavior, Text):
@ -59,7 +58,7 @@ class Cell(BoxLayout):
self.add_widget(w)
return
if desc['header']:
bl = I18nText(otext=str(desc['value']),
bl = Text(i18n=True, text=str(desc['value']),
font_size=CSize(1),
halign='left'
)
@ -230,6 +229,7 @@ class DataGrid(WidgetReady, BGColorBehavior, BoxLayout):
kw.orientation = 'vertical'
self.color_level = color_level
self.radius = radius
self.select_rowid = None
WidgetReady.__init__(self)
BoxLayout.__init__(self,**kw)
BGColorBehavior.__init__(self,color_level=color_level,
@ -299,8 +299,8 @@ class DataGrid(WidgetReady, BGColorBehavior, BoxLayout):
if o.scroll_y >= 0.999:
self.dataloader.loadPreviousPage()
def getData(self):
if not self.row_selected:
def getValue(self):
if not self.select_rowid:
return None
return self._getRowData(self.select_rowid)
@ -309,7 +309,7 @@ class DataGrid(WidgetReady, BGColorBehavior, BoxLayout):
if self.freeze_part:
d.update(self.freeze_part.body.getRowData(rowid))
d.update(self.normal_part.body.getRowData(rowid))
print('getData() return=',d)
print('getValue() return=',d)
return DictObject(**d)
def bodyOnSize(self,o,s):
@ -408,4 +408,3 @@ class DataGrid(WidgetReady, BGColorBehavior, BoxLayout):
fs.append(f)
return fs
Factory.register('DataGrid',DataGrid)

View File

@ -113,8 +113,6 @@ class FileLoaderBrowser(Popup):
self.control_box.add_widget(self.btn_load)
self.control_box.add_widget(self.btn_icon_view)
Factory.register('FileLoaderBrowser',FileLoaderBrowser)
if __name__ == '__main__':
from kivy.app import App
class Test(App):

View File

@ -10,7 +10,7 @@ from .widgetExt.inputext import FloatInput,IntegerInput, \
StrInput,SelectInput, BoolInput, AmountInput, Password
from .baseWidget import *
from .utils import *
from .i18n import I18nText, I18n
from .i18n import I18n
from .toolbar import Toolbar
from .color_definitions import getColors
from .bgcolorbehavior import BGColorBehavior
@ -161,14 +161,15 @@ class InputBox(BoxLayout):
self.add_widget(bl)
label = self.options.get('label',self.options.get('name'))
kwargs = {
"otext":label,
"i18n":True,
"text":label,
"font_size":CSize(1),
"size_hint_x":None,
"width":CSize(len(label)),
"size_hint_y":None,
"height":CSize(3)
}
self.labeltext = I18nText(**kwargs)
self.labeltext = Text(**kwargs)
bl.add_widget(self.labeltext)
Logger.info('kivyblock:label.widht=%f,label.height=%f',
self.labeltext.width,self.labeltext.height)
@ -300,7 +301,7 @@ class Form(BGColorBehavior, BoxLayout):
w.input_widget.focus_previous = p.input_widget
p = w
def getData(self):
def getValue(self):
d = {}
for f in self.fieldWidgets:
v = f.getValue()
@ -325,7 +326,7 @@ class Form(BGColorBehavior, BoxLayout):
if not self.checkData():
Logger.info('kivyblocks: CheckData False')
return
d = self.getData()
d = self.getValue()
Logger.info('kivyblocks: fire on_submit')
self.dispatch('on_submit',d)
@ -348,7 +349,7 @@ class StrSearchForm(BoxLayout):
self.register_event_type('on_submit')
self.input_widget.bind(on_text_validate=self.submit_input)
def getData(self):
def getValue(self):
d = {
self.name:self.input_widget.text
}

View File

@ -1,9 +1,9 @@
import locale
from kivy.app import App
from kivy.properties import StringProperty
from kivy.uix.label import Label
from appPublic.Singleton import SingletonDecorator
from appPublic.jsonConfig import getConfig
from .baseWidget import Text
from .threadcall import HttpClient
@SingletonDecorator
@ -42,26 +42,3 @@ class I18n:
for w in self.i18nWidgets:
w.changeLang(lang)
class I18nText(Text):
lang=StringProperty('')
otext=StringProperty('')
def __init__(self,**kw):
self.options = kw.copy()
otext = kw.get('otext',kw.get('text'))
if kw.get('otext'):
del kw['otext']
super().__init__(**kw)
self.i18n = I18n()
self.i18n.addI18nWidget(self)
self.otext = otext
def on_otext(self,o,v=None):
self.text = self.i18n(self.otext)
def changeLang(self,lang):
self.lang = lang
def on_lang(self,o,lang):
self.text = self.i18n(self.otext)

View File

@ -86,4 +86,3 @@ class KivyCamera(Image):
self.update_task = None
# self.cupture.close()
Factory.register('KivyCamera',KivyCamera)

View File

@ -132,8 +132,6 @@ class QRCodeWidget(FloatLayout):
img.texture = texture
img.canvas.ask_update()
Factory.register('QRCodeWidget',QRCodeWidget)
if __name__ == '__main__':
from kivy.app import runTouchApp
import sys

View File

@ -9,8 +9,20 @@ from .form import Form, StrSearchForm
from .boxViewer import BoxViewer
from .pagescontainer import PageContainer
from .hostimage import HostImage
from .toggleitems import PressableBox, ToggleItems
from .twosides import TwoSides
from .tab import TabsPanel
from .qrdata import QRCodeWidget
from .kivycamera import KivyCamera
from .filebrowser import FileLoaderBrowser
r = Factory.register
r('DataGrid',DataGrid)
r('FileLoaderBrowser',FileLoaderBrowser)
r('KivyCamera',KivyCamera)
r('QRCodeWidget',QRCodeWidget)
r('TabsPanel',TabsPanel)
r('TwoSides',TwoSides)
r('PageContainer', PageContainer)
r('BoxViewer', BoxViewer)
r('Form', Form)
@ -41,6 +53,8 @@ r('PopupMenu',PopupMenu)
r('HostImage',HostImage)
r('APlayer',APlayer)
r('WrapText',WrapText)
r('PressableBox',PressableBox)
r('ToggleItems',ToggleItems)
if platform == 'android':
r('PhoneButton',PhoneButton)
r('AWebView',AWebView)

View File

@ -57,8 +57,6 @@ class TabsPanel(BGColorBehavior, TabbedPanel):
desc = d['content']
self.add_tab(name,text,desc)
Factory.register('TabsPanel',TabsPanel)
if __name__ == '__main__':
from kivy.app import App
pass

View File

@ -28,10 +28,10 @@ class PressableBox(BGColorBehavior, TouchRippleButtonBehavior, BoxLayout):
def on_press(self,o=None):
self.selected()
def set_data(self,d):
def setValue(self,d):
self.user_data = d
def get_data(self):
def getValue(self):
return self.user_data
class ToggleItems(BGColorBehavior, BoxLayout):
@ -73,7 +73,7 @@ class ToggleItems(BGColorBehavior, BoxLayout):
c = PressableBox(**kw)
d = desc.get('data')
if d:
c.set_data(d)
c.setValue(d)
self.item_widgets.append(c)
self.add_widget(c)
c.bind(on_press=self.select_item)
@ -98,20 +98,18 @@ class ToggleItems(BGColorBehavior, BoxLayout):
def select_item(self,o=None):
[i.unselected() for i in self.item_widgets if i != o]
self.dispatch('on_press',o.get_data())
self.dispatch('on_press',o.getValue())
def getValue(self):
for i in self.item_widgets:
if i.is_selected():
return i.get_data()
return i.getValue()
return None
def setValue(self,v):
for i in self.item_widgets:
if i.get_data() == v:
if i.getValue() == v:
i.selected()
self.select_iten(i)
return
Factory.register('PressableBox',PressableBox)
Factory.register('ToggleItems',ToggleItems)

View File

@ -13,9 +13,9 @@ from appPublic.dictObject import DictObject
from .widgetExt.scrollwidget import ScrollWidget
from .utils import *
from .ready import WidgetReady
from .i18n import I18nText
from .color_definitions import getColors
from .bgcolorbehavior import BGColorBehavior
from .baseWidget import Text
"""
toobar={
@ -62,7 +62,8 @@ class Tool(ButtonBehavior, BGColorBehavior, BoxLayout):
tsize = CSize(self.opts.text_size)
label = self.opts.label or self.opts.name
self.lbl = I18nText( otext=label,
self.lbl = Text(i18n=True,
text=label,
font_size=int(tsize),
text_size=(CSize(len(label)), tsize),
height=tsize,

View File

@ -56,5 +56,3 @@ class TwoSides(WidgetReady, BoxLayout):
self.clear_widgets()
self.add_widget(self.portrait_widget)
Factory.register('TwoSides',TwoSides)