bugfix
This commit is contained in:
parent
4e8e183307
commit
4f81e6e8a7
@ -63,7 +63,7 @@ from .widgetExt.scrollwidget import ScrollWidget
|
||||
from .widgetExt.binstateimage import BinStateImage
|
||||
from .widgetExt.jsoncodeinput import JsonCodeInput
|
||||
from .widgetExt.inputext import FloatInput,IntegerInput, \
|
||||
StrInput,SelectInput, BoolInput, AmountInput
|
||||
StrInput,SelectInput, BoolInput, Password
|
||||
from .widgetExt.messager import Messager
|
||||
from .charts.bar import Bar
|
||||
from .bgcolorbehavior import BGColorBehavior
|
||||
|
@ -13,7 +13,7 @@ from kivyblocks.bgcolorbehavior import BGColorBehavior
|
||||
from kivyblocks.utils import CSize, SUPER, blockImage
|
||||
from kivyblocks.baseWidget import Box, Text
|
||||
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):
|
||||
def __init__(self, **kw):
|
||||
@ -286,8 +286,7 @@ def build_checkbox(desc, rec=None):
|
||||
x = SingleCheckBox(select_state=v)
|
||||
return x
|
||||
|
||||
view_register('checkbox', build_checkbox)
|
||||
input_register('checkbox', build_checkbox)
|
||||
UiFactory.register('checkbox', build_checkbox, build_checkbox)
|
||||
|
||||
r = Factory.register
|
||||
r('TinyText', TinyText)
|
||||
|
@ -140,7 +140,7 @@ class DateInput(HBox):
|
||||
self.datetype = 'yyyy-mm-dd'
|
||||
y = int(datestr[:4])
|
||||
m = int(datestr[5:7])
|
||||
d = int(datestr[9:10])
|
||||
d = int(datestr[8:10])
|
||||
return y, m, d
|
||||
|
||||
def ymd2str(self, y, m, d):
|
||||
@ -175,6 +175,8 @@ class DateInput(HBox):
|
||||
return None
|
||||
|
||||
def setValue(self, datestr):
|
||||
if datestr == '':
|
||||
datestr = curDateString()
|
||||
self.old_value = datestr
|
||||
y, m, d = self.str2ymd(datestr)
|
||||
self.yw.setValue(y)
|
||||
|
106
kivyblocks/dg.c
106
kivyblocks/dg.c
@ -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_tailer[] = "tailer";
|
||||
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_valign[] = "valign";
|
||||
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_BoxLayout[] = "BoxLayout";
|
||||
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_bar_width[] = "bar_width";
|
||||
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_selected_rowid[] = "selected_rowid";
|
||||
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_Body_delRowById[] = "Body.delRowById";
|
||||
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_TimeCost;
|
||||
static PyObject *__pyx_n_s_Toolbar;
|
||||
static PyObject *__pyx_n_s_UiFactory;
|
||||
static PyObject *__pyx_n_s_VBox;
|
||||
static PyObject *__pyx_n_s_WidgetCSS;
|
||||
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_2;
|
||||
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_unselect_row;
|
||||
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'
|
||||
* else:
|
||||
* 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']
|
||||
*/
|
||||
/*else*/ {
|
||||
@ -2946,43 +2948,46 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
|
||||
/* "kivyblocks/dg.pyx":72
|
||||
* else:
|
||||
* 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']
|
||||
* 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_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_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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
|
||||
__pyx_t_1 = NULL;
|
||||
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
|
||||
__pyx_t_4 = NULL;
|
||||
__pyx_t_7 = 0;
|
||||
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
|
||||
__pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4);
|
||||
if (likely(__pyx_t_1)) {
|
||||
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
|
||||
__Pyx_INCREF(__pyx_t_1);
|
||||
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
|
||||
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
|
||||
if (likely(__pyx_t_4)) {
|
||||
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
|
||||
__Pyx_INCREF(__pyx_t_4);
|
||||
__Pyx_INCREF(function);
|
||||
__Pyx_DECREF_SET(__pyx_t_4, function);
|
||||
__Pyx_DECREF_SET(__pyx_t_1, function);
|
||||
__pyx_t_7 = 1;
|
||||
}
|
||||
}
|
||||
#if CYTHON_FAST_PYCALL
|
||||
if (PyFunction_Check(__pyx_t_4)) {
|
||||
PyObject *__pyx_temp[3] = {__pyx_t_1, __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_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
|
||||
if (PyFunction_Check(__pyx_t_1)) {
|
||||
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_desc, __pyx_t_2};
|
||||
__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_4); __pyx_t_4 = 0;
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
} else
|
||||
#endif
|
||||
#if CYTHON_FAST_PYCCALL
|
||||
if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
|
||||
PyObject *__pyx_temp[3] = {__pyx_t_1, __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_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
|
||||
if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
|
||||
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_desc, __pyx_t_2};
|
||||
__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_4); __pyx_t_4 = 0;
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
} 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_GOTREF(__pyx_t_3);
|
||||
if (__pyx_t_1) {
|
||||
__Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = NULL;
|
||||
if (__pyx_t_4) {
|
||||
__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_GIVEREF(__pyx_v_desc);
|
||||
@ -2999,11 +3004,11 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
|
||||
__Pyx_GIVEREF(__pyx_t_2);
|
||||
PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_7, __pyx_t_2);
|
||||
__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_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_t_5 = 0;
|
||||
}
|
||||
@ -3011,7 +3016,7 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
|
||||
|
||||
/* "kivyblocks/dg.pyx":73
|
||||
* 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'] # <<<<<<<<<<<<<<
|
||||
* if 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;
|
||||
|
||||
/* "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']
|
||||
* if bl: # <<<<<<<<<<<<<<
|
||||
* self.add_widget(bl)
|
||||
@ -3038,27 +3043,27 @@ static PyObject *__pyx_pf_10kivyblocks_2dg_4Cell___init__(CYTHON_UNUSED PyObject
|
||||
*
|
||||
* 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_GOTREF(__pyx_t_4);
|
||||
__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_1);
|
||||
__pyx_t_3 = NULL;
|
||||
if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
|
||||
__pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
|
||||
if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
|
||||
__pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
|
||||
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(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;
|
||||
if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 75, __pyx_L1_error)
|
||||
__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;
|
||||
|
||||
/* "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']
|
||||
* if 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_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_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_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},
|
||||
@ -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_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_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_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},
|
||||
@ -19608,7 +19614,7 @@ if (!__Pyx_RefNanny) {
|
||||
* from .toolbar import Toolbar
|
||||
* from .bgcolorbehavior import BGColorBehavior # <<<<<<<<<<<<<<
|
||||
* 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_GOTREF(__pyx_t_1);
|
||||
@ -19628,7 +19634,7 @@ if (!__Pyx_RefNanny) {
|
||||
* from .toolbar import Toolbar
|
||||
* from .bgcolorbehavior import BGColorBehavior
|
||||
* 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)
|
||||
@ -19648,26 +19654,26 @@ if (!__Pyx_RefNanny) {
|
||||
/* "kivyblocks/dg.pyx":33
|
||||
* from .bgcolorbehavior import BGColorBehavior
|
||||
* from .widget_css import WidgetCSS
|
||||
* from .uitype import build_view_widget # <<<<<<<<<<<<<<
|
||||
* from .uitype.factory import UiFactory # <<<<<<<<<<<<<<
|
||||
*
|
||||
* class BLabel(ButtonBehavior, Text):
|
||||
*/
|
||||
__pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_1);
|
||||
__Pyx_INCREF(__pyx_n_s_build_view_widget);
|
||||
__Pyx_GIVEREF(__pyx_n_s_build_view_widget);
|
||||
PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_build_view_widget);
|
||||
__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_INCREF(__pyx_n_s_UiFactory);
|
||||
__Pyx_GIVEREF(__pyx_n_s_UiFactory);
|
||||
PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_UiFactory);
|
||||
__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_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);
|
||||
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_2); __pyx_t_2 = 0;
|
||||
|
||||
/* "kivyblocks/dg.pyx":35
|
||||
* from .uitype import build_view_widget
|
||||
* from .uitype.factory import UiFactory
|
||||
*
|
||||
* class BLabel(ButtonBehavior, Text): # <<<<<<<<<<<<<<
|
||||
* def __init__(self, **kw):
|
||||
@ -19703,7 +19709,7 @@ if (!__Pyx_RefNanny) {
|
||||
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
|
||||
|
||||
/* "kivyblocks/dg.pyx":35
|
||||
* from .uitype import build_view_widget
|
||||
* from .uitype.factory import UiFactory
|
||||
*
|
||||
* class BLabel(ButtonBehavior, Text): # <<<<<<<<<<<<<<
|
||||
* def __init__(self, **kw):
|
||||
|
@ -30,7 +30,7 @@ from .ready import WidgetReady
|
||||
from .toolbar import Toolbar
|
||||
from .bgcolorbehavior import BGColorBehavior
|
||||
from .widget_css import WidgetCSS
|
||||
from .uitype import build_view_widget
|
||||
from .uitype.factory import UiFactory
|
||||
|
||||
class BLabel(ButtonBehavior, Text):
|
||||
def __init__(self, **kw):
|
||||
@ -69,7 +69,7 @@ class Cell(ButtonBehavior, WidgetCSS, BoxLayout):
|
||||
self.cell_type = 'header'
|
||||
else:
|
||||
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']
|
||||
if bl:
|
||||
self.add_widget(bl)
|
||||
|
@ -1,9 +1,11 @@
|
||||
from math import floor
|
||||
from kivy.factory import Factory
|
||||
from kivy.properties import NumericProperty, StringProperty, \
|
||||
DictProperty, ListProperty, OptionProperty, BooleanProperty
|
||||
from kivy.logger import Logger
|
||||
from kivy.uix.textinput import TextInput
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.stacklayout import StackLayout
|
||||
from kivy.core.window import Window
|
||||
from kivy.graphics import Color
|
||||
from .responsivelayout import VResponsiveLayout
|
||||
@ -16,7 +18,7 @@ from .dataloader import DataGraber
|
||||
from .ready import WidgetReady
|
||||
from .widget_css import WidgetCSS
|
||||
from .dateinput import DateInput
|
||||
from .uitype import get_input_builder
|
||||
from .uitype.factory import UiFactory # import get_input_builder
|
||||
|
||||
"""
|
||||
form options
|
||||
@ -58,7 +60,6 @@ class InputBox(BoxLayout):
|
||||
self.options = options
|
||||
self.uitype = options.get('uitype',options.get('datatype','str'))
|
||||
self.size_hint = (None, None)
|
||||
width = self.form.inputwidth
|
||||
height = self.form.inputheight
|
||||
if self.uitype == 'text':
|
||||
if not options.get('height'):
|
||||
@ -74,16 +75,21 @@ class InputBox(BoxLayout):
|
||||
else:
|
||||
kwargs['size_hint_y'] = None
|
||||
kwargs['height'] = CSize(height)
|
||||
if width <= 1:
|
||||
kwargs['size_hint_x'] = width
|
||||
if self.form.input_width <= 1:
|
||||
kwargs['size_hint_x'] = self.form.input_width
|
||||
else:
|
||||
kwargs['size_hint_x'] = None
|
||||
kwargs['width'] = CSize(width)
|
||||
kwargs['width'] = self.form.input_width
|
||||
super().__init__(**kwargs)
|
||||
self.initflag = False
|
||||
self.bind(size=self.setSize,
|
||||
pos=self.setSize)
|
||||
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):
|
||||
if self.input_widget is None:
|
||||
@ -97,6 +103,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)
|
||||
|
||||
@ -104,44 +114,42 @@ class InputBox(BoxLayout):
|
||||
if self.initflag:
|
||||
return
|
||||
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'))
|
||||
kwargs = {
|
||||
"i18n":True,
|
||||
"otext":label,
|
||||
"font_size":CSize(1),
|
||||
}
|
||||
if self.form.labelwidth < 1:
|
||||
if self.form.labelwidth <= 1:
|
||||
kwargs['size_hint_x'] = self.form.labelwidth
|
||||
else:
|
||||
kwargs['size_hint_x'] = None
|
||||
kwargs['width'] = CSize(self.form.labelwidth)
|
||||
|
||||
self.labeltext = Text(**kwargs)
|
||||
bl.add_widget(self.labeltext)
|
||||
self.add_widget(self.labeltext)
|
||||
if self.options.get('required',False):
|
||||
star = Label(text='*',
|
||||
color=(1,0,0,1),
|
||||
size_hint_x=None,
|
||||
width=CSize(1))
|
||||
bl.add_widget(star)
|
||||
self.add_widget(star)
|
||||
|
||||
options = self.options.copy()
|
||||
options['hint_text'] = i18n(self.options.get('hint_text'))
|
||||
f = get_input_builder(self.uitype)
|
||||
self.input_widget = f(options)
|
||||
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:
|
||||
pass
|
||||
self.input_widget.height = self.height
|
||||
self.input_widget.size_hint_y = None
|
||||
|
||||
if self.form.labelwidth < 1:
|
||||
self.input_widget.size_hint_x = 1 - self.form.labelwidth
|
||||
else:
|
||||
@ -186,9 +194,6 @@ class InputBox(BoxLayout):
|
||||
if self.old_value != o.text:
|
||||
self.dispatch('on_datainput',o.text)
|
||||
|
||||
def setSize(self,o,v=None):
|
||||
self.init()
|
||||
|
||||
def setValue(self,v):
|
||||
self.input_widget.setValue(v)
|
||||
|
||||
@ -225,7 +230,7 @@ def defaultToolbar():
|
||||
}
|
||||
|
||||
class Form(WidgetCSS, WidgetReady, BoxLayout):
|
||||
cols = NumericProperty(1)
|
||||
cols = NumericProperty(None)
|
||||
csscls=StringProperty('formcss')
|
||||
input_css=StringProperty('formfieldcss')
|
||||
inputwidth=NumericProperty(1)
|
||||
@ -239,22 +244,60 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
|
||||
submit=DictProperty(None)
|
||||
clear=DictProperty(None)
|
||||
notoolbar=BooleanProperty(False)
|
||||
def __init__(self,
|
||||
**options):
|
||||
def __init__(self, **options):
|
||||
self.cols = 1
|
||||
if self.toolbar_at in ['top','bottom']:
|
||||
options['orientation'] = 'vertical'
|
||||
else:
|
||||
options['orientation'] = 'horizontal'
|
||||
SUPER(Form, self, options)
|
||||
if self.inputwidth <= 1:
|
||||
self.cols = 1
|
||||
self.options_cols = self.cols
|
||||
if isHandHold() and Window.width < Window.height:
|
||||
self.cols = 1
|
||||
self.options = options
|
||||
self.setup_cols_and_inputwidth()
|
||||
self.init()
|
||||
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):
|
||||
if not hasattr(self,'fsc'):
|
||||
return
|
||||
@ -269,7 +312,7 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
|
||||
self.fsc.height = self.height
|
||||
else:
|
||||
self.fsc.width = self.width
|
||||
self.fsc.org_box_width = self.width / self.options_cols
|
||||
self.set_grid_attrs()
|
||||
|
||||
def init(self):
|
||||
if not self.notoolbar:
|
||||
@ -303,8 +346,7 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
|
||||
|
||||
self.toolbar_w = Factory.Toolbar(**desc)
|
||||
self.fsc = VResponsiveLayout(
|
||||
self.inputwidth,
|
||||
self.cols,
|
||||
box_width = self.input_width,
|
||||
size_hint=(1,1)
|
||||
)
|
||||
|
||||
|
BIN
kivyblocks/imgs/error.png
Normal file
BIN
kivyblocks/imgs/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
kivyblocks/imgs/info.png
Normal file
BIN
kivyblocks/imgs/info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -3,11 +3,16 @@ from kivy.factory import Factory
|
||||
from kivy.properties import StringProperty, NumericProperty
|
||||
from kivy.uix.image import AsyncImage
|
||||
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 .clickable import ClickableIconText
|
||||
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 = {
|
||||
"bgcolor":[0.88,0.88,0.88,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('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('message_default_body_css', conform_default_body_css)
|
||||
register_css('conform_button_default_css', conform_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):
|
||||
title = StringProperty(None)
|
||||
title_icon = StringProperty(None)
|
||||
|
@ -3,11 +3,13 @@ from kivy.uix.label import Label
|
||||
from kivy.properties import NumericProperty, ColorProperty
|
||||
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):
|
||||
dec = NumericProperty(4)
|
||||
old_price = NumericProperty(None)
|
||||
compare_price = NumericProperty(None)
|
||||
price = NumericProperty(None)
|
||||
nor_color = ColorProperty([0.9,0.9,0.9,1]) # white
|
||||
inc_color = ColorProperty([0.9,0,0,1]) # red
|
||||
@ -15,7 +17,9 @@ class PriceView(Label):
|
||||
def __init__(self, **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:
|
||||
return
|
||||
if not isinstance(self.price, float) and \
|
||||
@ -23,16 +27,15 @@ class PriceView(Label):
|
||||
return
|
||||
|
||||
f = '%%.0%df' % self.dec
|
||||
self.text = f % price
|
||||
if self.old_price is None:
|
||||
self.text = f % self.price
|
||||
if self.compare_price is None:
|
||||
self.color = self.nor_color
|
||||
elif self.price > self.old_price:
|
||||
elif self.price > self.compare_price:
|
||||
self.color = self.inc_color
|
||||
elif self.price < self.old_price:
|
||||
elif self.price < self.compare_price:
|
||||
self.color = self.dec_color
|
||||
else:
|
||||
self.color = nor_color
|
||||
self.old_price = self.price
|
||||
|
||||
def getValue(self):
|
||||
return self.price
|
||||
@ -40,14 +43,26 @@ class PriceView(Label):
|
||||
def setValue(self, 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)
|
||||
|
||||
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)
|
||||
|
@ -97,7 +97,6 @@ r('IntegerInput',IntegerInput)
|
||||
r('StrInput',StrInput)
|
||||
r('SelectInput',SelectInput)
|
||||
r('BoolInput',BoolInput)
|
||||
r('AmountInput',AmountInput)
|
||||
r('Messager',Messager)
|
||||
r('Bar',Bar)
|
||||
r('LoginForm',LoginForm)
|
||||
|
@ -1,35 +1,42 @@
|
||||
|
||||
from math import floor
|
||||
from kivy.properties import NumericProperty
|
||||
from kivy.utils import platform
|
||||
from kivy.uix.scrollview import ScrollView
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.graphics import Color, Ellipse,Rectangle
|
||||
from kivy.clock import Clock
|
||||
from .utils import CSize, isHandHold
|
||||
from .utils import CSize, isHandHold, show_widget_info
|
||||
|
||||
class VResponsiveLayout(ScrollView):
|
||||
def __init__(self,box_width,cols, **kw):
|
||||
self.org_box_width = box_width
|
||||
self.org_cols = cols
|
||||
self.box_width = box_width
|
||||
self.box_cols = cols
|
||||
box_width = NumericProperty(1)
|
||||
def __init__(self, **kw):
|
||||
self._inner = None
|
||||
super(VResponsiveLayout, self).__init__(**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))
|
||||
self._inner.col_force_default = True
|
||||
self._inner.col_default_width = self.box_width
|
||||
super(VResponsiveLayout,self).add_widget(self._inner)
|
||||
self._inner.bind(
|
||||
minimum_height=self._inner.setter('height'))
|
||||
self.sizeChangedTask = None
|
||||
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):
|
||||
self.setCols()
|
||||
|
||||
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)
|
||||
return a
|
||||
|
||||
@ -41,13 +48,13 @@ class VResponsiveLayout(ScrollView):
|
||||
return a
|
||||
|
||||
def setCols(self,*args):
|
||||
cols = round(self.width / self.org_box_width)
|
||||
cols = floor(self.width / self.box_width)
|
||||
if 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
|
||||
for w in self._inner.children:
|
||||
w.width = box_width
|
||||
#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)
|
||||
|
||||
|
@ -155,7 +155,6 @@ class Toolbar(ScrollPanel):
|
||||
w.bind(on_press=self.tool_press)
|
||||
w.bind(minimum_width=w.setter('width'))
|
||||
w.bind(minimum_height=w.setter('height'))
|
||||
print(w, 'children=', len(w.children))
|
||||
|
||||
def delete_tool(self, o):
|
||||
w, t = o.data
|
||||
|
@ -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)
|
||||
|
@ -74,6 +74,20 @@ def loading(parent):
|
||||
view.open()
|
||||
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):
|
||||
"""
|
||||
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'):
|
||||
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)
|
||||
|
@ -1,14 +1,13 @@
|
||||
from kivy.utils import platform
|
||||
from .binstateimage import BinStateImage
|
||||
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 .messager import Messager
|
||||
__all__ = [
|
||||
BinStateImage,
|
||||
JsonCodeInput,
|
||||
FloatInput,
|
||||
AmountInput,
|
||||
Password,
|
||||
BoolInput,
|
||||
IntegerInput,
|
||||
|
@ -10,10 +10,11 @@ from kivy.uix.dropdown import DropDown
|
||||
from kivy.uix.switch import Switch
|
||||
from kivy.metrics import sp,dp
|
||||
from kivy.app import App
|
||||
from kivy.properties import BooleanProperty, ListProperty
|
||||
from kivy.properties import BooleanProperty, ListProperty, \
|
||||
NumericProperty
|
||||
|
||||
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
|
||||
|
||||
class BoolInput(Switch):
|
||||
@ -34,12 +35,11 @@ class BoolInput(Switch):
|
||||
def setValue(self,v):
|
||||
self.active = v
|
||||
|
||||
class StrInput(TextInput):
|
||||
def __init__(self,csscls='default',
|
||||
**kv):
|
||||
class StrInput(WidgetCSS, TextInput):
|
||||
length = NumericProperty(None)
|
||||
def __init__(self, **kv):
|
||||
if kv is None:
|
||||
kv = {}
|
||||
css = get_css(csscls)
|
||||
a = {
|
||||
"allow_copy":True,
|
||||
"password":False,
|
||||
@ -51,26 +51,17 @@ class StrInput(TextInput):
|
||||
"write_tab":False
|
||||
}
|
||||
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)
|
||||
self.text = self.old_value = ''
|
||||
self.register_event_type('on_changed')
|
||||
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):
|
||||
pass
|
||||
|
||||
@ -80,6 +71,14 @@ class StrInput(TextInput):
|
||||
self.old_value = 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):
|
||||
return self.text
|
||||
|
||||
@ -89,11 +88,10 @@ class StrInput(TextInput):
|
||||
self.text = str(v)
|
||||
self.old_value = self.text
|
||||
|
||||
|
||||
class Password(StrInput):
|
||||
def __init__(self, **kw):
|
||||
kw['password'] = True
|
||||
super().__init__(**kw)
|
||||
self.password = True
|
||||
|
||||
class IntegerInput(StrInput):
|
||||
def __init__(self,**kw):
|
||||
@ -101,49 +99,23 @@ class IntegerInput(StrInput):
|
||||
a.update(kw)
|
||||
a['halign'] = 'right'
|
||||
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):
|
||||
self.cursor = (0,len(self.text))
|
||||
|
||||
def getValue(self):
|
||||
return int(self.text)
|
||||
|
||||
class FloatInput(IntegerInput):
|
||||
pat = re.compile('[^0-9]')
|
||||
def filter(self,substring):
|
||||
pat = self.pat
|
||||
if '.' in self.text:
|
||||
s = re.sub(pat, '', substring)
|
||||
else:
|
||||
s = '.'.join([re.sub(pat, '', s) for s in substring.split('.', 1)])
|
||||
return s
|
||||
dec = NumericProperty(2)
|
||||
def __init__(self,**kw):
|
||||
super(FloatInput, self).__init__(**kw)
|
||||
self.input_filter = 'float'
|
||||
|
||||
def insert_text(self, substring, from_undo=False):
|
||||
s = self.filter(substring)
|
||||
return StrInput.insert_text(self,s, from_undo=from_undo)
|
||||
def getValue(self):
|
||||
return float(self.text)
|
||||
|
||||
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):
|
||||
def __init__(self,csscls='input', **kw):
|
||||
super(MyDropDown,self).__init__()
|
||||
|
Loading…
Reference in New Issue
Block a user