This commit is contained in:
yumoqing 2020-08-21 02:28:14 +08:00
parent 3120174a48
commit f8b2ab4e3e
3 changed files with 74 additions and 98 deletions

View File

@ -5,17 +5,10 @@ from .color_definitions import getColors
_logcnt = 0 _logcnt = 0
class BGColorBehavior(object): class BGColorBehavior(object):
def __init__(self, bgcolor=[],fgcolor=[], color_level=-1,**kwargs): def __init__(self, color_level=-1,**kwargs):
self.color_level = color_level self.color_level = color_level
self.bgcolor = bgcolor self.bgcolor = []
self.fgcolor = fgcolor self.fgcolor = []
self.normal_bgcolor = bgcolor
self.normal_fgcolor = fgcolor
self.selected_bgcolor = bgcolor
self.selected_fgcolor = fgcolor
self.useOwnColor = False
self.useOwnBG = False
self.useOwnFG = False
if color_level != -1: if color_level != -1:
fg,bg= getColors(color_level) fg,bg= getColors(color_level)
self.fgcolor = fg self.fgcolor = fg
@ -26,39 +19,32 @@ class BGColorBehavior(object):
self.selected_bgcolor = bg self.selected_bgcolor = bg
self.selected_fgcolor = fg self.selected_fgcolor = fg
self.useOwnColor = True self.useOwnColor = True
else: self.on_bgcolor()
if bgcolor != [] and fgcolor != []:
self.useOwnColor = True
elif bgcolor != []:
self.useOwnBG = True
elif fgcolor != []:
self.useOwnFG = True
if self.fgcolor!=[]:
self.color = self.fgcolor
self.bind(size=self.onSize_bgcolor_behavior, self.bind(size=self.onSize_bgcolor_behavior,
pos=self.onSize_bgcolor_behavior) pos=self.onSize_bgcolor_behavior)
self.bind(parent=self.useAcestorColor)
self.on_bgcolor()
def useAcestorColor(self,o,v=None): def useAcestorColor(self,selected=False):
if self.useOwnColor:
return
p = self.parent p = self.parent
cnt = 0 cnt = 0
while p: while p:
if isinstance(p,BGColorBehavior): if isinstance(p,BGColorBehavior) and p.useOwnColor:
break if selected:
self.bgcolor = p.selected_bgcolor
self.color = self.fgcolor = p.selected_fgcolor
else:
self.bgcolor = p.normal_bgcolor
self.color = self.fgcolor = p.normal_fgcolor
self.on_bgcolor()
return
p = p.parent p = p.parent
cnt += 1 cnt += 1
if cnt > 100: if cnt > 100:
return break
if not self.useOwnBG and p: fg,bg= getColors(0,selected=selected)
self.bgcolor = p.bgcolor self.bgcolor = bg
self.on_bgcolor() self.color = self.fgcolor = fg
if not self.useOwnFG and p: self.on_bgcolor()
self.fgcolor = p.bgcolor
self.color = self.fgcolor
def onSize_bgcolor_behavior(self,o,v=None): def onSize_bgcolor_behavior(self,o,v=None):
if not hasattr(self,'rect'): if not hasattr(self,'rect'):
@ -77,9 +63,17 @@ class BGColorBehavior(object):
size=self.size) size=self.size)
def selected(self): def selected(self):
self.bgcolor = self.selected_bgcolor if self.useOwnColor:
self.on_bgcolor() self.bgcolor = self.selected_bgcolor
self.color = self.fgcolor = self.selected_fgcolor
self.on_bgcolor()
else:
self.useAcestorColor(selected=True)
def unselected(self): def unselected(self):
self.bgcolor = self.normal_bgcolor if self.useOwnColor:
self.on_bgcolor() self.bgcolor = self.normal_bgcolor
self.color = self.fgcolor = self.normal_fgcolor
self.on_bgcolor()
else:
self.useAcestorColor(selected=False)

View File

