This commit is contained in:
yumoqing 2021-12-20 15:56:31 +08:00
parent c0c749f66c
commit ad2cf5ca73
5 changed files with 175 additions and 237 deletions

View File

@ -74,7 +74,7 @@ from .threadcall import HttpClient
from .i18n import I18n from .i18n import I18n
from .widget_css import WidgetCSS from .widget_css import WidgetCSS
from .ready import WidgetReady from .ready import WidgetReady
from .utils import CSize, kwarg_pop from .utils import CSize, SUPER
from .swipebehavior import SwipeBehavior from .swipebehavior import SwipeBehavior
if platform == 'android': if platform == 'android':
@ -90,8 +90,7 @@ class WrapText(Label):
class Box(WidgetCSS, WidgetReady, BoxLayout): class Box(WidgetCSS, WidgetReady, BoxLayout):
def __init__(self, **kw): def __init__(self, **kw):
try: try:
kwarg_pop(self, kw) SUPER(Box, self, kw)
super(Box, self).__init__(**kw)
except Exception as e: except Exception as e:
print('Box(',kw,') Error') print('Box(',kw,') Error')
raise e raise e
@ -109,8 +108,7 @@ class VBox(Box):
class SwipeBox(SwipeBehavior, Box): class SwipeBox(SwipeBehavior, Box):
def __init__(self, **kw): def __init__(self, **kw):
kwarg_pop(self, kw) SUPER(SwipeBox, self, kw)
super(SwipeBox, self).__init__(**kw)
class Text(Label): class Text(Label):
@ -140,12 +138,13 @@ class Text(Label):
pass pass
else: else:
kwargs.update(fontsize) kwargs.update(fontsize)
kwarg_pop(self, kwargs) if not kwargs.get('text'):
super().__init__(**kwargs) kwargs['text'] = kwargs.get('otext','')
SUPER(Text, self, kwargs)
if self._i18n: if self._i18n:
self.i18n = I18n() self.i18n = I18n()
self.i18n.addI18nWidget(self) self.i18n.addI18nWidget(self)
self.otext = kw.get('text','')
if self.wrap: if self.wrap:
self.size_hint_y = None self.size_hint_y = None
self.text_size = self.width, None self.text_size = self.width, None
@ -182,9 +181,9 @@ class Text(Label):
def on_otext(self,o,v=None): def on_otext(self,o,v=None):
if self._i18n: if self._i18n:
self.text = self.i18n(v) self.text = self.i18n(self.otext)
else: else:
self.text = v self.text = self.otext
def changeLang(self,lang): def changeLang(self,lang):
self.lang = lang self.lang = lang

View File

