diff --git a/kivyblocks/bgcolorbehavior.py b/kivyblocks/bgcolorbehavior.py index 55a18e3..d83ec2d 100644 --- a/kivyblocks/bgcolorbehavior.py +++ b/kivyblocks/bgcolorbehavior.py @@ -5,17 +5,10 @@ from .color_definitions import getColors _logcnt = 0 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.bgcolor = bgcolor - self.fgcolor = 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 + self.bgcolor = [] + self.fgcolor = [] if color_level != -1: fg,bg= getColors(color_level) self.fgcolor = fg @@ -26,39 +19,32 @@ class BGColorBehavior(object): self.selected_bgcolor = bg self.selected_fgcolor = fg self.useOwnColor = True - else: - 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.on_bgcolor() + self.bind(size=self.onSize_bgcolor_behavior, pos=self.onSize_bgcolor_behavior) - self.bind(parent=self.useAcestorColor) - self.on_bgcolor() - def useAcestorColor(self,o,v=None): - if self.useOwnColor: - return - + def useAcestorColor(self,selected=False): p = self.parent cnt = 0 while p: - if isinstance(p,BGColorBehavior): - break + if isinstance(p,BGColorBehavior) and p.useOwnColor: + 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 cnt += 1 if cnt > 100: - return - if not self.useOwnBG and p: - self.bgcolor = p.bgcolor - self.on_bgcolor() - if not self.useOwnFG and p: - self.fgcolor = p.bgcolor - self.color = self.fgcolor + break + fg,bg= getColors(0,selected=selected) + self.bgcolor = bg + self.color = self.fgcolor = fg + self.on_bgcolor() def onSize_bgcolor_behavior(self,o,v=None): if not hasattr(self,'rect'): @@ -77,9 +63,17 @@ class BGColorBehavior(object): size=self.size) def selected(self): - self.bgcolor = self.selected_bgcolor - self.on_bgcolor() + if self.useOwnColor: + self.bgcolor = self.selected_bgcolor + self.color = self.fgcolor = self.selected_fgcolor + self.on_bgcolor() + else: + self.useAcestorColor(selected=True) def unselected(self): - self.bgcolor = self.normal_bgcolor - self.on_bgcolor() + if self.useOwnColor: + self.bgcolor = self.normal_bgcolor + self.color = self.fgcolor = self.normal_fgcolor + self.on_bgcolor() + else: + self.useAcestorColor(selected=False) diff --git a/kivyblocks/blocks.py b/kivyblocks/blocks.py index 0cbd64c..3685f94 100755 --- a/kivyblocks/blocks.py +++ b/kivyblocks/blocks.py @@ -32,10 +32,37 @@ from .boxViewer import BoxViewer from .tree import Tree, TextTree from .newvideo import Video from .qrcodereader import QRCodeReader +from .ready import WidgetReady +from .bgcolorbehavior import BGColorBehavior def showError(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): def __init__(self, id): super().__init__() @@ -244,7 +271,7 @@ class Blocks(EventDispatcher): opts = desc.get('options',{}) widget = None try: - klass = Factory.get(widgetClass) + klass = wrap_ready(widgetClass) widget = klass(**opts) if desc.get('parenturl'): widget.parenturl = desc.get('parenturl') @@ -283,8 +310,6 @@ class Blocks(EventDispatcher): if hasattr(widget,'parenturl'): w.parenturl = widget.parenturl widget.add_widget(w) - if hasattr(widget,'addChild'): - widget.addChild(w) if bcnt >= btotal: for b in desc.get('binds',[]): self.buildBind(widget,b) @@ -442,6 +467,8 @@ class Blocks(EventDispatcher): try: widget = self.__build(desc,ancestor=ancestor) self.dispatch('on_built',widget) + if hasattr(widget,'ready'): + widget.ready() except Exception as e: print_exc() doerr(None,e) diff --git a/kivyblocks/ready.py b/kivyblocks/ready.py index 28a1d98..bd33b39 100644 --- a/kivyblocks/ready.py +++ b/kivyblocks/ready.py @@ -1,60 +1,15 @@ -from kivy.uix.widget import Widget -from kivy.properties import BooleanProperty -from kivy.clock import Clock -from kivy.graphics import Color, Rectangle +from kivy.event import EventDispatcher -class WidgetReady(Widget): - ready = BooleanProperty(False) - kwargs_keys = ['bg_color'] - def __init__(self, **kw): - 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() +class WidgetReady(EventDispatcher): + def __init__(self): + self.register_event_type('on_ready') + self._ready = False - def setupBackgroundColor(self): - self.bind(pos=self.backgroundcolorfunc) - 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 on_ready(self): + pass + def ready(self): + if self._ready: + return + self.dispatch('on_ready') + self._ready = True