This commit is contained in:
yumoqing 2021-12-22 11:25:49 +08:00
parent ad2cf5ca73
commit 4a564de48a
5 changed files with 132 additions and 105 deletions

View File

@ -22,7 +22,6 @@ class TinyText(Text):
def on_texture_size(self, o, ts):
self._label.refresh()
self.size = self.texture_size
print('TinyText:texture_size=', self.texture_size, 'text=', self.text)
class ClickableBox(TouchRippleButtonBehavior, Box):
def __init__(self,
@ -32,6 +31,16 @@ class ClickableBox(TouchRippleButtonBehavior, Box):
self.border_width = border_width
# self.bind(minimum_height=self.setter('height'))
# self.bind(minimum_width=self.setter('width'))
self.bind(children=self.reset_size)
def reset_size(self, o, s):
self.size_hint = (None,None)
if self.orientation == 'horizontal':
self.height = max([c.height for c in self.children])
self.width = sum([c.width for c in self.children])
else:
self.height = sum([c.height for c in self.children])
self.width = max([c.width for c in self.children])
def on_press(self,o=None):
pass
@ -43,23 +52,15 @@ class ClickableText(ClickableBox):
print('ClickableText begin inited')
self.txt_w = None
SUPER(ClickableText, self, kw)
self.txt_w = TinyText(text=self.text,
self.txt_w = TinyText(otext=self.text,
i18n=True,
font_size=CSize(self.fontsize))
self.txt_w.bind(texture_size=self.reset_size)
self.add_widget(self.txt_w)
self.txt_w.size_hint = (None, None)
self.txt_w.size = self.txt_w.texture_size
#self.txt_w.bind(minimum_height=self.txt_w.setter('height'))
#self.txt_w.bind(minimum_width=self.txt_w.setter('width'))
print('ClickableText inited')
def reset_size(self, o, s):
self.size_hint = (None,None)
self.size = self.txt_w.texture_size
def on_text(self, o, txt):
print('on_text fired')
if self.txt_w:
self.txt_w.text = self.text
@ -73,22 +74,12 @@ class ClickableIconText(ClickableText):
SUPER(ClickableIconText, self, kw)
print('ClickableIconText inited')
def reset_size(self, o, s):
self.size_hint = (None,None)
if self.orientation == 'horizontal':
self.height = max(self.txt_w.texture_size[1], self.img_w.height)
self.width = self.txt_w.texture_size[0] + self.img_w.width
else:
self.height = self.txt_w.texture_size[1] + self.img_w.height
self.width = max(self.txt_w.texture_size[0], self.img_w.width)
def on_source(self, o, source):
if self.img_w:
self.img_w.source = source
return
self.img_w = AsyncImage(source=self.source, **self.img_kw)
self.add_widget(self.img_w, index=-1)
self.add_widget(self.img_w, index=len(self.children))
class ToggleText(ClickableText):
"""
@ -142,18 +133,8 @@ class ToggleIconText(ToggleText):
SUPER(ToggleIconText, self, kw)
self.source = self.source_off
self.img_w = AsyncImage(source=self.source, **self.img_kw)
self.add_widget(self.img_w, index=-1)
self.add_widget(self.img_w, index=len(self.children))
def reset_size(self, o, s):
self.size_hint = (None,None)
if self.orientation == 'horizontal':
self.height = max(self.txt_w.texture_size[1], self.img_w.height)
self.width = self.txt_w.texture_size[0] + self.img_w.width
else:
self.height = self.txt_w.texture_size[1] + self.img_w.height
self.width = max(self.txt_w.texture_size[0], self.img_w.width)
print(f'ToggleIconText:w,h={self.width},{self.height}')
def on_select_state(self, o, f):
super(ToggleIconText, self).on_select_state(o,f)
self.source = self.source_on if f else self.source_off
@ -168,12 +149,27 @@ class ClickableImage(ClickableBox):
def __init__(self, **kw):
self.img_w = None
SUPER(ClickableImage, self, kw)
self.img_w = AsyncImage(source=self.source, **self.img_kw)
self.add_widget(self.img_w)
# self.img_w = AsyncImage(source=self.source, **self.img_kw)
# self.add_widget(self.img_w)
def on_source(self, o, source):
if self.source is None:
self.source = blockImage('broken.png')
self.build_widget()
def on_img_kw(self, o, img_kw):
self.build_widget()
def build_widget(self):
if not self.source:
return
if not self.img_kw:
self.img_kw = {}
if self.img_w:
self.img_w.source = source
self.img_w.source = self.source
for k,v in self.img_kw.items():
setattr(self.img_w, k,v)
return
self.img_w = AsyncImage(source=self.source, **self.img_kw)
self.add_widget(self.img_w)
@ -204,8 +200,25 @@ class ToggleImage(ClickableImage):
else:
self.source = self.source_off
class CheckBox(ToggleImage):
otext = StringProperty(None)
def __init__(self, **kw):
SUPER(CheckBox, self, kw)
self.source_on = blockImage('checkbox-on.png')
self.source_off = blockImage('ceckbox-off.png')
if self.otext:
self.txt_w = TinyText(otext=self.otext, i18n=True)
self.add_widget(self.txt_w)
def getValue(self):
return self.state()
def setValue(self, v):
self.select_state = False if v else True
r = Factory.register
r('TinyText', TinyText)
r('CheckBox', CheckBox)
r('ClickableBox', ClickableBox)
r('ClickableText',ClickableText)
r('ClickableIconText',ClickableIconText)

View File

@ -21,7 +21,7 @@ from appPublic.timecost import TimeCost
from appPublic.uniqueID import getID
from appPublic.myTE import string_template_render
from .utils import CSize, setSizeOptions, loading, loaded, absurl, alert
from .utils import CSize, setSizeOptions, loading, loaded, absurl, alert, SUPER
from .baseWidget import Text, HBox, VBox
from .scrollpanel import ScrollPanel
from .paging import Paging, RelatedLoader
@ -166,7 +166,7 @@ class Row(BoxLayout):
class Header(WidgetReady, ScrollPanel):
def __init__(self,part,**kw):
super(Header, self).__init__(**kw)
SUPER(Header, self, kw)
self.part = part
self.init(1)
self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop)
@ -185,8 +185,8 @@ class Header(WidgetReady, ScrollPanel):
class Body(WidgetReady, ScrollPanel):
def __init__(self,part,**kw):
self.part = part
kw.update({'spacing':self.part.datagrid.linewidth})
super(Body, self).__init__(**kw)
SUPER(Body, self, kw)
self._inner.spacing = self.part.datagrid.linewidth
self.size_hint=(1,1)
self.idRow = {}
self.bind(on_scroll_stop=self.part.datagrid.on_scrollstop)
@ -262,6 +262,11 @@ class DataGridPart(WidgetReady, BoxLayout):
if not self.datagrid.noheader:
self.header = Header(self,**kw)
self.add_widget(self.header)
inner = {
"widgettype":"VBox",
"options":{
}
}
self.body = Body(self)
self.add_widget(self.body)
if not self.freeze_flag:
@ -522,6 +527,8 @@ class DataGrid(WidgetReady, BoxLayout):
data['data'] = recs2
f = partial(self.add_page_delay,data)
Clock.schedule_once(f, 0)
print('body=', self.normal_part.body.size,
'inner=', self.normal_part.body._inner.size)
def add_page_delay(self, data, *args):
recs = data['data']

View File

@ -241,8 +241,8 @@ class InputBox(BoxLayout):
def defaultToolbar():
return {
"img_size":1.5,
"text_size":0.7,
"img_size_c":1.5,
"text_size_c":0.7,
"tools":[
{
"name":"__submit",
@ -320,18 +320,6 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
self.fsc.org_box_width = self.width / self.options_cols
if self.notoolbar:
return
if self.toolbar_at in [ 'top', 'bottom' ]:
Logger.info('Form: height:tb:%d,ti:%d,fsc:%d, fm:%d',
self.toolbar.height,
self.toolbar.toggle_items.height,
self.fsc.height, self.height
)
else:
Logger.info('Form: width:tb:%d,ti:%d,fsc:%d, fm:%d',
self.toolbar.width,
self.toolbar.toggle_items.width,
self.fsc.width, self.width
)
def init(self):
if not self.notoolbar:
@ -359,11 +347,13 @@ class Form(WidgetCSS, WidgetReady, BoxLayout):
if self.toolbar_at in ['top', 'bottom']:
desc['orientation'] = 'horizontal'
desc['size_hint_y'] = None
desc['height'] = CSize(desc['img_size'] + desc['text_size'])
desc['height'] = CSize(desc['img_size_c'] + \
desc['text_size_c'])
else:
desc['orientation'] = 'vertical'
desc['size_hint_x'] = None
desc['width'] = CSize(desc['img_size'] + desc['text_size'])
desc['width'] = CSize(desc['img_size_c'] + \
desc['text_size_c'])
self.toolbar = Toolbar(**desc)
self.fsc = VResponsiveLayout(

View File

@ -1,4 +1,5 @@
from kivy.properties import NumericProperty, StringProperty, ListProperty
from kivy.properties import NumericProperty, StringProperty, \
OptionProperty, ListProperty
from kivy.uix.scrollview import ScrollView
from kivy.effects.scroll import ScrollEffect
from kivy.uix.widget import Widget
@ -8,38 +9,41 @@ from kivy.factory import Factory
from kivyblocks.utils import *
class ScrollPanel(ScrollView):
x_padding_c = NumericProperty(0)
y_padding_c = NumericProperty(0)
orientation = OptionProperty('vertical', \
options=['vertical', 'horizontal'])
bgcolor = ListProperty([0.2, 0.2, 0.2, 1])
padding_c = NumericProperty(1)
def __init__(self,inner=None, **kw):
print('ScrollPanel:kw=', kw)
SUPER(ScrollPanel, self, kw)
self.effect_cls = ScrollEffect
if not inner:
kw = {
'size_hint':(None,None),
'bgcolor':self.bgcolor,
}
desc = {
"widgettype":"Box",
"options":kw
}
self._inner = Factory.Blocks().widgetBuild(desc)
if not self._inner:
print('desc=', desc)
raise Exception('widget build failed')
self._inner.padding = self._inner.spacing = \
[CSize(self.x_padding_c), CSize(self.y_padding_c)]
self.create_default_inner()
elif isinstance(inner, Widget):
self._inner = inner
else:
self._inner = Factory.Blocks().widgetBuild(inner)
super(ScrollPanel,self).add_widget(self._inner)
self._inner.bind(
minimum_height=self._inner.setter('height'))
self._inner.bind(
minimum_width=self._inner.setter('width'))
super(ScrollPanel,self).add_widget(self._inner)
def create_default_inner(self):
kw = {
'size_hint':(None,None),
'orientation':self.orientation
}
desc = {
"widgettype":"Box",
"options":kw
}
self._inner = Factory.Blocks().widgetBuild(desc)
self._inner.bgcolor = self.bgcolor
if not self._inner:
print('desc=', desc)
raise Exception('widget build failed')
self._inner.spacing = CSize(self.padding_c)
def add_widget(self,widget,**kw):
a = self._inner.add_widget(widget,**kw)

View File

@ -10,7 +10,7 @@ from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.properties import StringProperty, DictProperty, \
ListProperty, NumericProperty
OptionProperty, ListProperty, NumericProperty
from appPublic.dictObject import DictObject
from appPublic.registerfunction import RegisterFunction
@ -23,7 +23,7 @@ from .baseWidget import Text, Box
from .scrollpanel import ScrollPanel
from .toggleitems import ToggleItems
class ScrollToolbar(ScrollPanel):
class Toolbar(ScrollPanel):
"""
tool has the follow attributes
{
@ -38,7 +38,6 @@ class ScrollToolbar(ScrollPanel):
}
toolbar has follow attributes
{
"padding_c":x spacing
"img_size_c":image height in charecter size
"text_size_c":
"toolbar_orient":"H" or "V"
@ -52,54 +51,44 @@ class ScrollToolbar(ScrollPanel):
css_on = StringProperty('default')
css_off = StringProperty('default')
tools = ListProperty([])
tool_orient = StringProperty('horizontal')
toolbar_orient = StringProperty('H')
padding_c = NumericProperty(1)
tool_orient = OptionProperty('horizontal', \
options=['horizontal', 'vertical'])
toolbar_orient = OptionProperty('H', options=['H', 'V'])
img_size_c = NumericProperty(2)
text_size_c = NumericProperty(1)
def __init__(self, **kw):
SUPER(ScrollToolbar, self, kw)
self.w_dic = {}
SUPER(Toolbar, self, kw)
self.register_event_type('on_press')
self.register_event_type('on_delete_tool')
if self.toolbar_orient == 'H':
self._inner.orientation = 'horizontal'
else:
self._inner.orientation = 'vertical'
self.clear_widgets()
self.w_dic = {}
for t in self.tools:
self.add_tool(t)
self.bar_width = 0
if self.toolbar_orient == 'H':
self.do_scroll_y = False
self._inner.spacing = CSize(self.padding_c,0)
else:
self.do_scroll_x = False
self._inner.spacing = CSize(0, self.padding_c)
def on_children_size(self, o, size):
self.on_size(None, None)
def on_size(self, o, size):
print('on_size=', size)
if self.toolbar_orient == 'H':
self.size_hint_x = 1
self.size_hint_y = None
if len(self.w_dic.keys()) > 0:
self.height = max([w.height for w in self.w_dic.keys()])
self._inner.spacing = CSize(self.padding_c,0)
else:
self.size_hint_x = None
self.size_hint_y = 1
if len(self.w_dic.keys()) > 0:
self.width = max([w.width for w in self.w_dic.keys() ])
self._inner.spacing = CSize(0, self.padding_c)
print('###size_hint=',
self.size_hint_x,
self.size_hint_y,
self.size_hint,
self.size)
def add_tool(self, t):
label = t.get('label', t.get('name', None))
@ -108,6 +97,7 @@ class ScrollToolbar(ScrollPanel):
ToggleIconText = Factory.ToggleIconText
ToggleText = Factory.ToggleText
ToggleImage = Factory.ToggleImage
ClickableImage = Factory.ClickableImage
if label and source_on:
w = ToggleIconText(css_on=self.css_on,
css_off=self.css_off,
@ -142,6 +132,18 @@ class ScrollToolbar(ScrollPanel):
}
)
print(w, 'children=', len(w.children))
if t.get('deletable', False):
x = ClickableImage(source=blockImage('delete.png'),
img_kw={
"size_hint":(None, None),
"size":CSize(1,1)
}
)
x.data = (w, t)
x.bind(on_press=self.delete_tool)
w.add_widget(x)
if w:
self.add_widget(w)
self.w_dic[w] = t
@ -150,13 +152,20 @@ class ScrollToolbar(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 del_tool(self, name):
m = [ x for x,y in self.w_dic.items() if y['name'] == name ]
for w in m:
self.remove(w)
def delete_tool(self, o):
w, t = o.data
self.del_tool(w)
self.dispatch('on_delete_tool', o.data)
def on_delete_tool(self, o, d=None):
pass
def del_tool(self, w):
self.remove_widget(w)
self.w_dic = {k:v for k,v in self.w_dic.copy().items() \
if k not in m }
if k != w }
def on_press(self, o):
pass
@ -187,7 +196,8 @@ class ToolPage(Box):
}
"""
toolbar_size = NumericProperty(2)
tool_at = StringProperty('top')
tool_at = OptionProperty('top', \
options=['top', 'bottom', 'left', 'right'])
toolbar = DictProperty({})
def __init__(self, **kw):
print('ToolPage:kw=',kw)
@ -202,16 +212,20 @@ class ToolPage(Box):
self.content_w = None
self.toolbar_w = None
self.init()
self.toolbar_w.bind(on_delete_tool=self.delete_content_widget)
name = self.toolbar['tools'][0]['name']
self.toolbar_w.select(name)
def delete_content_widget(self, o, d):
w, dic = d
self.del_tool(dic['name'])
def add_tool(self, tool):
self.toolbar_w.add_tool(tool)
def del_tool(self, name):
self.toolbar_w.del_tool(o)
g = self.content_widgets.copy()
self.content_widgets = {k:v for k,v in g.items()}
self.content_widgets = {k:v for k,v in g.items() if k!=name}
def on_size(self,obj,size):
if self.content_w is None:
@ -226,7 +240,7 @@ class ToolPage(Box):
def init(self):
self.content_w = BoxLayout()
self.content_w.widget_id = 'content'
self.toolbar_w = ScrollToolbar(**self.toolbar)
self.toolbar_w = Toolbar(**self.toolbar)
if self.tool_at in ['top','left']:
self.add_widget(self.toolbar_w)
self.add_widget(self.content_w)
@ -264,7 +278,8 @@ class ToolPage(Box):
def on_press_handle(self, o, v):
name = v.get('name')
refresh = v.get('refresh', False)
self.print_all()
# self.print_all()
w = self.content_widgets.get(name)
self.content_w.clear_widgets()
if w and not refresh:
@ -287,5 +302,3 @@ class ToolPage(Box):
if isinstance(r,Widget):
self.content_w.add_widget(r)
Factory.register('ScrollToolbar', ScrollToolbar)
Toolbar = ScrollToolbar