@ -10,26 +10,25 @@ from kivy.properties import NumericProperty, DictProperty, \
from kivyblocks.ready import WidgetReady from kivyblocks.ready import WidgetReady
from kivyblocks.bgcolorbehavior import BGColorBehavior from kivyblocks.bgcolorbehavior import BGColorBehavior
from kivyblocks.utils import CSize, kwarg_pop from kivyblocks.utils import CSize, SUPER
from kivyblocks.baseWidget import Box, Text from kivyblocks.baseWidget import Box, Text
from kivyblocks.widget_css import WidgetCSS from kivyblocks.widget_css import WidgetCSS
class TinyText(Text): class TinyText(Text):
def __init__(self, **kw):
SUPER(TinyText, self, kw)
self.on_texture_size(self, (1,1))
def on_texture_size(self, o, ts): def on_texture_size(self, o, ts):
self._label.refresh()
self.size = self.texture_size self.size = self.texture_size
print('TinyText:texture_size=', self.texture_size) print('TinyText:texture_size=', self.texture_size, 'text=', self.text)
class ClickableBox(TouchRippleButtonBehavior, Box): class ClickableBox(TouchRippleButtonBehavior, Box):
def __init__(self, def __init__(self,
border_width=1, border_width=1,
**kw): **kw):
kwarg_pop(self, kw) SUPER(ClickableBox, self, kw)
super(ClickableBox, self).__init__(
padding=[border_width,
border_width,
border_width,
border_width],
**kw)
self.border_width = border_width self.border_width = border_width
# self.bind(minimum_height=self.setter('height')) # self.bind(minimum_height=self.setter('height'))
# self.bind(minimum_width=self.setter('width')) # self.bind(minimum_width=self.setter('width'))
@ -43,9 +42,8 @@ class ClickableText(ClickableBox):
def __init__(self, **kw): def __init__(self, **kw):
print('ClickableText begin inited') print('ClickableText begin inited')
self.txt_w = None self.txt_w = None
kwarg_pop(self, kw) SUPER(ClickableText, self, kw)
super(ClickableText, self).__init__(**kw) self.txt_w = TinyText(text=self.text,
self.txt_w = TinyText(otext=self.text,
i18n=True, i18n=True,
font_size=CSize(self.fontsize)) font_size=CSize(self.fontsize))
self.txt_w.bind(texture_size=self.reset_size) self.txt_w.bind(texture_size=self.reset_size)
@ -72,8 +70,7 @@ class ClickableIconText(ClickableText):
img_kw = DictProperty({}) img_kw = DictProperty({})
def __init__(self, **kw): def __init__(self, **kw):
self.img_w = None self.img_w = None
kwarg_pop(self, kw) SUPER(ClickableIconText, self, kw)
super(ClickableIconText, self).__init__(**kw)
print('ClickableIconText inited') print('ClickableIconText inited')
def reset_size(self, o, s): def reset_size(self, o, s):
@ -107,8 +104,7 @@ class ToggleText(ClickableText):
css_on = StringProperty('default') css_on = StringProperty('default')
css_off = StringProperty('default') css_off = StringProperty('default')
def __init__(self, **kw): def __init__(self, **kw):
kwarg_pop(self, kw) SUPER(ToggleText, self, kw)
super(ToggleText, self).__init__(**kw)
def toggle(self): def toggle(self):
self.select_state = False if self.select_state else True self.select_state = False if self.select_state else True
@ -143,8 +139,7 @@ class ToggleIconText(ToggleText):
img_kw = DictProperty({}) img_kw = DictProperty({})
def __init__(self, **kw): def __init__(self, **kw):
self.img_w = None self.img_w = None
kwarg_pop(self, kw) SUPER(ToggleIconText, self, kw)
super(ToggleIconText, self).__init__(**kw)
self.source = self.source_off self.source = self.source_off
self.img_w = AsyncImage(source=self.source, **self.img_kw) 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=-1)
@ -172,8 +167,7 @@ class ClickableImage(ClickableBox):
img_kw = DictProperty(None) img_kw = DictProperty(None)
def __init__(self, **kw): def __init__(self, **kw):
self.img_w = None self.img_w = None
kwarg_pop(self, kw) SUPER(ClickableImage, self, kw)
super(ClickableImage, self).__init__(**kw)
self.img_w = AsyncImage(source=self.source, **self.img_kw) self.img_w = AsyncImage(source=self.source, **self.img_kw)
self.add_widget(self.img_w) self.add_widget(self.img_w)
@ -189,8 +183,7 @@ class ToggleImage(ClickableImage):
source_off = StringProperty(None) source_off = StringProperty(None)
select_state = BooleanProperty(False) select_state = BooleanProperty(False)
def __init__(self, **kw): def __init__(self, **kw):
kwarg_pop(self, kw) SUPER(ToggleImage, self, kw)
super(ToggleImage, self).__init__(**kw)
self.source = self.source_on self.source = self.source_on
def toggle(self): def toggle(self):

View File

