This commit is contained in:
yumoqing 2022-01-29 16:32:51 +08:00
parent b70e2def12
commit b455374a00
13 changed files with 2112 additions and 2167 deletions

View File

@ -3,7 +3,7 @@ import math
from traceback import print_exc
from kivy.properties import ObjectProperty, StringProperty, \
NumericProperty, BooleanProperty
NumericProperty, BooleanProperty, OptionProperty
from kivy.app import App
from kivy.utils import platform
from kivy.uix.button import Button, ButtonBehavior
@ -221,11 +221,16 @@ class Title6(Text):
kw.update({'texttype':'title6','bold':True})
Text.__init__(self, **kw)
class Modal(WidgetCSS, WidgetReady, ModalView):
class Modal(VBox):
content = DictProperty(None)
auto_open = BooleanProperty(True)
auto_dismiss = BooleanProperty(True)
position = OptionProperty('tc',options=['tl', 'tc', 'tr',
'cl', 'cc', 'cr',
'bl', 'bc', 'br'])
def __init__(self, **kw):
super(ModalView, self).__init__(**kw)
SUPER(Modal, self, kw)
if self.content:
blocks = Factory.Blocks()
self.content_w = blocks.widgetBuild(self.content)
@ -233,10 +238,69 @@ class Modal(WidgetCSS, WidgetReady, ModalView):
self.add_widget(self.content_w)
else:
print(content,':cannot build widget')
self.register_event_type('on_open')
self.register_event_type('on_pre_open')
self.register_event_type('on_pre_dismiss')
self.register_event_type('on_dismiss')
def on_touch_down(self, touch):
if not self.collide_point(touch.x, touch.y):
if self.auto_dismiss:
self.dispatch('on_pre_dismiss')
self.dismiss()
return True
return super().on_touch_down(touch)
def set_modal_position(self, w):
xn = self.position[1]
yn = self.position[0]
x, y = 0, 0
if xn == 'c':
x = (w.width - self.width) / 2
elif xn == 'r':
x = w.width - self.width
if x < 0:
x = 0
if yn == 'c':
y = (w.height - self.height) / 2
elif yn == 'b':
y = w.height - self.height
if y < 0:
y = 0
if w == Window:
self.pos = x, y
else:
self.pos = w.pos[0] + x, w.pos[1] + y
def open(self, widget=None):
self.dispatch('on_pre_open')
if widget is None:
widget = Window
self.set_modal_position(widget)
Window.add_widget(self)
self.dispatch('on_open')
def dismiss(self, *args):
self.dispatch('on_pre_dismiss')
self.dispatch('on_dismiss')
Window.remove_widget(self)
def on_open(self, *args):
pass
def on_dismiss(self, *args):
pass
def on_pre_open(self, *args):
pass
def on_pre_dismiss(self, *args):
pass
def add_widget(self, w, *args, **kw):
super().add_widget(w, *args, **kw)
# super().add_widget(Label(text='1111'))
if self.auto_open:
self.open()
@ -244,7 +308,7 @@ class TimedModal(Modal):
show_time = NumericProperty(0)
def __init__(self, **kw):
self.time_task = None
Modal.__init__(self, **kw)
SUPER(TimedModal, self, kw)
def open(self, *args, **kw):
if self.time_task is not None:
@ -259,7 +323,7 @@ class TimedModal(Modal):
if self.time_task:
self.time_task.cancel()
self.time_task = None
super().dismiss(*args, **kw)
super().dismiss()
class PressableImage(ButtonBehavior,AsyncImage):
def on_press(self):

File diff suppressed because it is too large Load Diff

View File

@ -332,7 +332,6 @@ class Blocks(EventDispatcher):
Logger.info('Block: get a null function,%s',str(desc))
return
w.bind(**{event:f})
# Logger.info('Block: %s bind built', str(desc))
def multipleAction(self, widget:Widget, desc, *args):
desc1 = {k:v for k, v in desc.items() if k != 'actions'}
@ -356,11 +355,6 @@ class Blocks(EventDispatcher):
w.open()
def uniaction(self, widget:Widget, desc, *args):
Logger.info('Block: uniaction() called, desc=%s, args=%s', \
str(desc),
args
)
acttype = desc.get('actiontype')
if acttype=='blocks':
return self.blocksAction(widget,desc, *args)
@ -415,7 +409,7 @@ class Blocks(EventDispatcher):
if isinstance(w, ModalView):
return
if target:
if target and not w.parent:
if add_mode == 'replace':
target.clear_widgets()
target.add_widget(w)
@ -431,10 +425,6 @@ class Blocks(EventDispatcher):
b.widgetBuild(opts)
def urlwidgetAction(self, widget:Widget, desc, *args):
Logger.info('Block: urlwidgetAction() called, desc=%s, args=%s', \
str(desc),
args
)
target = self.get_target(widget, desc)
add_mode = desc.get('mode','replace')
opts = desc.get('options').copy()
@ -454,7 +444,7 @@ class Blocks(EventDispatcher):
if isinstance(w, ModalView):
return
if target:
if target and not w.parent:
if add_mode == 'replace':
target.clear_widgets()
target.add_widget(w)

