bugfix
This commit is contained in:
parent
1352d23245
commit
9b6084e15d
@ -2,8 +2,8 @@ from kivy.logger import Logger
|
|||||||
from kivy.graphics import Color, Rectangle, RoundedRectangle
|
from kivy.graphics import Color, Rectangle, RoundedRectangle
|
||||||
from kivy.properties import ListProperty, NumericProperty
|
from kivy.properties import ListProperty, NumericProperty
|
||||||
from .color_definitions import getColors
|
from .color_definitions import getColors
|
||||||
|
from .mixin import register_mixin
|
||||||
|
|
||||||
_logcnt = 0
|
|
||||||
class BGColorBehavior(object):
|
class BGColorBehavior(object):
|
||||||
color_level=NumericProperty(0)
|
color_level=NumericProperty(0)
|
||||||
radius = ListProperty([])
|
radius = ListProperty([])
|
||||||
@ -65,3 +65,5 @@ class BGColorBehavior(object):
|
|||||||
self.bgcolor = self.normal_bgcolor
|
self.bgcolor = self.normal_bgcolor
|
||||||
self.color = self.fgcolor = self.normal_fgcolor
|
self.color = self.fgcolor = self.normal_fgcolor
|
||||||
self.on_bgcolor()
|
self.on_bgcolor()
|
||||||
|
|
||||||
|
register_mixin('BGColorBehavior', BGColorBehavior)
|
||||||
|
@ -103,6 +103,7 @@ def registerWidget(name:str,widget):
|
|||||||
globals()[name] = widget
|
globals()[name] = widget
|
||||||
|
|
||||||
|
|
||||||
|
klass_cnt = 0
|
||||||
class Blocks(EventDispatcher):
|
class Blocks(EventDispatcher):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
EventDispatcher.__init__(self)
|
EventDispatcher.__init__(self)
|
||||||
@ -113,6 +114,47 @@ class Blocks(EventDispatcher):
|
|||||||
config = getConfig()
|
config = getConfig()
|
||||||
self.script = Script()
|
self.script = Script()
|
||||||
|
|
||||||
|
def klassBuild(self, klass_name, options):
|
||||||
|
global klass_cnt
|
||||||
|
exclude_mixin = filter_mixin(options)
|
||||||
|
mixins = get_mixins(options)
|
||||||
|
klasses = [
|
||||||
|
{
|
||||||
|
'name':klass_name,
|
||||||
|
'klass':Factory.get(klass_name),
|
||||||
|
'opts':exclude_mixin
|
||||||
|
}
|
||||||
|
]
|
||||||
|
if mixins == {}:
|
||||||
|
return Factory.get(klass_name)(**options)
|
||||||
|
|
||||||
|
env = globals().copy()
|
||||||
|
lenv = {}
|
||||||
|
for n, d, in mixins.items():
|
||||||
|
klasses.append({
|
||||||
|
'name':n,
|
||||||
|
'klass':Factory.get(n),
|
||||||
|
'opts':d
|
||||||
|
})
|
||||||
|
print('mixins=', mixins)
|
||||||
|
env['klasses'] = klasses
|
||||||
|
ids = [ i for i in range(len(klasses))]
|
||||||
|
ids.reverse()
|
||||||
|
klasslist = ','.join([f'klasses[{i}]["klass"]' for i in ids])
|
||||||
|
code = f"""class ClassX{klass_cnt}({klasslist}):
|
||||||
|
def __init__(self):
|
||||||
|
for i in range(len(klasses)):
|
||||||
|
print(klasses[i]['opts'])
|
||||||
|
klasses[i]['klass'].__init__(self, **klasses[i]['opts'])
|
||||||
|
|
||||||
|
x = ClassX{klass_cnt}()
|
||||||
|
"""
|
||||||
|
print(code)
|
||||||
|
exec(code, env, lenv)
|
||||||
|
w = lenv.get('x', None)
|
||||||
|
klass_cnt += 1
|
||||||
|
return w
|
||||||
|
|
||||||
def set(self, k:str, v):
|
def set(self, k:str, v):
|
||||||
self.env[k] = v
|
self.env[k] = v
|
||||||
|
|
||||||
@ -243,19 +285,17 @@ class Blocks(EventDispatcher):
|
|||||||
if not widgetClass:
|
if not widgetClass:
|
||||||
Logger.info("Block: w_build(), desc invalid", desc)
|
Logger.info("Block: w_build(), desc invalid", desc)
|
||||||
raise Exception(desc)
|
raise Exception(desc)
|
||||||
|
|
||||||
widgetClass = desc['widgettype']
|
|
||||||
opts_org = self.valueExpr(desc.get('options',{}).copy())
|
opts_org = self.valueExpr(desc.get('options',{}).copy())
|
||||||
opts = filter_mixin(opts_org)
|
|
||||||
bopts = get_mixins(opts_org)
|
|
||||||
widget = None
|
widget = None
|
||||||
try:
|
try:
|
||||||
|
"""
|
||||||
klass = Factory.get(widgetClass)
|
klass = Factory.get(widgetClass)
|
||||||
widget = klass(**opts)
|
widget = klass(**opts)
|
||||||
mixin_behaviors(widget, bopts)
|
"""
|
||||||
|
widget = self.klassBuild(widgetClass, opts_org)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Error:',widgetClass,'contructon error')
|
print('Error:',widgetClass,'construction error')
|
||||||
print_exc()
|
print_exc()
|
||||||
raise NotExistsObject(widgetClass)
|
raise NotExistsObject(widgetClass)
|
||||||
|
|
||||||
@ -314,7 +354,7 @@ class Blocks(EventDispatcher):
|
|||||||
kw = self.valueExpr(sw.copy(),
|
kw = self.valueExpr(sw.copy(),
|
||||||
localnamespace={'self':widget})
|
localnamespace={'self':widget})
|
||||||
w = b.widgetBuild(kw)
|
w = b.widgetBuild(kw)
|
||||||
if w:
|
if w and not w.parent:
|
||||||
widget.add_widget(w)
|
widget.add_widget(w)
|
||||||
|
|
||||||
|
|
||||||
@ -684,7 +724,9 @@ class Blocks(EventDispatcher):
|
|||||||
if widgettype is None:
|
if widgettype is None:
|
||||||
print('Block3: desc must be a dict object not None')
|
print('Block3: desc must be a dict object not None')
|
||||||
return None
|
return None
|
||||||
return doit(desc)
|
w = doit(desc)
|
||||||
|
print('widgetBuild():w=', w)
|
||||||
|
return w
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def findWidget(self, id:str, from_widget:Widget=None) -> Widget:
|
def findWidget(self, id:str, from_widget:Widget=None) -> Widget:
|
||||||
|
@ -1,27 +1,62 @@
|
|||||||
|
from kivy.factory import Factory
|
||||||
|
from kivy.uix.behaviors import ButtonBehavior
|
||||||
|
from kivy.uix.behaviors import CodeNavigationBehavior
|
||||||
|
from kivy.uix.behaviors import CompoundSelectionBehavior
|
||||||
|
from kivy.uix.behaviors import CoverBehavior
|
||||||
|
from kivy.uix.behaviors import DragBehavior
|
||||||
|
from kivy.uix.behaviors import EmacsBehavior
|
||||||
|
from kivy.uix.behaviors import FocusBehavior
|
||||||
|
from kivy.uix.behaviors import ToggleButtonBehavior
|
||||||
|
from kivy.uix.behaviors import TouchRippleBehavior
|
||||||
|
from kivy.uix.behaviors import TouchRippleButtonBehavior
|
||||||
|
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
|
|
||||||
_mix_ins = {}
|
_mix_ins = {}
|
||||||
|
|
||||||
|
# def on_press(inst, *args):
|
||||||
|
# pass
|
||||||
|
|
||||||
|
# ButtonBehavior.on_press = on_press
|
||||||
|
|
||||||
def filter_mixin(kwargs):
|
def filter_mixin(kwargs):
|
||||||
return {k:v for k, v in kwargs.items() if not k.endswith('behavior')}
|
return {k:v for k, v in kwargs.items() if not k.endswith('Behavior')}
|
||||||
|
|
||||||
def get_mixins(kwargs):
|
def get_mixins(kwargs):
|
||||||
return {k:v for k, v in kwargs.items() if k.endswith('behavior')}
|
return {k:v for k, v in kwargs.items() if k.endswith('Behavior')}
|
||||||
|
|
||||||
def register_mixin(name, klass):
|
def register_mixin(name, klass):
|
||||||
_mix_ins[name] = klass
|
_mix_ins[name] = klass
|
||||||
|
Factory.register(name, klass)
|
||||||
|
|
||||||
def mix_other(inst, other):
|
def mix_other(inst, other):
|
||||||
for k,v in other.__dict__.items():
|
excluded = ['__class__', '__dict__', '__weakref__']
|
||||||
setattr(inst, k, v)
|
keys = [ k for k in dir(other) if k not in excluded ]
|
||||||
|
for k in keys:
|
||||||
|
if not hasattr(inst, k):
|
||||||
|
setattr(inst, k, getattr(other, k))
|
||||||
|
|
||||||
def mixin_behaviors(inst, kwargs):
|
def mixin_behaviors(inst, kwargs):
|
||||||
behaviors_kw = get_mixins(kwargs)
|
behaviors_kw = get_mixins(kwargs)
|
||||||
for name, dic in behaviors_kw.items():
|
for name, dic in behaviors_kw.items():
|
||||||
klass = _mix_ins.get(name)
|
klass = _mix_ins.get(name)
|
||||||
if klass:
|
if klass:
|
||||||
other = Factory.Blocks().widgetBuild(dic)
|
mix_other(klass, inst.__class__)
|
||||||
|
desc = {
|
||||||
|
"widgettype":name,
|
||||||
|
"options":dic
|
||||||
|
}
|
||||||
|
other = Factory.Blocks().widgetBuild(desc)
|
||||||
if other:
|
if other:
|
||||||
mix_other(inst, other)
|
mix_other(inst, other)
|
||||||
|
|
||||||
|
register_mixin('ButtonBehavior', ButtonBehavior)
|
||||||
|
register_mixin('CodeNavigationBehavior', CodeNavigationBehavior)
|
||||||
|
register_mixin('CompoundSelectionBehavior', CompoundSelectionBehavior)
|
||||||
|
register_mixin('CoverBehavior', CoverBehavior)
|
||||||
|
register_mixin('DragBehavior', DragBehavior)
|
||||||
|
register_mixin('EmacsBehavior', EmacsBehavior)
|
||||||
|
register_mixin('FocusBehavior', FocusBehavior)
|
||||||
|
register_mixin('ToggleButtonBehavior', ToggleButtonBehavior)
|
||||||
|
register_mixin('TouchRippleBehavior', TouchRippleBehavior)
|
||||||
|
register_mixin('TouchRippleButtonBehavior', TouchRippleButtonBehavior)
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
|
||||||
|
from kivy.core.window import Window
|
||||||
from kivy.properties import DictProperty, BooleanProperty, \
|
from kivy.properties import DictProperty, BooleanProperty, \
|
||||||
StringProperty, OptionProperty, \
|
StringProperty, OptionProperty, \
|
||||||
NumericProperty
|
NumericProperty
|
||||||
|
|
||||||
from mixin import register_mixin
|
|
||||||
|
|
||||||
class ModalBehavior(object):
|
class ModalBehavior(object):
|
||||||
auto_open = BooleanProperty(True)
|
auto_open = BooleanProperty(True)
|
||||||
auto_dismiss = BooleanProperty(True)
|
auto_dismiss = BooleanProperty(True)
|
||||||
@ -14,9 +13,10 @@ class ModalBehavior(object):
|
|||||||
'cl', 'cc', 'cr',
|
'cl', 'cc', 'cr',
|
||||||
'bl', 'bc', 'br'])
|
'bl', 'bc', 'br'])
|
||||||
def __init__(self, **kw):
|
def __init__(self, **kw):
|
||||||
|
for k,v in kw.items():
|
||||||
|
setattr(self, k,v)
|
||||||
self.time_task = None
|
self.time_task = None
|
||||||
self._target = None
|
self._target = None
|
||||||
super(Modal, self).__init__(**kw)
|
|
||||||
self.set_size_position()
|
self.set_size_position()
|
||||||
self._target.bind(size=self.set_size_position)
|
self._target.bind(size=self.set_size_position)
|
||||||
self.register_event_type('on_open')
|
self.register_event_type('on_open')
|
||||||
@ -28,11 +28,17 @@ class ModalBehavior(object):
|
|||||||
self.open()
|
self.open()
|
||||||
|
|
||||||
def on_touchdown(self, o, touch):
|
def on_touchdown(self, o, touch):
|
||||||
|
print('on_touchdown() called')
|
||||||
if not self.collide_point(touch.x, touch.y):
|
if not self.collide_point(touch.x, touch.y):
|
||||||
if self.auto_dismiss:
|
if self.auto_dismiss:
|
||||||
|
print('on_touchdown():auto_dismiss()')
|
||||||
self.dispatch('on_pre_dismiss')
|
self.dispatch('on_pre_dismiss')
|
||||||
self.dismiss()
|
self.dismiss()
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
print('on_touchdown(): not auto_dismiss')
|
||||||
|
else:
|
||||||
|
print('on_touchdown():inside modal')
|
||||||
|
|
||||||
def on_target(self, *args):
|
def on_target(self, *args):
|
||||||
self._target = None
|
self._target = None
|
||||||
@ -77,6 +83,7 @@ class ModalBehavior(object):
|
|||||||
self.pos = x, y
|
self.pos = x, y
|
||||||
else:
|
else:
|
||||||
self.pos = self._target.pos[0] + x, self._target.pos[1] + y
|
self.pos = self._target.pos[0] + x, self._target.pos[1] + y
|
||||||
|
print("modal",self._target.size, self.position, self.pos, self.size, self.size_hint)
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
if self.time_task is not None:
|
if self.time_task is not None:
|
||||||
@ -94,6 +101,7 @@ class ModalBehavior(object):
|
|||||||
self._target.disabled = True
|
self._target.disabled = True
|
||||||
|
|
||||||
def dismiss(self, *args):
|
def dismiss(self, *args):
|
||||||
|
print('dismiss() called')
|
||||||
if self.time_task:
|
if self.time_task:
|
||||||
self.time_task.cancel()
|
self.time_task.cancel()
|
||||||
self.time_task = None
|
self.time_task = None
|
||||||
@ -115,4 +123,3 @@ class ModalBehavior(object):
|
|||||||
def on_pre_dismiss(self, *args):
|
def on_pre_dismiss(self, *args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
register_mixin('modalbehavior', ModalBehavior)
|
|
||||||
|
@ -45,10 +45,12 @@ from .ffpyplayer_video import FFVideo
|
|||||||
from .upload import UploadFile
|
from .upload import UploadFile
|
||||||
from .pyinterpreter import PyInterpreter
|
from .pyinterpreter import PyInterpreter
|
||||||
from .circle_progress import CircleProgress
|
from .circle_progress import CircleProgress
|
||||||
|
from .modalbehavior import ModalBehavior
|
||||||
|
|
||||||
r = Factory.register
|
r = Factory.register
|
||||||
# if kivy.platform in ['win','linux', 'macosx']:
|
# if kivy.platform in ['win','linux', 'macosx']:
|
||||||
# r('ScreenWithMic', ScreenWithMic)
|
# r('ScreenWithMic', ScreenWithMic)
|
||||||
|
r('ModalBehavior', ModalBehavior)
|
||||||
r('CircleProgress', CircleProgress)
|
r('CircleProgress', CircleProgress)
|
||||||
r('PyInterpreter', PyInterpreter)
|
r('PyInterpreter', PyInterpreter)
|
||||||
r('UploadFile', UploadFile)
|
r('UploadFile', UploadFile)
|
||||||
|
@ -35,10 +35,10 @@ class Script:
|
|||||||
self.register('.ui', TemplateHandler)
|
self.register('.ui', TemplateHandler)
|
||||||
|
|
||||||
def url2filepath(self, url):
|
def url2filepath(self, url):
|
||||||
if url.startswith('file:///'):
|
if url.startswith('file://'):
|
||||||
url = url[8:]
|
url = url[7:]
|
||||||
ret = join(self.root, *url.split('/'))
|
ret = join(self.root, *url.split('/'))
|
||||||
# print('url2filepath():root=', self.root, url, ret)
|
print('url2filepath():root=', self.root, url, ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def show_info(self, env):
|
def show_info(self, env):
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import time
|
import time
|
||||||
from kivy.logger import Logger
|
from kivy.logger import Logger
|
||||||
|
from .mixin import register_mixin
|
||||||
|
|
||||||
class SwipeBehavior(object):
|
class SwipeBehavior(object):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
@ -56,6 +57,7 @@ class SwipeBehavior(object):
|
|||||||
# Logger.info('SwipeBehavior:touch_down fired')
|
# Logger.info('SwipeBehavior:touch_down fired')
|
||||||
if self.swipeenable:
|
if self.swipeenable:
|
||||||
# Logger.info('SwipeBehavior:touch_down fired')
|
# Logger.info('SwipeBehavior:touch_down fired')
|
||||||
|
touch.grab(self)
|
||||||
self.sb_start_point = touch.pos
|
self.sb_start_point = touch.pos
|
||||||
self.sb_start_time = time.time()
|
self.sb_start_time = time.time()
|
||||||
|
|
||||||
@ -69,8 +71,10 @@ class SwipeBehavior(object):
|
|||||||
|
|
||||||
def on_touchup(self,o,touch):
|
def on_touchup(self,o,touch):
|
||||||
ret = False
|
ret = False
|
||||||
if self.collide_point(*touch.pos) and self.swipeenable:
|
if self.collide_point(*touch.pos) and self.swipeenable and \
|
||||||
|
touch.grab_current is self:
|
||||||
# Logger.info('SwipeBehavior:touch_up fired')
|
# Logger.info('SwipeBehavior:touch_up fired')
|
||||||
|
touch.ungrab(self)
|
||||||
self.sb_end_point = touch.pos
|
self.sb_end_point = touch.pos
|
||||||
self.sb_end_time = time.time()
|
self.sb_end_time = time.time()
|
||||||
self.check_context_menu()
|
self.check_context_menu()
|
||||||
@ -116,3 +120,5 @@ class SwipeBehavior(object):
|
|||||||
elif self.sb_start_point[1] - self.sb_end_point[1] >= \
|
elif self.sb_start_point[1] - self.sb_end_point[1] >= \
|
||||||
self.threshold:
|
self.threshold:
|
||||||
self.dispatch('on_swipe_down')
|
self.dispatch('on_swipe_down')
|
||||||
|
|
||||||
|
register_mixin('SwipeBehavior', SwipeBehavior)
|
||||||
|
@ -48,7 +48,6 @@ def SUPER(klass, obj, kw):
|
|||||||
super(klass, obj).__init__(**kw)
|
super(klass, obj).__init__(**kw)
|
||||||
for k,v in dic.items():
|
for k,v in dic.items():
|
||||||
try:
|
try:
|
||||||
if v is not None:
|
|
||||||
setattr(obj, k, v)
|
setattr(obj, k, v)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'obj={obj}, setattr(obj, "{k}","{v}") error')
|
print(f'obj={obj}, setattr(obj, "{k}","{v}") error')
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"hugest":6.5
|
"hugest":6.5
|
||||||
},
|
},
|
||||||
"font_name":"normal",
|
"font_name":"normal",
|
||||||
|
"uihome":"file://",
|
||||||
"script_root":"$[workdir]$/scripts",
|
"script_root":"$[workdir]$/scripts",
|
||||||
"root":{
|
"root":{
|
||||||
"widgettype":"urlwidget",
|
"widgettype":"urlwidget",
|
||||||
|
@ -14,6 +14,21 @@
|
|||||||
"label":"Setting",
|
"label":"Setting",
|
||||||
"icon":"{{entire_url('/imgs/setting.png')}}",
|
"icon":"{{entire_url('/imgs/setting.png')}}",
|
||||||
"url":"{{entire_url('t.ui')}}"
|
"url":"{{entire_url('t.ui')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"behavior1",
|
||||||
|
"label":"behavior1",
|
||||||
|
"url":"{{entire_url('boxlayout/behavior.ui')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"modal1",
|
||||||
|
"label":"Modal Text",
|
||||||
|
"url":"{{entire_url('boxlayout/modalbehavior.ui')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"boxlayout",
|
||||||
|
"label":"WBoxLayout",
|
||||||
|
"url":"{{entire_url('boxlayout/normal.ui')}}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXT-X-VERSION:3
|
|
||||||
#EXT-X-STREAM-INF:BANDWIDTH=898222,RESOLUTION=1047x576,CODECS="avc1.77.30,mp4a.40.2"
|
|
||||||
chunklist_w891111828.m3u8
|
|
Loading…
Reference in New Issue
Block a user