@ -11,10 +11,9 @@ class ScrollPanel(ScrollView):
x_padding_c = NumericProperty(0) x_padding_c = NumericProperty(0)
y_padding_c = NumericProperty(0) y_padding_c = NumericProperty(0)
bgcolor = ListProperty([0.2, 0.2, 0.2, 1]) bgcolor = ListProperty([0.2, 0.2, 0.2, 1])
orient = StringProperty('V')
def __init__(self,inner=None, **kw): def __init__(self,inner=None, **kw):
print('ScrollPanel:kw=', kw) print('ScrollPanel:kw=', kw)
super(ScrollPanel,self).__init__(**kw) SUPER(ScrollPanel, self, kw)
self.effect_cls = ScrollEffect self.effect_cls = ScrollEffect
if not inner: if not inner:
kw = { kw = {
@ -29,11 +28,6 @@ class ScrollPanel(ScrollView):
if not self._inner: if not self._inner:
print('desc=', desc) print('desc=', desc)
raise Exception('widget build failed') raise Exception('widget build failed')
if isinstance(self._inner, BoxLayout):
if self.orient.upper() == 'H':
self._inner.orientation = 'horizontal'
else:
self._inner.orientation = 'vertical'
self._inner.padding = self._inner.spacing = \ self._inner.padding = self._inner.spacing = \
[CSize(self.x_padding_c), CSize(self.y_padding_c)] [CSize(self.x_padding_c), CSize(self.y_padding_c)]
elif isinstance(inner, Widget): elif isinstance(inner, Widget):

View File

@ -23,115 +23,6 @@ from .baseWidget import Text, Box
from .scrollpanel import ScrollPanel from .scrollpanel import ScrollPanel
from .toggleitems import ToggleItems from .toggleitems import ToggleItems
"""
toolbar options
{
radius:
"mode":"icon", "icontext","text"
img_size=1.5,
text_size=0.5,
tools:[
{
"name":"myid",
"img_src":"gggggg",
"label":"gggggg"
},
...
]
}
"""
class Toolbar(Box):
def __init__(self,
radius=[],
img_size=1.5,
text_size=0.5,
tools=[],
normal_css="default",
actived_css="default",
**opts):
self.radius = radius
self.img_size = img_size
self.text_size = text_size
self.tools = tools
self.tool_widgets={}
Box.__init__(self, **opts)
self.register_event_type('on_press')
first = True
subs_desc = []
for opt in self.tools:
subwidgets = []
img_src = opt.get('img_src',None)
if img_src:
subwidgets.append({
"widgettype":"AsyncImage",
"options":{
"size_hint_y":None,
"height":CSize(self.img_size),
"source":img_src
}
})
text = opt.get('label', None)
if text:
subwidgets.append({
"widgettype":"Text",
"options":{
"size_hint_y":None,
"i18n":True,
"height":CSize(self.text_size),
"fontsize":CSize(self.text_size),
"otext":text
}
})
desc = {
"widgettype":"VBox",
"options":{
},
"subwidgets":subwidgets,
"data":opt.get('name')
}
subs_desc.append(desc)
self.toggle_items = ToggleItems(
radius=self.radius,
unit_size=self.img_size + self.text_size,
items_desc=subs_desc,
normal_css=normal_css,
actived_css=actived_css,
**opts
)
for ti in self.toggle_items.item_widgets:
ti.widget_id = ti.user_data
self.toggle_items.bind(on_press=self.tool_press)
self.add_widget(self.toggle_items)
def on_press(self, o):
print('on_press(),', o)
def tool_press(self,o,v=None):
self.dispatch('on_press',self.toggle_items.getValue())
"""
Toolpage options
{
img_size:1.5,
text_size:0.7,
tool_at:"left","right","top","bottom",
radius:
"show_name":"default open tool's name"
tools:[
{
"name":"myid",
"img_src":"gggggg",
"label":"gggggg"
"fresh":true
"url":"ggggggggg"
"rfname":"register_function_name"
},
...
]
"""
class ScrollToolbar(ScrollPanel): class ScrollToolbar(ScrollPanel):
""" """
tool has the follow attributes tool has the follow attributes
@ -139,111 +30,134 @@ class ScrollToolbar(ScrollPanel):
"name", "name",
"source_on, "source_on,
"source_off, "source_off,
# source_on, source_off, or "img_src",
"label", "label",
"deletable"
"url",
"rfname",
} }
toolbar has follow attributes toolbar has follow attributes
{ {
"padding_c":x spacing "padding_c":x spacing
"img_size_c":image height in charecter size "img_size_c":image height in charecter size
"text_size_c": "text_size_c":
"orient":"H" or "V" "toolbar_orient":"H" or "V"
"tool_orient":"horizontal" or "vertical" "tool_orient":"horizontal" or "vertical"
"css_on", "css_on",
"css_off", "css_off",
"tools": "tools":
} }
css_on='default',
css_off='default',
tools=[],
tool_orient = 'horizontal',
orient='H',
padding_c=1,
img_size_c=2,
text_size_c=1,
self.css_on = css_on
self.css_off = css_off
self.tools=tools
self.tool_orient = tool_orient
self.orient = orient
self.padding_c = padding_c
self.img_size_c = img_size_c
self.text_size_c = text_size_c
""" """
css_on = StringProperty('default') css_on = StringProperty('default')
css_off = StringProperty('default') css_off = StringProperty('default')
tools = ListProperty([]) tools = ListProperty([])
tool_orient = StringProperty('horizontal') tool_orient = StringProperty('horizontal')
orient = StringProperty('H') toolbar_orient = StringProperty('H')
padding_c = NumericProperty(1) padding_c = NumericProperty(1)
img_size_c = NumericProperty(2) img_size_c = NumericProperty(2)
text_size_c = NumericProperty(1) text_size_c = NumericProperty(1)
def __init__(self, **kw): def __init__(self, **kw):
kwarg_pop(self, kw) SUPER(ScrollToolbar, self, kw)
super(ScrollToolbar, self).__init__(**kw)
self.register_event_type('on_press') self.register_event_type('on_press')
if self.orient == 'H': if self.toolbar_orient == 'H':
self._inner.orientation = 'horizontal' self._inner.orientation = 'horizontal'
else: else:
self._inner.orientation = 'vertical' self._inner.orientation = 'vertical'
self.clear_widgets() self.clear_widgets()
self.w_dic = {} self.w_dic = {}
for t in self.tools: for t in self.tools:
label = t.get('label', t.get('name', None)) self.add_tool(t)
source_on = t.get('source_on', t.get('img_src',None))
source_off = t.get('source_off', t.get('img_src', None))
ToggleIconText = Factory.ToggleIconText
ToggleText = Factory.ToggleText
ToggleImage = Factory.ToggleImage
if label and source_on:
w = ToggleIconText(css_on=self.css_on,
css_off=self.css_off,
text=label,
fontsize=CSize(self.text_size_c),
source_on=source_on,
source_off=source_off,
orientation=self.tool_orient,
img_kw={
"size_hint":(None, None),
"height":CSize(self.img_size_c),
"width":CSize(self.img_size_c)
}
)
elif label:
w = ToggleText(css_on=self.css_on,
css_off=self.css_off,
orientation=self.tool_orient,
fontsize=CSize(self.text_size_c),
text=label)
elif source_on:
w = ToggleImage( source_on=source_on,
source_off=source_off,
orientation=self.tool_orient,
img_kw={
"size_hint":(None, None),
"height":CSize(self.img_size_c),
"width":CSize(self.img_size_c)
}
)
if w:
self.add_widget(w)
self.w_dic[w] = t
w.bind(on_press=self.tool_press)
if self.orient == 'horizontal': self.bar_width = 0
if self.toolbar_orient == 'H':
self.do_scroll_y = False 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 self.size_hint_y = None
if len(self.w_dic.keys()) > 0: if len(self.w_dic.keys()) > 0:
self.height = max([w.height for w in self.w_dic.keys()]) self.height = max([w.height for w in self.w_dic.keys()])
self._inner.spacing = CSize(self.padding_c,0) self._inner.spacing = CSize(self.padding_c,0)
else: else:
self.do_scroll_x = False
self.size_hint_x = None self.size_hint_x = None
self.size_hint_y = 1
if len(self.w_dic.keys()) > 0: if len(self.w_dic.keys()) > 0:
self.width = max([w.width for w in self.w_dic.keys() ]) self.width = max([w.width for w in self.w_dic.keys() ])
self._inner.spacing = CSize(0, self.padding_c) 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))
source_on = t.get('source_on', t.get('img_src',None))
source_off = t.get('source_off', t.get('img_src', None))
ToggleIconText = Factory.ToggleIconText
ToggleText = Factory.ToggleText
ToggleImage = Factory.ToggleImage
if label and source_on:
w = ToggleIconText(css_on=self.css_on,
css_off=self.css_off,
text=label,
size_hint = (None, None),
fontsize=self.text_size_c,
source_on=source_on,
source_off=source_off,
orientation=self.tool_orient,
img_kw={
"size_hint":(None, None),
"height":CSize(self.img_size_c),
"width":CSize(self.img_size_c)
}
)
elif label:
w = ToggleText(css_on=self.css_on,
css_off=self.css_off,
size_hint = (None, None),
orientation=self.tool_orient,
fontsize=CSize(self.text_size_c),
text=label)
elif source_on:
w = ToggleImage( source_on=source_on,
source_off=source_off,
size_hint = (None, None),
orientation=self.tool_orient,
img_kw={
"size_hint":(None, None),
"height":CSize(self.img_size_c),
"width":CSize(self.img_size_c)
}
)
if w:
self.add_widget(w)
self.w_dic[w] = t
w.select(False)
w.bind(size=self.on_children_size)
w.bind(on_press=self.tool_press)
w.bind(minimum_width=w.setter('width'))
w.bind(minimum_height=w.setter('height'))
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)
self.w_dic = {k:v for k,v in self.w_dic.copy().items() \
if k not in m }
def on_press(self, o): def on_press(self, o):
pass pass
@ -263,13 +177,21 @@ class ScrollToolbar(ScrollPanel):
w.select(False) w.select(False)
self.dispatch('on_press', ret_v) self.dispatch('on_press', ret_v)
class ToolPage(BoxLayout): class ToolPage(Box):
"""
ToolPage:
{
toolbar_size:
tool_at
toolbar
}
"""
toolbar_size = NumericProperty(2) toolbar_size = NumericProperty(2)
tool_at = StringProperty('top') tool_at = StringProperty('top')
toolbar = DictProperty({}) toolbar = DictProperty({})
def __init__(self, **kw): def __init__(self, **kw):
print('ToolPage:kw=',kw) print('ToolPage:kw=',kw)
super(ToolPage, self).__init__(**kw) SUPER(ToolPage, self, kw)
if self.tool_at in [ 'top','bottom']: if self.tool_at in [ 'top','bottom']:
self.orientation = 'vertical' self.orientation = 'vertical'
else: else:
@ -283,16 +205,22 @@ class ToolPage(BoxLayout):
name = self.toolbar['tools'][0]['name'] name = self.toolbar['tools'][0]['name']
self.toolbar_w.select(name) self.toolbar_w.select(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()}
def on_size(self,obj,size): def on_size(self,obj,size):
if self.content_w is None: if self.content_w is None:
return return
if self.tool_at in ['top','bottom']: if self.tool_at in ['top','bottom']:
self.toolbar_w.width = self.width self.toolbar_w.size_hint_y = None
self.content_w.width = self.width
self.content_w.height = self.height - self.toolbar_w.height self.content_w.height = self.height - self.toolbar_w.height
else: else:
self.toolbar_w.height = self.height self.toolbar_w.size_hint_x = None
self.content_w.height = self.height
self.content_w.width = self.width - self.toolbar_w.width self.content_w.width = self.width - self.toolbar_w.width
def init(self): def init(self):
@ -318,29 +246,46 @@ class ToolPage(BoxLayout):
b = Factory.Blocks() b = Factory.Blocks()
return b.widgetBuild(desc) return b.widgetBuild(desc)
def print_all(self):
self.print_info(self)
self.print_info(self.toolbar_w)
for w in self.toolbar_w.w_dic.keys():
self.print_info(w)
for c in w.children:
self.print_info(c)
self.print_info(self.content_w)
for c in self.content_w.children:
self.print_info(c)
def print_info(self, o):
print('self.size_hint=', o.__class__, o.size_hint,
'self.x,y=', o.width, o.height)
def on_press_handle(self, o, v): def on_press_handle(self, o, v):
name = v.get('name') name = v.get('name')
fress = v.get('fress') refresh = v.get('refresh', False)
self.print_all()
w = self.content_widgets.get(name) w = self.content_widgets.get(name)
self.content_w.clear_widgets() self.content_w.clear_widgets()
if w is None or fresh: if w and not refresh:
url = v.get('url')
if url:
w = self.build_widget(url)
if w:
self.content_widgets[name] = w
self.content_w.add_widget(w)
return
rfname = v.get('rfname')
if rfname:
rf = RegisterFunction()
f = rf.get(rfname)
if f:
r = f()
if isinstance(r,Widget):
self.content_w.add_widget(r)
return
if w:
self.content_w.add_widget(w) self.content_w.add_widget(w)
return
url = v.get('url')
if url:
w = self.build_widget(url)
if w:
self.content_widgets[name] = w
self.content_w.add_widget(w)
print('w=', w)
return
rfname = v.get('rfname')
if rfname:
rf = RegisterFunction()
f = rf.get(rfname)
if f:
r = f()
if isinstance(r,Widget):
self.content_w.add_widget(r)
Factory.register('ScrollToolbar', ScrollToolbar) Factory.register('ScrollToolbar', ScrollToolbar)
Toolbar = ScrollToolbar

View File

@ -37,6 +37,13 @@ def kwarg_pop(obj, kw):
if hasattr(obj, k): if hasattr(obj, k):
setattr(obj, k, kw.pop(k)) setattr(obj, k, kw.pop(k))
def SUPER(klass, obj, kw):
keys = [ k for k in kw.keys() ]
dic = { k:kw.pop(k) for k in keys if hasattr(obj, k) }
super(klass, obj).__init__(**kw)
for k,v in dic.items():
setattr(obj, k, v)
def blockImage(name): def blockImage(name):
p = os.path.dirname(os.path.abspath(__file__)) p = os.path.dirname(os.path.abspath(__file__))
return os.path.join(p,'imgs',name) return os.path.join(p,'imgs',name)