View File

@ -86,9 +86,7 @@ class InputBox(BoxLayout):
self.init()
def focus_act(self, *args):
show_widget_info(self,'test')
show_widget_info(self.labeltext,'test')
show_widget_info(self.input_widget,'test')
pass
def on_size(self, *args):
@ -103,12 +101,10 @@ class InputBox(BoxLayout):
self.input_widget.size_hint_x = None
self.input_widget.width = self.width - self.labeltext.width - CSize(1)
show_widget_info(self,'test')
show_widget_info(self.labeltext,'test')
show_widget_info(self.input_widget,'test')
def on_datainput(self,o,v=None):
print('on_datainput fired ...',o,v)
pass
#print('on_datainput fired ...',o,v)
def init(self):
if self.initflag:
@ -139,10 +135,7 @@ class InputBox(BoxLayout):
options['hint_text'] = i18n(self.options.get('hint_text'))
options['size_hint_y'] = None
options['height'] = self.height
print('options=', options)
self.input_widget = UiFactory.build_input_widget(options)
print('inputw.height=',self.input_widget.height)
try:
self.input_widget.bind(focus=self.focus_act)
except:
@ -246,6 +239,7 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
notoolbar=BooleanProperty(False)
def __init__(self, **options):
self.cols = 1
self.toolbar_w = None
if self.toolbar_at in ['top','bottom']:
options['orientation'] = 'vertical'
else:
@ -259,23 +253,14 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
if isHandHold() and Window.width < Window.height:
self._cols = 1
self.input_width = 1
print('1-inputwidth=', self.inputwidth,
'input_width=',self.input_width,
'CSize(1)=', CSize(1))
return
if self.cols is None and self.inputwidth is None:
self.input_width = 1
self._cols = 1
print('2-inputwidth=', self.inputwidth,
'input_width=',self.input_width,
'CSize(1)=', CSize(1))
return
if self.inputwidth > 1:
self.input_width = CSize(self.inputwidth)
self._cols = -1 # auto calculate
print('3-inputwidth=', self.inputwidth,
'input_width=',self.input_width,
'CSize(1)=', CSize(1), CSize(self.inputwidth))
return
if self.cols is not None:
self._cols = self.cols
@ -283,15 +268,9 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
self.input_width = -1
else:
self.input_width = CSize(self.inputwidth)
print('4-inputwidth=', self.inputwidth,
'input_width=',self.input_width,
'CSize(1)=', CSize(1))
return
self.input_width = -1
self._cols = 1
print('5-inputwidth=', self.inputwidth,
'input_width=',self.input_width,
'CSize(1)=', CSize(1), CSize(self.inputwidth))
def set_grid_attrs(self):
if self._cols == 1 and self.input_width <= 1:
@ -350,10 +329,10 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
size_hint=(1,1)
)
if self.toolbar_at in ['top', 'left'] and not self.notoolbar:
if self.toolbar_at in ['top', 'left'] and self.toolbar_w:
self.add_widget(self.toolbar_w)
self.add_widget(self.fsc)
if self.toolbar_at in ['bottom', 'right'] and not self.notoolbar:
if self.toolbar_at in ['bottom', 'right'] and self.toolbar_w:
self.add_widget(self.toolbar_w)
self.fieldWidgets=[]
@ -407,7 +386,6 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
return True
def on_submit(self,o, v=None):
print('Form():on_submit fired ...',v)
return False
def on_submit_button(self,o,v=None):
@ -466,5 +444,4 @@ class StrSearchForm(BoxLayout):
self.dispatch('on_submit',d)
def on_submit(self,v=None):
print('StrSearchForm():on_submit fired ..........')
pass

View File

