This commit is contained in:
yumoqing 2022-02-19 15:53:32 +08:00
parent 5e32fe3083
commit 586f6a46db
9 changed files with 1119 additions and 994 deletions

View File

@ -273,6 +273,8 @@ class Modal(VBox):
self.pos = w.pos[0] + x, w.pos[1] + y self.pos = w.pos[0] + x, w.pos[1] + y
def open(self, widget=None): def open(self, widget=None):
if self.parent:
return
self.dispatch('on_pre_open') self.dispatch('on_pre_open')
if widget is None: if widget is None:
widget = Window widget = Window

File diff suppressed because it is too large Load Diff

View File

@ -461,6 +461,7 @@ class Blocks(EventDispatcher):
data.update(rt) data.update(rt)
if desc.get('keymapping'): if desc.get('keymapping'):
data = keyMapping(data, desc.get('keymapping')) data = keyMapping(data, desc.get('keymapping'))
Logger.info('getActionData():rtdesc=%s, data=%s', rtdesc, data)
return data return data
def registedfunctionAction(self, widget:Widget, desc, *args): def registedfunctionAction(self, widget:Widget, desc, *args):

View File

@ -126,6 +126,8 @@ class ClickableIconText(_IconBehavior, _TextBehavior, ClickableBox):
class CommandBox(ClickableIconText): class CommandBox(ClickableIconText):
value = DictProperty(None) value = DictProperty(None)
params = DictProperty(None)
conform = DictProperty(None)
target = StringProperty(None) target = StringProperty(None)
datawidget = StringProperty(None) datawidget = StringProperty(None)
datamethod = StringProperty(None) datamethod = StringProperty(None)
@ -143,6 +145,8 @@ class CommandBox(ClickableIconText):
datawidget = self.datawidget, datawidget = self.datawidget,
datamethod = self.method, datamethod = self.method,
url=self.url, url=self.url,
params=self.params,
conform = self.conform,
rfname = self.rfname, rfname = self.rfname,
method = self.method, method = self.method,
script = self.script, script = self.script,
@ -325,9 +329,15 @@ def build_cmdbox_view(desc, rec=None):
kw = { kw = {
'text' : desc.get('label'), 'text' : desc.get('label'),
'source' : desc.get('icon'), 'source' : desc.get('icon'),
'img_kw' : desc.get('img_kw'), 'img_kw' : desc.get('img_kw',{
'size_hint':[None, None],
'height':CSize(1),
'width':CSize(1)
}),
'rfname':desc.get('rfname'), 'rfname':desc.get('rfname'),
'script':desc.get('script'), 'script':desc.get('script'),
'params':desc.get('params'),
'conform':desc.get('conform'),
'target':desc.get('target'), 'target':desc.get('target'),
'datawidget':desc.get('datawidget'), 'datawidget':desc.get('datawidget'),
'datamethod':desc.get('datamethod'), 'datamethod':desc.get('datamethod'),

View File

@ -7,6 +7,7 @@ def get_cmd_desc(cmd_desc):
desc = { desc = {
} }
v = cmd_desc v = cmd_desc
desc['conform'] = v.get('conform')
desc['target'] = v.get('target') desc['target'] = v.get('target')
if v.get('datawidget'): if v.get('datawidget'):
desc['datawidget'] = v.get('datawidget') desc['datawidget'] = v.get('datawidget')
@ -14,6 +15,7 @@ def get_cmd_desc(cmd_desc):
desc['datamethod'] = v['datamethod'] desc['datamethod'] = v['datamethod']
keys = v.keys() keys = v.keys()
if 'url' in keys: if 'url' in keys:
Logger.info('get_cmd_desc():cmd_desc=%s', cmd_desc)
desc['actiontype'] = 'urlwidget' desc['actiontype'] = 'urlwidget'
desc['mode'] = 'replace' desc['mode'] = 'replace'
options = { options = {
@ -43,14 +45,22 @@ def get_cmd_desc(cmd_desc):
def cmd_action(cmd_desc, widget): def cmd_action(cmd_desc, widget):
desc = get_cmd_desc(cmd_desc) desc = get_cmd_desc(cmd_desc)
if desc is None: if desc is None:
Logger.error('CommandAction: cmd_desc=%s error') Logger.error('CommandAction: desc is None cmd_desc=%s error', \
cmd_desc)
return return
blocks = Factory.Blocks() blocks = Factory.Blocks()
if 'conform' in cmd_desc: conform_desc = desc.get('conform')
options = cmd_desc['conform'] if conform_desc is None:
w = Factory.Conform(**options) Logger.info('cmd_action():desc=%s', desc)
f = partial(blocks.uniaction, widget, desc) blocks.uniaction(widget, desc)
w.bind(on_conform=f)
return return
blocks.uniaction(widget, desc)
w = blocks.widgetBuild({
"widgettype":"Conform",
"options":conform_desc
})
w.bind(on_conform=partial(blocks.uniaction, widget, desc))
w.open()
Logger.info('cmd_action():desc=%s, conform and action', desc)

View File

@ -2,12 +2,79 @@ from appPublic.timeUtils import curDateString, monthMaxDay
from kivy.clock import Clock from kivy.clock import Clock
from kivy.factory import Factory from kivy.factory import Factory
from kivy.properties import NumericProperty from kivy.properties import NumericProperty, BooleanProperty, \
OptionProperty
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label from kivy.uix.label import Label
from kivyblocks.baseWidget import SelectInput, HBox from kivyblocks.baseWidget import SelectInput, HBox
from kivyblocks.utils import CSize from kivyblocks.utils import CSize
date_format_info = {
'yyyy-mm-dd':{
'ystart':0,
'mstart':5,
'dstart':8
},
'mm-dd-yyyy':{
'ystart':6,
'mstart':0,
'dstart':3
},
'dd-mm-yyyy':{
'ystart':6,
'mstart':3,
'dstart':0
},
'yyyymmdd':{
'ystart':0,
'mstart':4,
'dstart':6
},
'mmddyyyy':{
'ystart':4,
'mstart':0,
'dstart':2
},
'ddmmyyyy':{
'ystart':4,
'mstart':2,
'dstart':0
}
}
def get_datestr(y, m, d, dateformat):
def replace_slice(s, v, pos,length):
x = '%0' + str(length) + 'd'
sv = x % v
d = ''
if pos > 0:
d = s[0:pos]
d = d + sv
d = d + s[pos+length:]
return d
if y is None:
return None
info = date_format_info.get(dateformat)
if info is None:
return None
ret = dateformat
ret = replace_slice(ret, y, info['ystart'], 4)
ret = replace_slice(ret, m, info['mstart'], 4)
ret = replace_slice(ret, d, info['dstart'], 4)
return ret
def get_ymd(dstr, dateformat):
if not dstr:
return None, None, None
info = date_format_info.get(dateformat)
if info is None:
return None, None, None
y = int(dstr[info['ystart'], info['ystart']+4])
m = int(dstr[info['mstart'], info['mstart']+2])
d = int(dstr[info['dstart'], info['dstart']+2])
return y, m, d
class YearInput(SelectInput): class YearInput(SelectInput):
nullable = BooleanProperty(True) nullable = BooleanProperty(True)
e_year = NumericProperty(None) e_year = NumericProperty(None)
@ -87,27 +154,16 @@ class YearInput(SelectInput):
class DateInput(HBox): class DateInput(HBox):
default_date = OptionProperty(None, options=[None, 'today']) default_date = OptionProperty(None, options=[None, 'today'])
date_format = OptionProperty('yyyy-mm-dd', options=[ date_format = OptionProperty('yyyy-mm-dd', options=[k for k in date_format_info.keys() ])
'yyyy-mm-dd',
'dd-mm-yyyy',
'mm-dd-yyyy',
'yyyymmdd',
'mmddyyyy',
'ddmmyyyy']
def __init__(self, allow_copy=True, **kw): def __init__(self, allow_copy=True, **kw):
print('DateInput():kw=', kw) print('DateInput():kw=', kw)
self.datetype = 'yyyy-mm-dd'
kw['size_hint_x'] = None kw['size_hint_x'] = None
kw['width'] = 10 kw['width'] = 10
super(DateInput, self).__init__(**kw) super(DateInput, self).__init__(**kw)
self.register_event_type('on_changed') self.register_event_type('on_changed')
self.old_datestr = None self.old_datestr = None
value = kw.get('value',self.defaultdate()) value = kw.get('value',self.defaultdate())
if value: y, m, d = get_ymd(value, 'yyyy-mm-dd')
y, m, d = self.str2ymd(value)
else:
y, m, d = None, None, None
months_data = [] months_data = []
days_data = [] days_data = []
for i in range(12): for i in range(12):
@ -162,26 +218,13 @@ class DateInput(HBox):
def str2ymd(self, datestr): def str2ymd(self, datestr):
if datestr is None or datestr == '': if datestr is None or datestr == '':
return None, None, None return None, None, None
return get_ymd(datestr, self.dateformat)
if len(datestr) == 8:
self.datetype = 'yyyymmdd'
y = int(datestr[:4])
m = int(datestr[4:6])
d = int(datestr[6:8])
return y, m, d
self.datetype = 'yyyy-mm-dd'
y = int(datestr[:4])
m = int(datestr[5:7])
d = int(datestr[8:10])
return y, m, d
def ymd2str(self, y, m, d): def ymd2str(self, y, m, d):
if y is None: if y is None:
return None return None
if self.datetype == 'yyyymmdd': return get_datestr(y, m, d, self.dateformat)
return '%4d%02d%02d' % (y,m,d)
return '%04d-%02d-%02d' % (y, m, d)
def data_changed(self, o, d): def data_changed(self, o, d):
datestr = None datestr = None

View File

@ -13,10 +13,11 @@ from .ready import WidgetReady
class VResponsiveLayout(WidgetCSS, WidgetReady, ScrollView): class VResponsiveLayout(WidgetCSS, WidgetReady, ScrollView):
box_width = NumericProperty(None) box_width = NumericProperty(None)
box_width_c = NumericProperty(None) box_width_c = NumericProperty(None)
columes = NumericProperty(None)
def __init__(self, **kw): def __init__(self, **kw):
self._inner = None self._inner = None
self.col_width = None self.col_width = None
self.col_width_hint = False self.cols = None
super(VResponsiveLayout, self).__init__(**kw) super(VResponsiveLayout, self).__init__(**kw)
self.options = kw self.options = kw
self._inner = GridLayout(cols=1, padding=2, self._inner = GridLayout(cols=1, padding=2,
@ -26,45 +27,28 @@ class VResponsiveLayout(WidgetCSS, WidgetReady, ScrollView):
super(VResponsiveLayout,self).add_widget(self._inner) super(VResponsiveLayout,self).add_widget(self._inner)
self._inner.bind( self._inner.bind(
minimum_height=self._inner.setter('height')) minimum_height=self._inner.setter('height'))
self.bind(pos=self.set_col_width_cnt,size=self.set_col_width_cnt) self.bind(size=self.set_col_width)
def on_box_width_c(self, *args): def calculate_col_width(self, cnt):
print('on_box_width_c fire......')
if self.box_width_c is None:
return
if self.box_width:
return
if not self._inner:
return
self.col_width = CSize(self.box_width)
self.col_width_hint = False
self.set_col_width_cnt()
def on_box_width(self, *args):
print('on_box_width fire......')
if not self._inner:
return
if self.box_width is None:
return
if self.box_width <= 1:
self.col_width = self.box_width
self.col_width_hint = True
else:
self.col_width = self.box_width
self.col_width_hint = False
self.set_col_width_cnt()
def calculate_col_width(self):
# cnt * col_width + 2*padding + (cnt-1) * spacing = width # cnt * col_width + 2*padding + (cnt-1) * spacing = width
w = self._inner w = self._inner
if len(w.padding) == 1: padding = 0
width = w.width - 2 * w.padding if isinstance(w.padding, float):
return width * self.col_width padding = w.padding
if len(w.padding) == 2: elif len(w.padding) < 4:
width = w.width - 2 * w.padding[0] padding = w.padding[0]
return width * self.col_width else:
width = w.width - w.padding[0] - w.padding[2] padding = (w.padding[0] + w.padding[2])/2
return width * self.col_width spacing = 0
if isinstance(w.spacing, float):
spacing = w.spacing
elif len(w.spacing) < 4:
spacing = w.spacing[0]
else:
spacing = (w.spacing[0] + w.spacing[2]) / 2
print('w.padding=', w.padding, 'w.spacing=', w.spacing, 'padding=', padding)
width = (w.width - 2 * padding - cnt * spacing) / cnt
return width
def get_col_width(self): def get_col_width(self):
return self._inner.col_default_width return self._inner.col_default_width
@ -72,40 +56,42 @@ class VResponsiveLayout(WidgetCSS, WidgetReady, ScrollView):
def get_cols(self): def get_cols(self):
return self._inner.cols return self._inner.cols
def set_col_width(self): def set_col_width(self, o, s):
if self.box_width_c is not None: if self._inner is None:
self.col_width = CSize(self.box_width)
self.col_width_hint = False
return return
self._inner.size = self.size
if isHandHold() and self.width < self.height:
self.cols = 1
self.col_width = self.calculate_col_width(self.cols)
return self.setCols()
if self.columes is not None and self.columes > 0:
self.cols = self.columes
self.col_width = self.calculate_col_width(self.cols)
return self.setCols()
if self.box_width_c is not None:
self.cols = floor(self._inner.width / CSize(self.box_width_c))
if self.cols < 1:
self.cols = 1
self.col_width = self.calculate_col_width(self.cols)
return self.setCols()
if self.box_width is not None: if self.box_width is not None:
if self.box_width <= 1: if self.box_width <= 1:
self.col_width = self.box_width sef.cols = floor(1 / self.box)
self.col_width_hint = True self.col_width = self.calculate_col_width(self.cols)
return self.setCols()
else: else:
self.col_width = self.box_width self.cols = floor(self._inner.width / self.box_width)
self.col_width_hint = False if self.cols < 1:
self.cols = 1
self.col_width = self.calculate_col_width(self.cols)
return self.setCols()
return return
def set_col_width_cnt(self, *args):
print('set_col_width_cnt() called .....')
if self.col_width is None:
self.set_col_width()
if self.col_width is None:
return
if self.col_width_hint:
self._inner.col_default_width = \
self.calculate_col_width()
else:
self._inner.col_default_width = self.col_width
self.setCols()
for w in self._inner.children:
w.size_hint_x = None
w.width = self._inner.col_default_width
def on_orientation(self,o): def on_orientation(self,o):
self.set_col_width_cnt() self.set_col_width()
def add_widget(self,widget,**kw): def add_widget(self,widget,**kw):
a = self._inner.add_widget(widget,**kw) a = self._inner.add_widget(widget,**kw)
@ -119,8 +105,9 @@ class VResponsiveLayout(WidgetCSS, WidgetReady, ScrollView):
return a return a
def setCols(self,*args): def setCols(self,*args):
cols = floor(self.width / self._inner.col_default_width) self._inner.cols = self.cols
if cols < 1: self._inner.col_default_width = self.col_width
cols = 1 for w in self._inner.children:
self._inner.cols = cols w.size_hint_x = None
w.width = self._inner.col_default_width

View File

@ -1,22 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from distutils.core import setup try:
from setuptools import setup, find_packages from setuptools import setup
except ImportError:
from distutils.core import setup
from Cython.Build import cythonize from Cython.Build import cythonize
from version import version
# usage: # usage:
# python setup.py bdist_wininst generate a window executable file # python setup.py bdist_wininst generate a window executable file
# python setup.py bdist_egg generate a egg file # python setup.py bdist_egg generate a egg file
# Release information about eway # Release information about eway
# version = "0.0.4" version = "0.1.1"
description = "kivy blocks is a tool to build kivy ui with json format uidesc files" description = "kivy blocks is a tool to build kivy ui with json format uidesc files"
author = "yumoqing" author = "yumoqing"
email = "yumoqing@icloud.com" email = "yumoqing@icloud.com"
packages=find_packages()
package_data = { package_data = {
"kivyblocks":[ "kivyblocks":[
"blocks.pyx", "blocks.pyx",
@ -52,7 +52,14 @@ setup(
"appPublic", "appPublic",
"sqlor" "sqlor"
], ],
packages=packages, packages=[
'kivyblocks',
'kivyblocks.image_processing',
'kivyblocks.mapview',
'kivyblocks.uitype',
'kivyblocks.widgetExt',
'kivyblocks.xcamera'
],
package_data=package_data, package_data=package_data,
keywords = [ keywords = [
], ],

View File

@ -1 +1 @@
version = '0.0.5' version = '0.1.0'