@ -32,10 +32,37 @@ from .boxViewer import BoxViewer
from .tree import Tree, TextTree from .tree import Tree, TextTree
from .newvideo import Video from .newvideo import Video
from .qrcodereader import QRCodeReader from .qrcodereader import QRCodeReader
from .ready import WidgetReady
from .bgcolorbehavior import BGColorBehavior
def showError(e): def showError(e):
print('error',e) print('error',e)
def wrap_ready(klass):
try:
w = Factory.get(klass)
if hasattr(w,'ready'):
return w
Factory.unregister(klass)
globals()[klass] = w
except:
w = globals().get(klass)
if w is None:
return None
if hasattr(w,'ready'):
return w
script = f"""class R_{klass}(WidgetReady, {klass}):
def __init__(self, **kw):
{klass}.__init__(self, **kw)
WidgetReady.__init__(self)
"""
exec(script,globals(),globals())
newWidget = globals().get(f'R_{klass}')
Factory.register(klass,newWidget)
return newWidget
class WidgetNotFoundById(Exception): class WidgetNotFoundById(Exception):
def __init__(self, id): def __init__(self, id):
super().__init__() super().__init__()
@ -244,7 +271,7 @@ class Blocks(EventDispatcher):
opts = desc.get('options',{}) opts = desc.get('options',{})
widget = None widget = None
try: try:
klass = Factory.get(widgetClass) klass = wrap_ready(widgetClass)
widget = klass(**opts) widget = klass(**opts)
if desc.get('parenturl'): if desc.get('parenturl'):
widget.parenturl = desc.get('parenturl') widget.parenturl = desc.get('parenturl')
@ -283,8 +310,6 @@ class Blocks(EventDispatcher):
if hasattr(widget,'parenturl'): if hasattr(widget,'parenturl'):
w.parenturl = widget.parenturl w.parenturl = widget.parenturl
widget.add_widget(w) widget.add_widget(w)
if hasattr(widget,'addChild'):
widget.addChild(w)
if bcnt >= btotal: if bcnt >= btotal:
for b in desc.get('binds',[]): for b in desc.get('binds',[]):
self.buildBind(widget,b) self.buildBind(widget,b)
@ -442,6 +467,8 @@ class Blocks(EventDispatcher):
try: try:
widget = self.__build(desc,ancestor=ancestor) widget = self.__build(desc,ancestor=ancestor)
self.dispatch('on_built',widget) self.dispatch('on_built',widget)
if hasattr(widget,'ready'):
widget.ready()
except Exception as e: except Exception as e:
print_exc() print_exc()
doerr(None,e) doerr(None,e)

View File

@ -1,60 +1,15 @@
from kivy.uix.widget import Widget from kivy.event import EventDispatcher
from kivy.properties import BooleanProperty
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
class WidgetReady(Widget): class WidgetReady(EventDispatcher):
ready = BooleanProperty(False) def __init__(self):
kwargs_keys = ['bg_color'] self.register_event_type('on_ready')
def __init__(self, **kw): self._ready = False
self.bg_color = kw.get('bg_color',None)
self.all_ready = {}
self.all_ready[self] = False
self.backgroundcolorTask = None
if self.bg_color is not None:
self.setupBackgroundColor()
def setupBackgroundColor(self): def on_ready(self):
self.bind(pos=self.backgroundcolorfunc) pass
self.bind(size=self.backgroundcolorfunc)
def backgroundcolorfunc(self,o,v):
if self.backgroundcolorTask is not None:
self.backgroundcolorTask.cancel()
self.backgroundcolorTask = Clock.schedule_once(self._setBackgroundColor)
def _setBackgroundColor(self,t=0):
self.canvas.before.clear()
with self.canvas.before:
Color(*self.bg_color)
Rectangle(size=self.size,pos=self.pos)
def addChild(self,w):
"""
need to call addChild to make widget to wait the subwidget on_ready event
w the subwidget of self
"""
if hasattr(w,'ready'):
self.all_ready[w] = False
w.bind(on_ready=self.childReady)
def childReady(self,c,v=None):
self.all_ready[c] = True
if all(self.all_ready.values()):
self.ready = True
def on_ready(self,o,v=None):
print(self,'on_ready')
def built(self):
"""
when self built, call it at end to issue the on_ready event
"""
self.all_ready[self] = True
if all(self.all_ready.values()):
self.ready = True
def setBackgroundColor(self,bgcolor):
self.bg_color = bgcolor
self._setBackgroundColor(0)
def ready(self):
if self._ready:
return
self.dispatch('on_ready')
self._ready = True