@ -1,6 +1,8 @@
from kivy.factory import Factory
from kivy.properties import StringProperty, NumericProperty
from kivy.core.window import Window
from kivy.properties import StringProperty, NumericProperty, \
OptionProperty
from kivy.uix.image import AsyncImage
from .utils import *
from .baseWidget import Modal, Text, HBox,VBox, TimedModal
@ -45,11 +47,18 @@ class Message(TimedModal):
default_title = 'Message'
default_message = 'Message'
title_icon = StringProperty(blockImage('info.png'))
message = StringPrperty(None)
message = StringProperty(None)
body_css = StringProperty('message_default_body_css')
title_css = StringProperty('message_default_title_css')
show_position = OptionProperty('br', options=['tl','tc','tr',
'cl','cc','cr',
'bl','bc','br'])
width_c = NumericProperty(15)
height_c = NumericProperty(6)
def __init__(self, **kw):
SUPER(Message, self, kw)
self.size_hint = None, None
self.set_position()
b = VBox(csscls=self.title_css)
b1 = HBox(size_hint_y=None, height=CSize(2))
b1.add_widget(AsyncImage(source=self.title_icon,
@ -74,6 +83,34 @@ class Message(TimedModal):
b.add_widget(b2)
self.add_widget(b)
def on_size(self, *args):
self.set_position()
try:
super().on_size(*args)
except:
pass
def set_position(self):
# self.pos_hint = None, None
self.size_hint = None, None
self.width = CSize(self.width_c)
self.height = CSize(self.height_c)
xn = self.show_position[1]
yn = self.show_position[0]
if xn == 'l':
self.anchor_x = 'left'
elif xn == 'c':
self.anchor_x = 'center'
else:
self.anchor_x = 'right'
if yn == 't':
self.anchor_y = 'top'
elif yn == 'c':
self.anchor_y = 'center'
else:
self.anchor_y = 'bottom'
class Error(Message):
default_title = 'Error'
default_message = 'Error message'

View File

@ -310,9 +310,6 @@ sub-widget's description file format
self.sub_widgets = []
self.sub_widgets.append(w)
self.show_currentpage()
show_widget_info(self)
for w in self.get_subwidgets():
show_widget_info(w)
def show_left_menu(self, o):
def x(*args):

View File

@ -52,9 +52,4 @@ class VResponsiveLayout(ScrollView):
if cols < 1:
cols = 1
self._inner.cols = cols
#print(self.width, self._inner.width, self.box_width, cols, cols * self.box_width)
#for c in self.children[:2]:
# show_widget_info(c)
# for c1 in c.children:
# show_widget_info(c1)

View File

@ -210,7 +210,6 @@ class ToolPage(Box):
options=['top', 'bottom', 'left', 'right'])
toolbar = DictProperty({})
def __init__(self, **kw):
print('ToolPage:kw=',kw)
SUPER(ToolPage, self, kw)
if self.tool_at in [ 'top','bottom']:
self.orientation = 'vertical'
@ -306,7 +305,6 @@ class ToolPage(Box):
if w:
self.content_widgets[name] = w
self.content_w.add_widget(w)
print('w=', w)
return
rfname = v.get('rfname')
if rfname:

View File

@ -89,6 +89,7 @@ class TwoSides(WidgetReady, BoxLayout):
w = Factory.Blocks().widgetBuild({
"widgettype":"Modal",
"options":{
"auto_open":False,
"auto_dismiss":True,
"size_hint":[None,None],
"size":(x,y),

View File

@ -7,4 +7,5 @@ from .amount import *
from .password import *
from .text import *
from .code import *
from .viewer import *

View File

@ -23,12 +23,18 @@ class UiFactory:
def build_view_widget(self, desc, rec=None):
ut = desc.get('uitype', 'str')
f = view_widget_builders.get(ut)
if f is None:
print(desc, 'view builder not defined')
return None
return f(desc, rec=rec)
@classmethod
def build_input_widget(self, desc, rec=None):
ut = desc.get('uitype', 'str')
f = input_widget_builders.get(ut)
if f is None:
print(desc, 'input builder not defined')
return None
return f(desc, rec=rec)
class StringView(Label):

View File

@ -0,0 +1,18 @@
import ujson as json
from kivy.factory import Factory
from .factory import UiFactory
from appPublic.myTE import MyTemplateEngine
def view_build_viewer(desc, rec=None):
viewer_desc = desc.get('viewer')
if not viewer_desc:
return None
if isinstance(viewer_desc, dict):
viewer_desc = json.dumps(viewer_desc)
mytmpl = MyTemplateEngine(['.'])
v_desc = mytmpl.renders(viewer_desc, rec)
vdesc = json.loads(v_desc)
return Factory.Blocks().widgetBuild(vdesc)
UiFactory.register('viewer', None, view_build_viewer)

View File

@ -105,7 +105,11 @@ class IntegerInput(StrInput):
self.cursor = (0,len(self.text))
def getValue(self):
try:
return int(self.text)
except:
pass
return None
class FloatInput(IntegerInput):
dec = NumericProperty(2)
@ -114,7 +118,11 @@ class FloatInput(IntegerInput):
self.input_filter = 'float'
def getValue(self):
try:
return float(self.text)
except:
pass
return None
class MyDropDown(DropDown):
def __init__(self,csscls='input', **kw):
@ -151,7 +159,7 @@ class MyDropDown(DropDown):
if d.get(self.textField) == v:
r = d.get(self.valueField)
return r
return ''
return None
def setData(self,data):
self.si_data = data