This commit is contained in:
yumoqing 2022-01-27 11:07:46 +08:00
parent 4e8e183307
commit 4f81e6e8a7
17 changed files with 298 additions and 570 deletions

View File

@ -63,7 +63,7 @@ from .widgetExt.scrollwidget import ScrollWidget
from .widgetExt.binstateimage import BinStateImage from .widgetExt.binstateimage import BinStateImage
from .widgetExt.jsoncodeinput import JsonCodeInput from .widgetExt.jsoncodeinput import JsonCodeInput
from .widgetExt.inputext import FloatInput,IntegerInput, \ from .widgetExt.inputext import FloatInput,IntegerInput, \
StrInput,SelectInput, BoolInput, AmountInput StrInput,SelectInput, BoolInput, Password
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

View File

@ -13,7 +13,7 @@ from kivyblocks.bgcolorbehavior import BGColorBehavior
from kivyblocks.utils import CSize, SUPER, blockImage from kivyblocks.utils import CSize, SUPER, blockImage
from kivyblocks.baseWidget import Box, Text from kivyblocks.baseWidget import Box, Text
from kivyblocks.widget_css import WidgetCSS from kivyblocks.widget_css import WidgetCSS
from kivyblocks.uitype import view_register, input_register, get_value from .uitype.factory import UiFactory, get_value
class TinyText(Text): class TinyText(Text):
def __init__(self, **kw): def __init__(self, **kw):
@ -286,8 +286,7 @@ def build_checkbox(desc, rec=None):
x = SingleCheckBox(select_state=v) x = SingleCheckBox(select_state=v)
return x return x
view_register('checkbox', build_checkbox) UiFactory.register('checkbox', build_checkbox, build_checkbox)
input_register('checkbox', build_checkbox)
r = Factory.register r = Factory.register
r('TinyText', TinyText) r('TinyText', TinyText)

View File

@ -140,7 +140,7 @@ class DateInput(HBox):
self.datetype = 'yyyy-mm-dd' self.datetype = 'yyyy-mm-dd'
y = int(datestr[:4]) y = int(datestr[:4])
m = int(datestr[5:7]) m = int(datestr[5:7])
d = int(datestr[9:10]) d = int(datestr[8:10])
return y, m, d return y, m, d
def ymd2str(self, y, m, d): def ymd2str(self, y, m, d):
@ -175,6 +175,8 @@ class DateInput(HBox):
return None return None
def setValue(self, datestr): def setValue(self, datestr):
if datestr == '':
datestr = curDateString()
self.old_value = datestr self.old_value = datestr
y, m, d = self.str2ymd(datestr) y, m, d = self.str2ymd(datestr)
self.yw.setValue(y) self.yw.setValue(y)

View File

