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.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

View File

@ -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)

View File

@ -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)

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_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):

View File

@ -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)

View File

@ -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

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.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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

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()
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)

View File

@ -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,

View File

@ -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__()