@ -1607,7 +1607,6 @@ static const char __pyx_k_row_id[] = "row_id";
static const char __pyx_k_select[] = "select"; static const char __pyx_k_select[] = "select";
static const char __pyx_k_tailer[] = "tailer"; static const char __pyx_k_tailer[] = "tailer";
static const char __pyx_k_target[] = "target"; static const char __pyx_k_target[] = "target";
static const char __pyx_k_uitype[] = "uitype";
static const char __pyx_k_update[] = "update"; static const char __pyx_k_update[] = "update";
static const char __pyx_k_valign[] = "valign"; static const char __pyx_k_valign[] = "valign";
static const char __pyx_k_Factory[] = "Factory"; static const char __pyx_k_Factory[] = "Factory";
@ -1648,6 +1647,7 @@ static const char __pyx_k_setWidth[] = "setWidth";
static const char __pyx_k_vertical[] = "vertical"; static const char __pyx_k_vertical[] = "vertical";
static const char __pyx_k_BoxLayout[] = "BoxLayout"; static const char __pyx_k_BoxLayout[] = "BoxLayout";
static const char __pyx_k_Rectangle[] = "Rectangle"; static const char __pyx_k_Rectangle[] = "Rectangle";
static const char __pyx_k_UiFactory[] = "UiFactory";
static const char __pyx_k_WidgetCSS[] = "WidgetCSS"; static const char __pyx_k_WidgetCSS[] = "WidgetCSS";
static const char __pyx_k_bar_width[] = "bar_width"; static const char __pyx_k_bar_width[] = "bar_width";
static const char __pyx_k_cell_type[] = "cell_type"; static const char __pyx_k_cell_type[] = "cell_type";
@ -1759,6 +1759,7 @@ static const char __pyx_k_on_scroll_stop[] = "on_scroll_stop";
static const char __pyx_k_row_normal_css[] = "row_normal_css"; static const char __pyx_k_row_normal_css[] = "row_normal_css";
static const char __pyx_k_selected_rowid[] = "selected_rowid"; static const char __pyx_k_selected_rowid[] = "selected_rowid";
static const char __pyx_k_tailer_widgets[] = "tailer_widgets"; static const char __pyx_k_tailer_widgets[] = "tailer_widgets";
static const char __pyx_k_uitype_factory[] = "uitype.factory";
static const char __pyx_k_BGColorBehavior[] = "BGColorBehavior"; static const char __pyx_k_BGColorBehavior[] = "BGColorBehavior";
static const char __pyx_k_Body_delRowById[] = "Body.delRowById"; static const char __pyx_k_Body_delRowById[] = "Body.delRowById";
static const char __pyx_k_Body_getRowData[] = "Body.getRowData"; static const char __pyx_k_Body_getRowData[] = "Body.getRowData";
@ -1935,6 +1936,7 @@ static PyObject *__pyx_n_s_StringProperty;
static PyObject *__pyx_n_s_Text; static PyObject *__pyx_n_s_Text;
static PyObject *__pyx_n_s_TimeCost; static PyObject *__pyx_n_s_TimeCost;
static PyObject *__pyx_n_s_Toolbar; static PyObject *__pyx_n_s_Toolbar;
static PyObject *__pyx_n_s_UiFactory;
static PyObject *__pyx_n_s_VBox; static PyObject *__pyx_n_s_VBox;
static PyObject *__pyx_n_s_WidgetCSS; static PyObject *__pyx_n_s_WidgetCSS;
static PyObject *__pyx_n_s_WidgetReady; static PyObject *__pyx_n_s_WidgetReady;
@ -2171,7 +2173,7 @@ static PyObject *__pyx_n_s_time;
static PyObject *__pyx_n_s_toolbar; static PyObject *__pyx_n_s_toolbar;
static PyObject *__pyx_n_s_toolbar_2; static PyObject *__pyx_n_s_toolbar_2;
static PyObject *__pyx_n_s_txt; static PyObject *__pyx_n_s_txt;
static PyObject *__pyx_n_s_uitype; static PyObject *__pyx_n_s_uitype_factory;
static PyObject *__pyx_n_s_ujson; static PyObject *__pyx_n_s_ujson;
static PyObject *__pyx_n_s_unselect_row; static PyObject *__pyx_n_s_unselect_row;
static PyObject *__pyx_n_s_unselected; static PyObject *__pyx_n_s_unselected;
@ -2937,7 +2939,7 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
* self.cell_type = 'header' * self.cell_type = 'header'
* else: * else:
* self.cell_type = 'data' # <<<<<<<<<<<<<< * self.cell_type = 'data' # <<<<<<<<<<<<<<
* bl = build_view_widget(desc,self.row.row_data) * bl = UiFactory.build_view_widget(desc,self.row.row_data)
* self.colume_name = desc['name'] * self.colume_name = desc['name']
*/ */
/*else*/ { /*else*/ {
@ -2946,43 +2948,46 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
/* "kivyblocks/dg.pyx":72 /* "kivyblocks/dg.pyx":72
* else: * else:
* self.cell_type = 'data' * self.cell_type = 'data'
* bl = build_view_widget(desc,self.row.row_data) # <<<<<<<<<<<<<< * bl = UiFactory.build_view_widget(desc,self.row.row_data) # <<<<<<<<<<<<<<
* self.colume_name = desc['name'] * self.colume_name = desc['name']
* if bl: * if bl:
*/ */
__Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_build_view_widget); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_UiFactory); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4); __Pyx_GOTREF(__pyx_t_4);
__pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_row); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error) __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_build_view_widget); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_1);
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_row_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_row); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_row_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2); __Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_1 = NULL; __pyx_t_4 = NULL;
__pyx_t_7 = 0; __pyx_t_7 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
__pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4); __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
if (likely(__pyx_t_1)) { if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
__Pyx_INCREF(__pyx_t_1); __Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function); __Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_4, function); __Pyx_DECREF_SET(__pyx_t_1, function);
__pyx_t_7 = 1; __pyx_t_7 = 1;
} }
} }
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_4)) { if (PyFunction_Check(__pyx_t_1)) {
PyObject *__pyx_temp[3] = {__pyx_t_1, __pyx_v_desc, __pyx_t_2}; PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_desc, __pyx_t_2};
__pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error) __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_5); __Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else } else
#endif #endif
#if CYTHON_FAST_PYCCALL #if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
PyObject *__pyx_temp[3] = {__pyx_t_1, __pyx_v_desc, __pyx_t_2}; PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_desc, __pyx_t_2};
__pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error) __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_5); __Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else } else
@ -2990,8 +2995,8 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
{ {
__pyx_t_3 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 72, __pyx_L1_error) __pyx_t_3 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_t_3);
if (__pyx_t_1) { if (__pyx_t_4) {
__Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = NULL; __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL;
} }
__Pyx_INCREF(__pyx_v_desc); __Pyx_INCREF(__pyx_v_desc);
__Pyx_GIVEREF(__pyx_v_desc); __Pyx_GIVEREF(__pyx_v_desc);
@ -2999,11 +3004,11 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
__Pyx_GIVEREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_7, __pyx_t_2); PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_7, __pyx_t_2);
__pyx_t_2 = 0; __pyx_t_2 = 0;
__pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error) __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5); __Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
} }
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_bl = __pyx_t_5; __pyx_v_bl = __pyx_t_5;
__pyx_t_5 = 0; __pyx_t_5 = 0;
} }
@ -3011,7 +3016,7 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
/* "kivyblocks/dg.pyx":73 /* "kivyblocks/dg.pyx":73
* self.cell_type = 'data' * self.cell_type = 'data'
* bl = build_view_widget(desc,self.row.row_data) * bl = UiFactory.build_view_widget(desc,self.row.row_data)
* self.colume_name = desc['name'] # <<<<<<<<<<<<<< * self.colume_name = desc['name'] # <<<<<<<<<<<<<<
* if bl: * if bl:
* self.add_widget(bl) * self.add_widget(bl)
@ -3022,7 +3027,7 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
/* "kivyblocks/dg.pyx":74 /* "kivyblocks/dg.pyx":74
* bl = build_view_widget(desc,self.row.row_data) * bl = UiFactory.build_view_widget(desc,self.row.row_data)
* self.colume_name = desc['name'] * self.colume_name = desc['name']
* if bl: # <<<<<<<<<<<<<< * if bl: # <<<<<<<<<<<<<<
* self.add_widget(bl) * self.add_widget(bl)
@ -3038,27 +3043,27 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
* *
* class Row(BoxLayout): * class Row(BoxLayout):
*/ */
__pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_add_widget); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 75, __pyx_L1_error) __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_add_widget); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4); __Pyx_GOTREF(__pyx_t_1);
__pyx_t_3 = NULL; __pyx_t_3 = NULL;
if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
__pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4); __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
if (likely(__pyx_t_3)) { if (likely(__pyx_t_3)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
__Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(__pyx_t_3);
__Pyx_INCREF(function); __Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_4, function); __Pyx_DECREF_SET(__pyx_t_1, function);
} }
} }
__pyx_t_5 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_3, __pyx_v_bl) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_bl); __pyx_t_5 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_v_bl) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_bl);
__Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 75, __pyx_L1_error) if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 75, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5); __Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
/* "kivyblocks/dg.pyx":74 /* "kivyblocks/dg.pyx":74
* bl = build_view_widget(desc,self.row.row_data) * bl = UiFactory.build_view_widget(desc,self.row.row_data)
* self.colume_name = desc['name'] * self.colume_name = desc['name']
* if bl: # <<<<<<<<<<<<<< * if bl: # <<<<<<<<<<<<<<
* self.add_widget(bl) * self.add_widget(bl)
@ -17656,6 +17661,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
{&__pyx_n_s_Text, __pyx_k_Text, sizeof(__pyx_k_Text), 0, 0, 1, 1}, {&__pyx_n_s_Text, __pyx_k_Text, sizeof(__pyx_k_Text), 0, 0, 1, 1},
{&__pyx_n_s_TimeCost, __pyx_k_TimeCost, sizeof(__pyx_k_TimeCost), 0, 0, 1, 1}, {&__pyx_n_s_TimeCost, __pyx_k_TimeCost, sizeof(__pyx_k_TimeCost), 0, 0, 1, 1},
{&__pyx_n_s_Toolbar, __pyx_k_Toolbar, sizeof(__pyx_k_Toolbar), 0, 0, 1, 1}, {&__pyx_n_s_Toolbar, __pyx_k_Toolbar, sizeof(__pyx_k_Toolbar), 0, 0, 1, 1},
{&__pyx_n_s_UiFactory, __pyx_k_UiFactory, sizeof(__pyx_k_UiFactory), 0, 0, 1, 1},
{&__pyx_n_s_VBox, __pyx_k_VBox, sizeof(__pyx_k_VBox), 0, 0, 1, 1}, {&__pyx_n_s_VBox, __pyx_k_VBox, sizeof(__pyx_k_VBox), 0, 0, 1, 1},
{&__pyx_n_s_WidgetCSS, __pyx_k_WidgetCSS, sizeof(__pyx_k_WidgetCSS), 0, 0, 1, 1}, {&__pyx_n_s_WidgetCSS, __pyx_k_WidgetCSS, sizeof(__pyx_k_WidgetCSS), 0, 0, 1, 1},
{&__pyx_n_s_WidgetReady, __pyx_k_WidgetReady, sizeof(__pyx_k_WidgetReady), 0, 0, 1, 1}, {&__pyx_n_s_WidgetReady, __pyx_k_WidgetReady, sizeof(__pyx_k_WidgetReady), 0, 0, 1, 1},
@ -17892,7 +17898,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
{&__pyx_n_s_toolbar, __pyx_k_toolbar, sizeof(__pyx_k_toolbar), 0, 0, 1, 1}, {&__pyx_n_s_toolbar, __pyx_k_toolbar, sizeof(__pyx_k_toolbar), 0, 0, 1, 1},
{&__pyx_n_s_toolbar_2, __pyx_k_toolbar_2, sizeof(__pyx_k_toolbar_2), 0, 0, 1, 1}, {&__pyx_n_s_toolbar_2, __pyx_k_toolbar_2, sizeof(__pyx_k_toolbar_2), 0, 0, 1, 1},
{&__pyx_n_s_txt, __pyx_k_txt, sizeof(__pyx_k_txt), 0, 0, 1, 1}, {&__pyx_n_s_txt, __pyx_k_txt, sizeof(__pyx_k_txt), 0, 0, 1, 1},
{&__pyx_n_s_uitype, __pyx_k_uitype, sizeof(__pyx_k_uitype), 0, 0, 1, 1}, {&__pyx_n_s_uitype_factory, __pyx_k_uitype_factory, sizeof(__pyx_k_uitype_factory), 0, 0, 1, 1},
{&__pyx_n_s_ujson, __pyx_k_ujson, sizeof(__pyx_k_ujson), 0, 0, 1, 1}, {&__pyx_n_s_ujson, __pyx_k_ujson, sizeof(__pyx_k_ujson), 0, 0, 1, 1},
{&__pyx_n_s_unselect_row, __pyx_k_unselect_row, sizeof(__pyx_k_unselect_row), 0, 0, 1, 1}, {&__pyx_n_s_unselect_row, __pyx_k_unselect_row, sizeof(__pyx_k_unselect_row), 0, 0, 1, 1},
{&__pyx_n_s_unselected, __pyx_k_unselected, sizeof(__pyx_k_unselected), 0, 0, 1, 1}, {&__pyx_n_s_unselected, __pyx_k_unselected, sizeof(__pyx_k_unselected), 0, 0, 1, 1},
@ -19608,7 +19614,7 @@ if (!__Pyx_RefNanny) {
* from .toolbar import Toolbar * from .toolbar import Toolbar
* from .bgcolorbehavior import BGColorBehavior # <<<<<<<<<<<<<< * from .bgcolorbehavior import BGColorBehavior # <<<<<<<<<<<<<<
* from .widget_css import WidgetCSS * from .widget_css import WidgetCSS
* from .uitype import build_view_widget * from .uitype.factory import UiFactory
*/ */
__pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_1);
@ -19628,7 +19634,7 @@ if (!__Pyx_RefNanny) {
* from .toolbar import Toolbar * from .toolbar import Toolbar
* from .bgcolorbehavior import BGColorBehavior * from .bgcolorbehavior import BGColorBehavior
* from .widget_css import WidgetCSS # <<<<<<<<<<<<<< * from .widget_css import WidgetCSS # <<<<<<<<<<<<<<
* from .uitype import build_view_widget * from .uitype.factory import UiFactory
* *
*/ */
__pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error) __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error)
@ -19648,26 +19654,26 @@ if (!__Pyx_RefNanny) {
/* "kivyblocks/dg.pyx":33 /* "kivyblocks/dg.pyx":33
* from .bgcolorbehavior import BGColorBehavior * from .bgcolorbehavior import BGColorBehavior
* from .widget_css import WidgetCSS * from .widget_css import WidgetCSS
* from .uitype import build_view_widget # <<<<<<<<<<<<<< * from .uitype.factory import UiFactory # <<<<<<<<<<<<<<
* *
* class BLabel(ButtonBehavior, Text): * class BLabel(ButtonBehavior, Text):
*/ */
__pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_1);
__Pyx_INCREF(__pyx_n_s_build_view_widget); __Pyx_INCREF(__pyx_n_s_UiFactory);
__Pyx_GIVEREF(__pyx_n_s_build_view_widget); __Pyx_GIVEREF(__pyx_n_s_UiFactory);
PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_build_view_widget); PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_UiFactory);
__pyx_t_2 = __Pyx_Import(__pyx_n_s_uitype, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __pyx_t_2 = __Pyx_Import(__pyx_n_s_uitype_factory, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2); __Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_build_view_widget); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_UiFactory); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_build_view_widget, __pyx_t_1) < 0) __PYX_ERR(0, 33, __pyx_L1_error) if (PyDict_SetItem(__pyx_d, __pyx_n_s_UiFactory, __pyx_t_1) < 0) __PYX_ERR(0, 33, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* "kivyblocks/dg.pyx":35 /* "kivyblocks/dg.pyx":35
* from .uitype import build_view_widget * from .uitype.factory import UiFactory
* *
* class BLabel(ButtonBehavior, Text): # <<<<<<<<<<<<<< * class BLabel(ButtonBehavior, Text): # <<<<<<<<<<<<<<
* def __init__(self, **kw): * def __init__(self, **kw):
@ -19703,7 +19709,7 @@ if (!__Pyx_RefNanny) {
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
/* "kivyblocks/dg.pyx":35 /* "kivyblocks/dg.pyx":35
* from .uitype import build_view_widget * from .uitype.factory import UiFactory
* *
* class BLabel(ButtonBehavior, Text): # <<<<<<<<<<<<<< * class BLabel(ButtonBehavior, Text): # <<<<<<<<<<<<<<
* def __init__(self, **kw): * def __init__(self, **kw):

View File

@ -30,7 +30,7 @@ from .ready import WidgetReady
from .toolbar import Toolbar from .toolbar import Toolbar
from .bgcolorbehavior import BGColorBehavior from .bgcolorbehavior import BGColorBehavior
from .widget_css import WidgetCSS from .widget_css import WidgetCSS
from .uitype import build_view_widget from .uitype.factory import UiFactory
class BLabel(ButtonBehavior, Text): class BLabel(ButtonBehavior, Text):
def __init__(self, **kw): def __init__(self, **kw):
@ -69,7 +69,7 @@ class Cell(ButtonBehavior, WidgetCSS, BoxLayout):
self.cell_type = 'header' self.cell_type = 'header'
else: else:
self.cell_type = 'data' self.cell_type = 'data'
bl = build_view_widget(desc,self.row.row_data) bl = UiFactory.build_view_widget(desc,self.row.row_data)
self.colume_name = desc['name'] self.colume_name = desc['name']
if bl: if bl:
self.add_widget(bl) self.add_widget(bl)

View File

@ -1,9 +1,11 @@
from math import floor
from kivy.factory import Factory from kivy.factory import Factory
from kivy.properties import NumericProperty, StringProperty, \ from kivy.properties import NumericProperty, StringProperty, \
DictProperty, ListProperty, OptionProperty, BooleanProperty DictProperty, ListProperty, OptionProperty, BooleanProperty
from kivy.logger import Logger from kivy.logger import Logger
from kivy.uix.textinput import TextInput from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
from kivy.core.window import Window from kivy.core.window import Window
from kivy.graphics import Color from kivy.graphics import Color
from .responsivelayout import VResponsiveLayout from .responsivelayout import VResponsiveLayout
@ -16,7 +18,7 @@ from .dataloader import DataGraber
from .ready import WidgetReady from .ready import WidgetReady
from .widget_css import WidgetCSS from .widget_css import WidgetCSS
from .dateinput import DateInput from .dateinput import DateInput
from .uitype import get_input_builder from .uitype.factory import UiFactory # import get_input_builder
""" """
form options form options
@ -58,7 +60,6 @@ class InputBox(BoxLayout):
self.options = options self.options = options
self.uitype = options.get('uitype',options.get('datatype','str')) self.uitype = options.get('uitype',options.get('datatype','str'))
self.size_hint = (None, None) self.size_hint = (None, None)
width = self.form.inputwidth
height = self.form.inputheight height = self.form.inputheight
if self.uitype == 'text': if self.uitype == 'text':
if not options.get('height'): if not options.get('height'):
@ -74,16 +75,21 @@ class InputBox(BoxLayout):
else: else:
kwargs['size_hint_y'] = None kwargs['size_hint_y'] = None
kwargs['height'] = CSize(height) kwargs['height'] = CSize(height)
if width <= 1: if self.form.input_width <= 1:
kwargs['size_hint_x'] = width kwargs['size_hint_x'] = self.form.input_width
else: else:
kwargs['size_hint_x'] = None kwargs['size_hint_x'] = None
kwargs['width'] = CSize(width) kwargs['width'] = self.form.input_width
super().__init__(**kwargs) super().__init__(**kwargs)
self.initflag = False self.initflag = False
self.bind(size=self.setSize,
pos=self.setSize)
self.register_event_type("on_datainput") self.register_event_type("on_datainput")
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')
def on_size(self, *args): def on_size(self, *args):
if self.input_widget is None: if self.input_widget is None:
@ -97,6 +103,10 @@ class InputBox(BoxLayout):
self.input_widget.size_hint_x = None self.input_widget.size_hint_x = None
self.input_widget.width = self.width - self.labeltext.width - CSize(1) 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): def on_datainput(self,o,v=None):
print('on_datainput fired ...',o,v) print('on_datainput fired ...',o,v)
@ -104,44 +114,42 @@ class InputBox(BoxLayout):
if self.initflag: if self.initflag:
return return
i18n = I18n() i18n = I18n()
opts = {
"orientation":"horizontal",
"size_hint_y":None,
"height":CSize(self.form.inputheight)
}
if self.form.inputwidth > 1:
opts['size_hint_x'] = None
opts['width'] = CSize(self.form.inputwidth)
else:
opts['size_hint_x'] = self.form.inputwidth
bl = BoxLayout(**opts)
self.add_widget(bl)
label = self.options.get('label',self.options.get('name')) label = self.options.get('label',self.options.get('name'))
kwargs = { kwargs = {
"i18n":True, "i18n":True,
"otext":label, "otext":label,
"font_size":CSize(1), "font_size":CSize(1),
} }
if self.form.labelwidth < 1: if self.form.labelwidth <= 1:
kwargs['size_hint_x'] = self.form.labelwidth kwargs['size_hint_x'] = self.form.labelwidth
else: else:
kwargs['size_hint_x'] = None kwargs['size_hint_x'] = None
kwargs['width'] = CSize(self.form.labelwidth) kwargs['width'] = CSize(self.form.labelwidth)
self.labeltext = Text(**kwargs) self.labeltext = Text(**kwargs)
bl.add_widget(self.labeltext) self.add_widget(self.labeltext)
if self.options.get('required',False): if self.options.get('required',False):
star = Label(text='*', star = Label(text='*',
color=(1,0,0,1), color=(1,0,0,1),
size_hint_x=None, size_hint_x=None,
width=CSize(1)) width=CSize(1))
bl.add_widget(star) self.add_widget(star)
options = self.options.copy() options = self.options.copy()
options['hint_text'] = i18n(self.options.get('hint_text')) options['hint_text'] = i18n(self.options.get('hint_text'))
f = get_input_builder(self.uitype) options['size_hint_y'] = None
self.input_widget = f(options) 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:
pass
self.input_widget.height = self.height
self.input_widget.size_hint_y = None
if self.form.labelwidth < 1: if self.form.labelwidth < 1:
self.input_widget.size_hint_x = 1 - self.form.labelwidth self.input_widget.size_hint_x = 1 - self.form.labelwidth
else: else:
@ -186,9 +194,6 @@ class InputBox(BoxLayout):
if self.old_value != o.text: if self.old_value != o.text:
self.dispatch('on_datainput',o.text) self.dispatch('on_datainput',o.text)
def setSize(self,o,v=None):
self.init()
def setValue(self,v): def setValue(self,v):
self.input_widget.setValue(v) self.input_widget.setValue(v)
@ -225,7 +230,7 @@ def defaultToolbar():
} }
class Form(WidgetCSS, WidgetReady, BoxLayout): class Form(WidgetCSS, WidgetReady, BoxLayout):
cols = NumericProperty(1) cols = NumericProperty(None)
csscls=StringProperty('formcss') csscls=StringProperty('formcss')
input_css=StringProperty('formfieldcss') input_css=StringProperty('formfieldcss')
inputwidth=NumericProperty(1) inputwidth=NumericProperty(1)
@ -239,22 +244,60 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
submit=DictProperty(None) submit=DictProperty(None)
clear=DictProperty(None) clear=DictProperty(None)
notoolbar=BooleanProperty(False) notoolbar=BooleanProperty(False)
def __init__(self, def __init__(self, **options):
**options): self.cols = 1
if self.toolbar_at in ['top','bottom']: if self.toolbar_at in ['top','bottom']:
options['orientation'] = 'vertical' options['orientation'] = 'vertical'
else: else:
options['orientation'] = 'horizontal' options['orientation'] = 'horizontal'
SUPER(Form, self, options) SUPER(Form, self, options)
if self.inputwidth <= 1: self.setup_cols_and_inputwidth()
self.cols = 1
self.options_cols = self.cols
if isHandHold() and Window.width < Window.height:
self.cols = 1
self.options = options
self.init() self.init()
self.register_event_type('on_submit') self.register_event_type('on_submit')
def setup_cols_and_inputwidth(self):
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
if self.inputwidth is None:
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:
self.input_width = self.width
self.fsc.box_width = self.input_width
def on_size(self, *args): def on_size(self, *args):
if not hasattr(self,'fsc'): if not hasattr(self,'fsc'):
return return
@ -269,7 +312,7 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
self.fsc.height = self.height self.fsc.height = self.height
else: else:
self.fsc.width = self.width self.fsc.width = self.width
self.fsc.org_box_width = self.width / self.options_cols self.set_grid_attrs()
def init(self): def init(self):
if not self.notoolbar: if not self.notoolbar:
@ -303,8 +346,7 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
self.toolbar_w = Factory.Toolbar(**desc) self.toolbar_w = Factory.Toolbar(**desc)
self.fsc = VResponsiveLayout( self.fsc = VResponsiveLayout(
self.inputwidth, box_width = self.input_width,
self.cols,
size_hint=(1,1) size_hint=(1,1)
) )

BIN
kivyblocks/imgs/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
kivyblocks/imgs/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -3,11 +3,16 @@ from kivy.factory import Factory
from kivy.properties import StringProperty, NumericProperty from kivy.properties import StringProperty, NumericProperty
from kivy.uix.image import AsyncImage from kivy.uix.image import AsyncImage
from .utils import * from .utils import *
from .baseWidget import Modal, Text, HBox,VBox from .baseWidget import Modal, Text, HBox,VBox, TimedModal
from .widget_css import register_css from .widget_css import register_css
from .clickable import ClickableIconText from .clickable import ClickableIconText
from .toggleitems import PressableBox from .toggleitems import PressableBox
error_default_title_css = {
"bgcolor":[0.88,0,0,1],
"fgcolor":[0.12,0.12,0.12,1]
}
conform_default_title_css = { conform_default_title_css = {
"bgcolor":[0.88,0.88,0.88,1], "bgcolor":[0.88,0.88,0.88,1],
"fgcolor":[0.12,0.12,0.12,1] "fgcolor":[0.12,0.12,0.12,1]
@ -28,10 +33,53 @@ cancel_button_default_css = {
} }
register_css('conform_default_title_css', conform_default_title_css) register_css('conform_default_title_css', conform_default_title_css)
register_css('message_default_title_css', conform_default_title_css)
register_css('error_default_title_css', error_default_title_css)
register_css('conform_default_body_css', conform_default_body_css) register_css('conform_default_body_css', conform_default_body_css)
register_css('message_default_body_css', conform_default_body_css)
register_css('conform_button_default_css', conform_button_default_css) register_css('conform_button_default_css', conform_button_default_css)
register_css('cancel_button_default_css', cancel_button_default_css) register_css('cancel_button_default_css', cancel_button_default_css)
class Message(TimedModal):
title = StringProperty(None)
default_title = 'Message'
default_message = 'Message'
title_icon = StringProperty(blockImage('info.png'))
message = StringPrperty(None)
body_css = StringProperty('message_default_body_css')
title_css = StringProperty('message_default_title_css')
def __init__(self, **kw):
SUPER(Message, self, kw)
b = VBox(csscls=self.title_css)
b1 = HBox(size_hint_y=None, height=CSize(2))
b1.add_widget(AsyncImage(source=self.title_icon,
size_hint=[None,None],
height=CSize(1.2),
width=CSize(1.2)))
b1.add_widget(Text(otext=self.title or self.default_title,
font_size=CSize(1.2),
i18n=True,
wrap=True,
halign='left',
valign='center',
))
b.add_widget(b1)
b2 = HBox(csscls=self.body_css)
b2.add_widget(Text(text=self.message or self.default_message,
i18n=True,
wrap=True,
halign='left',
size_hint=(1,1),
font_size=CSize(1)))
b.add_widget(b2)
self.add_widget(b)
class Error(Message):
default_title = 'Error'
default_message = 'Error message'
title_icon = StringProperty(blockImage('error.png'))
title_css = StringProperty('error_default_title_css')
class Conform(Modal): class Conform(Modal):
title = StringProperty(None) title = StringProperty(None)
title_icon = StringProperty(None) title_icon = StringProperty(None)

View File

@ -3,11 +3,13 @@ from kivy.uix.label import Label
from kivy.properties import NumericProperty, ColorProperty from kivy.properties import NumericProperty, ColorProperty
from kivy.factory import Factory from kivy.factory import Factory
from kivyblocks.uitype import view_register, get_value from .baseWidget import FloatInput
from .uitype.factory import UiFactory, get_value
class PriceView(Label): class PriceView(Label):
dec = NumericProperty(4) dec = NumericProperty(4)
old_price = NumericProperty(None) compare_price = NumericProperty(None)
price = NumericProperty(None) price = NumericProperty(None)
nor_color = ColorProperty([0.9,0.9,0.9,1]) # white nor_color = ColorProperty([0.9,0.9,0.9,1]) # white
inc_color = ColorProperty([0.9,0,0,1]) # red inc_color = ColorProperty([0.9,0,0,1]) # red
@ -15,7 +17,9 @@ class PriceView(Label):
def __init__(self, **kw): def __init__(self, **kw):
super(PriceView, self).__init__(text='', **kw) super(PriceView, self).__init__(text='', **kw)
def on_price(self, price): def on_compare_price(self, *args):
self.on_price()
def on_price(self, *args):
if self.price is None: if self.price is None:
return return
if not isinstance(self.price, float) and \ if not isinstance(self.price, float) and \
@ -23,16 +27,15 @@ class PriceView(Label):
return return
f = '%%.0%df' % self.dec f = '%%.0%df' % self.dec
self.text = f % price self.text = f % self.price
if self.old_price is None: if self.compare_price is None:
self.color = self.nor_color self.color = self.nor_color
elif self.price > self.old_price: elif self.price > self.compare_price:
self.color = self.inc_color self.color = self.inc_color
elif self.price < self.old_price: elif self.price < self.compare_price:
self.color = self.dec_color self.color = self.dec_color
else: else:
self.color = nor_color self.color = nor_color
self.old_price = self.price
def getValue(self): def getValue(self):
return self.price return self.price
@ -40,14 +43,26 @@ class PriceView(Label):
def setValue(self, v): def setValue(self, v):
self.price = v self.price = v
@classmethod
def builder(desc, rec=None):
v = get_value(desc, rec=rec)
return PriceView(price=v,
font_size=CSize(1),
halign='right',
valign='middle'
)
class PriceInput(FloatInput):
@classmethod
def builder(self, desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = PriceInput(**kw)
if v is not None:
w.setValue(v)
return w
Factory.register('PriceView', PriceView) Factory.register('PriceView', PriceView)
def build_view_price_widget(desc, rec=None):
v = get_value(desc, rec=rec)
return Factory.PriceView(price=v,
font_size=CSize(1),
halign='right',
valign='middle'
)
view_register('price', build_view_price_widget) UiFactory.register('price', PriceInput.builder, PriceView.builder)

View File

@ -97,7 +97,6 @@ r('IntegerInput',IntegerInput)
r('StrInput',StrInput) r('StrInput',StrInput)
r('SelectInput',SelectInput) r('SelectInput',SelectInput)
r('BoolInput',BoolInput) r('BoolInput',BoolInput)
r('AmountInput',AmountInput)
r('Messager',Messager) r('Messager',Messager)
r('Bar',Bar) r('Bar',Bar)
r('LoginForm',LoginForm) r('LoginForm',LoginForm)

View File

@ -1,35 +1,42 @@
from math import floor
from kivy.properties import NumericProperty
from kivy.utils import platform from kivy.utils import platform
from kivy.uix.scrollview import ScrollView from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color, Ellipse,Rectangle from kivy.graphics import Color, Ellipse,Rectangle
from kivy.clock import Clock from kivy.clock import Clock
from .utils import CSize, isHandHold from .utils import CSize, isHandHold, show_widget_info
class VResponsiveLayout(ScrollView): class VResponsiveLayout(ScrollView):
def __init__(self,box_width,cols, **kw): box_width = NumericProperty(1)
self.org_box_width = box_width def __init__(self, **kw):
self.org_cols = cols self._inner = None
self.box_width = box_width
self.box_cols = cols
super(VResponsiveLayout, self).__init__(**kw) super(VResponsiveLayout, self).__init__(**kw)
self.options = kw self.options = kw
self._inner = GridLayout(cols=self.org_cols, padding=2, self._inner = GridLayout(cols=1, padding=2,
spacing=2,size_hint=(1,None)) spacing=2,size_hint=(1,None))
self._inner.col_force_default = True
self._inner.col_default_width = self.box_width
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.sizeChangedTask = None self.setCols()
self.bind(pos=self.setCols,size=self.setCols) self.bind(pos=self.setCols,size=self.setCols)
def on_box_width(self, *args):
if not self._inner:
return
self._inner.col_default_width = self.box_width
for w in self._inner.children:
w.size_hint_x = None
w.width = self.box_width
self.setCols()
def on_orientation(self,o): def on_orientation(self,o):
self.setCols() self.setCols()
def add_widget(self,widget,**kw): def add_widget(self,widget,**kw):
width = self.box_width
if hasattr(widget, 'cols'):
width = widget.cols * self.box_width
widget.width = width
a = self._inner.add_widget(widget,**kw) a = self._inner.add_widget(widget,**kw)
return a return a
@ -41,13 +48,13 @@ class VResponsiveLayout(ScrollView):
return a return a
def setCols(self,*args): def setCols(self,*args):
cols = round(self.width / self.org_box_width) cols = floor(self.width / self.box_width)
if cols < 1: if cols < 1:
cols = 1 cols = 1
if isHandHold() and self.width < self.height and self.org_cols >= 2:
cols = 2
box_width = self.width / cols - 2
self._inner.cols = cols self._inner.cols = cols
for w in self._inner.children: #print(self.width, self._inner.width, self.box_width, cols, cols * self.box_width)
w.width = box_width #for c in self.children[:2]:
# show_widget_info(c)
# for c1 in c.children:
# show_widget_info(c1)

View File

@ -155,7 +155,6 @@ class Toolbar(ScrollPanel):
w.bind(on_press=self.tool_press) w.bind(on_press=self.tool_press)
w.bind(minimum_width=w.setter('width')) w.bind(minimum_width=w.setter('width'))
w.bind(minimum_height=w.setter('height')) w.bind(minimum_height=w.setter('height'))
print(w, 'children=', len(w.children))
def delete_tool(self, o): def delete_tool(self, o):
w, t = o.data w, t = o.data

View File

@ -1,374 +0,0 @@
#uitype.py
"""
each ui type need to provides a view widget and a input widget
to auto construct the form widget and record show widget.
we use a register machinans to maintian the ui type information to build the view widget and input widget
"""
import ujson as json
from kivy.factory import Factory
from kivy.properties import NumericProperty, StringProperty, \
BooleanProperty
from kivy.uix.label import Label
from appPublic.myTE import string_template_render
from kivyblocks.utils import CSize
from .baseWidget import WrapText, Text
from .dateinput import DateInput
from .widgetExt.inputext import FloatInput,IntegerInput, \
StrInput,SelectInput, BoolInput, AmountInput, Password
class StringView(Label):
def __init__(self, **kw):
super(StringView, self).__init__(**kw)
self.wrap = True
self.halign = 'left'
self.valign = 'middle'
def getValue(self):
return self.text
def setValue(self, v):
self.text = str(v)
class PasswordView(StringView):
def __init__(self, text='*', **kw):
super(PasswordView, self).__init__(text=text, **kw)
def getValue(self):
return None
def setValue(self, v):
pass
class TextView(WrapText):
def getValue(self):
return self.text
def setValue(self, v):
self.text = v
view_widget_builders = {
}
input_widget_builders = {}
def view_register(uitype, f):
view_widget_builders.update({uitype:f})
def input_register(uitype, f):
input_widget_builders.update({uitype:f})
def get_input_builder(uitype):
return input_widget_builders.get(uitype, \
input_widget_builders.get('str', None))
def get_view_builder(uitype):
return view_widget_builders.get(uitype, \
view_widget_builders.get('str', None))
def build_view_widget(desc, rec = None):
viewer = desc.get('viewer')
if viewer:
if isinstance(viewer,dict):
viewer = json.dumps(viewer)
rendered = string_template_render(viewer, rec)
dic = json.loads(rendered)
if dic is None:
return None
w = Factory.Blocks().widgetBuild(dic)
return w
f = get_view_builder(desc.get('uitype'))
return f(desc, rec)
def build_input_widget(desc, rec=None):
f = get_input_builder(desc.get('uitype'))
return f(desc, rec)
def get_value(desc, rec=None):
if rec:
return rec.get(desc['name'])
return desc.get('value', desc.get('defaultvalue', ''))
def build_view_str_widget(desc, rec=None):
txt = get_value(desc, rec=rec)
return StringView(text=str(txt) if txt else '',
font_size=CSize(1),
halign='left',
valign='middle')
view_register('str', build_view_str_widget)
view_register('date', build_view_str_widget)
view_register('time', build_view_str_widget)
view_register('timestamp', build_view_str_widget)
def build_view_text_widget(desc, rec=None):
txt = get_value(desc, rec=rec)
return TextView(text=str(txt) if txt else '',
font_size=CSize(1),
halign='left',
valign='middle')
view_register('text', build_view_text_widget)
def build_view_passwd_widget(desc, rec=None):
return PasswordView(text='*',
font_size=CSize(1),
halign='left',
valign='middle')
view_register('password', build_view_passwd_widget)
class BoolView(Label):
value = BooleanProperty(False)
def __init__(self, text='', **kw):
super(BoolView, self).__init__(text='', **kw)
self.wrap = True
self.halign = 'center'
self.valign = 'middle'
def on_value(self, *args):
if self.value:
self.text = 'true'
else:
self.text = 'false'
def getValue(self):
return self.value
def setValue(self, v):
self.value = v
def build_view_bool_widget(desc, rec=None):
v = get_value(desc, rec)
if v is not None:
return BoolView(value=v,
font_size=CSize(1),
halign='left',
valign='middle')
default_value = desc.get('nullvalue',False)
return BoolView(value=default_Value,
font_size=CSize(1),
halign='left',
valign='middle')
view_register('bool', build_view_bool_widget)
class IntView(Text):
value = NumericProperty(None)
nullstr = StringProperty('')
def __init__(self, **kw):
super(IntView, self).__init__(text='', **kw)
self.wrap = True
self.halign = 'right'
self.valign = 'middle'
def on_value(self, *args):
if self.value is not None:
self.text = str(v)
else:
self.text = self.nullstr
def setValue(self, v):
self.value = v
def getValue(self):
return self.value
def build_view_int_widget(desc, rec=None):
v = get_value(desc, rec=rec)
return IntValue(value=v,
nullstr=desc.get('nullstr',''),
font_size=CSize(1),
halign='right',
valign='middle'
)
view_register('int', build_view_int_widget)
class FloatView(Text):
value = NumericProperty(None)
nullstr = StringProperty('')
dec = NumericProperty(2)
def __init__(self, **kw):
super(FloatView, self).__init__(text=self.nullstr, **kw)
self.wrap = True
self.halign = 'right'
self.valign = 'middle'
def on_value(self, *args):
if self.value is None:
self.text = self.bullstr
f = '%%.0%df' % self.dec
self.text = f % self.value
def getValue(self):
return self.value
def setValue(self, v):
self.value = v
def build_view_float_widget(desc, rec=None):
v = get_value(desc, rec=rec)
return FloatView(value=v,
dec=desc.get('dec', 2),
nullstr=desc.get('nullstr',''),
font_size=CSize(1),
halign='right',
valign='middle'
)
view_register('float', build_view_float_widget)
def build_view_code_widget(desc, rec=None):
tf = desc.get('textField','text')
vf = desc.get('valueField','value')
v = rec.get(tf,rec.get(vf, ' '))
return Text(text=v,
i18n=True,
font_size = CSize(1),
wrap=True,
halign='center',
valign='middle'
)
view_register('code', build_view_code_widget)
class AmountView(FloatView):
def on_value(self, *args):
if self.value is None:
self.text = self.nullstr
else:
self.text = self.amount_str()
def amount_str(self):
f = '%%.0%df' % self.dec
s = f % self.value
parts = s.split('.')
p_int = parts[0]
subs = []
if p_int[0] == '-':
subs.append('-')
p_int = p_int[1:]
l = [i for i in p_int]
l.reverse()
k = []
for i,c in enumerate(l):
if i and (i) % 3 == 0:
k.append(',')
k.append(c)
k.reverse()
subs.append(''.join(k))
if len(parts) > 1:
subs.append(f'.{parts[1]}')
return ''.join(subs)
def build_view_amount_widget(desc, rec=None):
v = get_value(desc, rec=rec)
defaultvalue = desc.get('nullstr', '')
return Amount(value=v,
dec=desc.get('dec', 2),
nullstr=defaultvale,
font_size=CSize(1),
halign='right',
valign='middle'
)
view_register('amount', build_view_amount_widget)
def build_input_str_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = StrInput(**kw)
if v:
w.setValue(v)
return w
input_register('str', build_input_str_widget)
def build_input_text_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
kw['multiline'] = True
w = StrInput(**kw)
if v:
w.setValue(v)
return w
input_register('text', build_input_text_widget)
def build_input_int_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = IntegerInput(**kw)
if v:
w.setValue(v)
return w
input_register('int', build_input_int_widget)
input_register('time', build_input_int_widget)
def build_input_float_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = FloatInput(**kw)
if v:
w.setValue(v)
return w
input_register('float', build_input_float_widget)
def build_input_amount_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = AmountInput(**kw)
if v:
w.setValue(v)
return w
input_register('amount', build_input_amount_widget)
def build_input_date_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = DateInput(**kw)
if v:
w.setValue(v)
return w
input_register('date', build_input_date_widget)
def build_input_bool_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = BoolInput(**kw)
if v:
w.setValue(v)
return w
input_register('bool', build_input_bool_widget)
def build_input_code_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = SelectInput(**kw)
if v:
w.setValue(v)
return w
input_register('code', build_input_code_widget)
def build_input_password_widget(desc, rec=None):
v = get_value(desc, rec=rec)
kw = desc.get('uiparams', {})
w = Password(**kw)
if v:
w.setValue(v)
return w
input_register('password', build_input_password_widget)

View File

@ -74,6 +74,20 @@ def loading(parent):
view.open() view.open()
return view return view
def set_widget_width(self, width):
if width <= 1:
self.size_hint_x = width
else:
self.size_hint_x = None
self.width = width
def set_widget_height(self, height):
if height <= 1:
self.size_hint_y = height
else:
self.size_hint_y = None
self.height = height
def setSizeOptions(desc,kw): def setSizeOptions(desc,kw):
""" """
desc's width, and height to setup a widget's size options desc's width, and height to setup a widget's size options
@ -217,5 +231,5 @@ def absurl(url,parent):
def show_widget_info(w, tag='DEBUG'): def show_widget_info(w, tag='DEBUG'):
id = getattr(w, 'widget_id', 'null') id = getattr(w, 'widget_id', 'null')
msg=f"""{tag}:size_hint={w.size_hint},size={w.size},pos={w.pos},widget_id={id}""" msg=f"""{tag}:size_hint={w.size_hint},size={w.size},pos={w.pos},widget_id={id},{w}"""
Logger.info(msg) Logger.info(msg)

View File

@ -1,14 +1,13 @@
from kivy.utils import platform from kivy.utils import platform
from .binstateimage import BinStateImage from .binstateimage import BinStateImage
from .jsoncodeinput import JsonCodeInput from .jsoncodeinput import JsonCodeInput
from .inputext import FloatInput,IntegerInput,StrInput,SelectInput, BoolInput, AmountInput, Password from .inputext import FloatInput,IntegerInput,StrInput,SelectInput, BoolInput, Password
from .scrollwidget import ScrollWidget from .scrollwidget import ScrollWidget
from .messager import Messager from .messager import Messager
__all__ = [ __all__ = [
BinStateImage, BinStateImage,
JsonCodeInput, JsonCodeInput,
FloatInput, FloatInput,
AmountInput,
Password, Password,
BoolInput, BoolInput,
IntegerInput, IntegerInput,

View File

@ -10,10 +10,11 @@ from kivy.uix.dropdown import DropDown
from kivy.uix.switch import Switch from kivy.uix.switch import Switch
from kivy.metrics import sp,dp from kivy.metrics import sp,dp
from kivy.app import App from kivy.app import App
from kivy.properties import BooleanProperty, ListProperty from kivy.properties import BooleanProperty, ListProperty, \
NumericProperty
from ..threadcall import HttpClient from ..threadcall import HttpClient
from ..utils import CSize from ..utils import CSize, set_widget_height, set_widget_width
from ..widget_css import WidgetCSS, get_css from ..widget_css import WidgetCSS, get_css
class BoolInput(Switch): class BoolInput(Switch):
@ -34,12 +35,11 @@ class BoolInput(Switch):
def setValue(self,v): def setValue(self,v):
self.active = v self.active = v
class StrInput(TextInput): class StrInput(WidgetCSS, TextInput):
def __init__(self,csscls='default', length = NumericProperty(None)
**kv): def __init__(self, **kv):
if kv is None: if kv is None:
kv = {} kv = {}
css = get_css(csscls)
a = { a = {
"allow_copy":True, "allow_copy":True,
"password":False, "password":False,
@ -51,26 +51,17 @@ class StrInput(TextInput):
"write_tab":False "write_tab":False
} }
a.update(kv) a.update(kv)
a['background_color'] = css['bgcolor']
a['foreground_color'] = css['fgcolor']
w = kv.get('width',1)
h = kv.get('height',1)
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)
super(StrInput, self).__init__(**a) super(StrInput, self).__init__(**a)
self.text = self.old_value = '' self.text = self.old_value = ''
self.register_event_type('on_changed') self.register_event_type('on_changed')
self.bind(on_text_validate=self.checkChange) self.bind(on_text_validate=self.checkChange)
def on_bgcolor(self, *args):
self.background_color = self.bgcolor
def on_fgcolor(self, *args):
self.foreground_color = self.fgcolor
def on_changed(self,v=None): def on_changed(self,v=None):
pass pass
@ -80,6 +71,14 @@ class StrInput(TextInput):
self.old_value = v self.old_value = v
self.dispatch('on_changed',v) self.dispatch('on_changed',v)
def insert_text(self, substring, from_undo=False):
if self.length:
if len(self.text) + len(substring) > self.length:
return None
ret = super().insert_text(substring, from_undo=from_undo)
# ret is None
return ret
def getValue(self): def getValue(self):
return self.text return self.text
@ -89,11 +88,10 @@ class StrInput(TextInput):
self.text = str(v) self.text = str(v)
self.old_value = self.text self.old_value = self.text
class Password(StrInput): class Password(StrInput):
def __init__(self, **kw): def __init__(self, **kw):
kw['password'] = True
super().__init__(**kw) super().__init__(**kw)
self.password = True
class IntegerInput(StrInput): class IntegerInput(StrInput):
def __init__(self,**kw): def __init__(self,**kw):
@ -101,49 +99,23 @@ class IntegerInput(StrInput):
a.update(kw) a.update(kw)
a['halign'] = 'right' a['halign'] = 'right'
super().__init__(**a) super().__init__(**a)
self.input_filter = 'int'
pat = re.compile('[^0-9]')
def insert_text(self, substring, from_undo=False):
pat = self.pat
s = re.sub(pat, '', substring)
return StrInput.insert_text(self,s, from_undo=from_undo)
def on_focus(self,t,v): def on_focus(self,t,v):
self.cursor = (0,len(self.text)) self.cursor = (0,len(self.text))
def getValue(self):
return int(self.text)
class FloatInput(IntegerInput): class FloatInput(IntegerInput):
pat = re.compile('[^0-9]') dec = NumericProperty(2)
def filter(self,substring): def __init__(self,**kw):
pat = self.pat super(FloatInput, self).__init__(**kw)
if '.' in self.text: self.input_filter = 'float'
s = re.sub(pat, '', substring)
else:
s = '.'.join([re.sub(pat, '', s) for s in substring.split('.', 1)])
return s
def insert_text(self, substring, from_undo=False): def getValue(self):
s = self.filter(substring) return float(self.text)
return StrInput.insert_text(self,s, from_undo=from_undo)
class AmountInput(FloatInput):
def filter(self,substring):
s = super(AmountInput,self).filter(substring)
a = s.split('.')
b = a[0]
if len(b)>3:
k = []
while len(b)>3:
x = b[-3:]
k.insert(0,x)
b = b[:-3]
a[0] = ','.join(k)
s = '.'.join(a)
return '.'.join(a)
def insert_text(self, substring, from_undo=False):
s = self.filter(substring)
return StrInput.insert_text(self,s, from_undo=from_undo)
class MyDropDown(DropDown): class MyDropDown(DropDown):
def __init__(self,csscls='input', **kw): def __init__(self,csscls='input', **kw):
super(MyDropDown,self).__init__() super(MyDropDown,self).__init__()