This commit is contained in:
yumoqing 2022-08-29 20:59:26 +08:00
parent 48ecc1c5e3
commit c13dd66f05
11 changed files with 152 additions and 27 deletions

View File

@ -4,6 +4,7 @@ from traceback import print_exc
from kivy.properties import ObjectProperty, StringProperty, \ from kivy.properties import ObjectProperty, StringProperty, \
NumericProperty, BooleanProperty, OptionProperty NumericProperty, BooleanProperty, OptionProperty
from kivy.properties import DictProperty
from kivy.app import App from kivy.app import App
from kivy.utils import platform from kivy.utils import platform
from kivy.uix.button import Button, ButtonBehavior from kivy.uix.button import Button, ButtonBehavior
@ -86,6 +87,34 @@ class WrapText(Label):
self.bind(width=lambda *x: self.setter('text_size')(self, (self.width, None)), self.bind(width=lambda *x: self.setter('text_size')(self, (self.width, None)),
texture_size=lambda *x: self.setter('height')(self, self.texture_size[1])) texture_size=lambda *x: self.setter('height')(self, self.texture_size[1]))
class StackBox(WidgetCSS, WidgetReady, StackLayout):
def __init__(self, **kw):
super().__init__(**kw)
class AnchorBox(WidgetCSS, WidgetReady, AnchorLayout):
def __init__(self, **kw):
super().__init__(**kw)
def FloatBox(WidgetCSS, WidgetReady, FloatLayout):
def __init__(self, **kw):
super().__init__(**kw)
def RelativeBox(WidgetCSS, WidgetReady, RelativeLayout):
def __init__(self, **kw):
super().__init__(**kw)
def GridBox(WidgetCSS, WidgetReady, GridLayout):
def __init__(self, **kw):
super().__init__(**kw)
def PageBox(WidgetCSS, WidgetReady, PageLayout):
def __init__(self, **kw):
super().__init__(**kw)
def ScatterBox(WidgetCSS, WidgetReady, ScatterLayout):
def __init__(self, **kw):
super().__init__(**kw)
class Box(WidgetCSS, WidgetReady, BoxLayout): class Box(WidgetCSS, WidgetReady, BoxLayout):
def __init__(self, **kw): def __init__(self, **kw):
try: try:
@ -471,3 +500,69 @@ def device_type():
else: else:
return "mobile" return "mobile"
class ExAccordion(WidgetCSS, WidgetReady, Accordion):
"""
{
"widgettype":"Accordion",
"options":{
"csscls",
"items":[{
"title":"titl1",
"active":false,
"widget":{
}
}
]
}
}
"""
items = ListProperty(None)
def __init__(self, **kw):
print('ExAccordion() init...')
super().__init__(**kw)
self.width = self.height = 800
# Clock.schedule_once(self._build_children, 0.1)
self._build_children()
def _build_children(self, *args):
for i in self.items:
bk = Factory.Blocks()
w = bk.widgetBuild(i['widget'])
if w is None:
continue
tw = AccordionItem()
if isinstance(i['title'], str):
tw.title = i['title']
else:
tw.title = bk.widgetBuild(i['title'])
tw.add_widget(w)
if i.get('active'):
self.collapse = False
else:
self.collapse = True
self.add_widget(tw)
class Slider(Carousel):
"""
{
"widgettype":"Slider",
"options":{
"direction":"right",
"loop":true,
"items":[
{
"widgettype":....
}
]
}
}
"""
items = ListProperty(None)
def __init__(self, **kw):
print('Carousel pro=', dir(Carousel))
super().__init__(**kw)
bk = Factory.Blocks()
for desc in self.items:
w = bk.widgetBuild(desc)
self.add_widget(w)

View File

@ -286,7 +286,7 @@ class Blocks(EventDispatcher):
if isinstance(v,dict) and v.get('widgettype'): if isinstance(v,dict) and v.get('widgettype'):
b = Blocks() b = Blocks()
v = self.valueExpr(v, localnamespace={'self':widget}) v = self.valueExpr(v, localnamespace={'self':widget})
w = b.w_build(v) w = b.widgetBuild(v)
if hasattr(widget,k): if hasattr(widget,k):
aw = getattr(widget,k) aw = getattr(widget,k)
if isinstance(aw,Layout): if isinstance(aw,Layout):

View File

@ -12,9 +12,10 @@ from kivy.clock import Clock
from kivy.properties import StringProperty, BooleanProperty, \ from kivy.properties import StringProperty, BooleanProperty, \
OptionProperty, NumericProperty OptionProperty, NumericProperty
from kivy.graphics.texture import Texture from kivy.graphics.texture import Texture
from kivyblocks.ready import WidgetReady
class FFVideo(Image): class FFVideo(WidgetReady, Image):
v_src = StringProperty(None) v_src = StringProperty(None)
status = OptionProperty('stop', \ status = OptionProperty('stop', \
options=['stop', 'play', 'pause']) options=['stop', 'play', 'pause'])
@ -39,6 +40,7 @@ class FFVideo(Image):
self.lib_opts = {} self.lib_opts = {}
self.headers_pattern = {} self.headers_pattern = {}
super(FFVideo, self).__init__(**kwargs) super(FFVideo, self).__init__(**kwargs)
self.set_black()
self.register_event_type('on_frame') self.register_event_type('on_frame')
self.register_event_type('on_open_failed') self.register_event_type('on_open_failed')
self.register_event_type('on_leave_focus') self.register_event_type('on_leave_focus')
@ -48,7 +50,7 @@ class FFVideo(Image):
def on_open_failed(self, *args): def on_open_failed(self, *args):
pass pass
def on_load_syccess(self, *args): def on_load_success(self, *args):
pass pass
def on_enter_focus(self, *args): def on_enter_focus(self, *args):
@ -194,6 +196,9 @@ class FFVideo(Image):
lib_opts=lib_opts) lib_opts=lib_opts)
self._play_start() self._play_start()
def file_opened(self, files):
self.v_src = files[0]
def play(self): def play(self):
if self._player is None: if self._player is None:
return return
@ -254,7 +259,7 @@ class FFVideo(Image):
return return
image_texture = Texture.create( image_texture = Texture.create(
size=self.size, colorfmt='rgb') size=self.size, colorfmt='rgb')
buf = b'\x00' * self.width * self.height * 3 buf = b'\x00' * int(self.width * self.height * 3)
image_texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte') image_texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')
self.texture = image_texture self.texture = image_texture
self.is_black = True self.is_black = True

View File

@ -13,12 +13,9 @@ from kivyblocks.baseWidget import PressableImage, StrInput
import os import os
def i18n(s):
return s
class FileLoaderBrowser(Popup): class FileLoaderBrowser(Popup):
def __init__(self,rootpath='/', title='load file', choose_dir=False, **kwargs): def __init__(self,rootpath='/', title='load file', choose_dir=False, **kwargs):
# i18n = I18n() i18n = I18n()
self.content = BoxLayout(orientation='vertical') self.content = BoxLayout(orientation='vertical')
Popup.__init__(self, content = self.content, Popup.__init__(self, content = self.content,
title=i18n(title), title=i18n(title),

View File

@ -352,7 +352,7 @@ sub-widget's description file format
return True return True
mc = MenuContainer() mc = MenuContainer()
mc.add_widget(w.menu_widget) mc.add_widget(w.menu_widget)
self.w.menu_widget.bind(on_press=mc.dismiss) w.menu_widget.bind(on_press=mc.dismiss)
mc.size_hint = (None,None) mc.size_hint = (None,None)
mc.height = self.content.height mc.height = self.content.height
mc.width = self.width * 0.4 mc.width = self.width * 0.4

View File

@ -8,6 +8,7 @@ from kivy.clock import Clock
from kivy.utils import platform from kivy.utils import platform
from kivy.app import App from kivy.app import App
from kivy.properties import BooleanProperty from kivy.properties import BooleanProperty
from plyer import filechooser
desktopOSs=[ desktopOSs=[
"win", "win",
@ -124,3 +125,24 @@ class WidgetReady(object):
self.size = state['size'] self.size = state['size']
if state['parent'] is not window: if state['parent'] is not window:
state['parent'].add_widget(self) state['parent'].add_widget(self)
def file_open_for_read(self, *args, **kw):
method_name = kw.get('on_selection')
if method_name is None:
return
f = getattr(self, method_name)
if f is None:
return
kw['on_selection'] = f
filechooser.open_file(**kw)
def file_open_for_write(self, *args, **kw):
method_name = kw.get('on_selection')
if method_name is None:
return
f = getattr(self, method_name)
if f is None:
return
kw['on_selection'] = f
filechooser.save_file(**kw)

View File

@ -46,6 +46,13 @@ from .ffpyplayer_video import FFVideo
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('AnchorBox', AnchorBox)
r('FloatBox', FloatBox)
r('RelativeBox', RelativeBox)
r('GridBox', GridBox)
r('PageBox', PageBox)
r('ScatterBox', ScatterBox)
r('StackBox', StackBox)
r('DateInput', DateInput) r('DateInput', DateInput)
r('HTTPSeriesData', HTTPSeriesData) r('HTTPSeriesData', HTTPSeriesData)
r('HTTPDataHandler', HTTPDataHandler) r('HTTPDataHandler', HTTPDataHandler)
@ -109,6 +116,8 @@ r('HBox',HBox)
r('VBox',VBox) r('VBox',VBox)
r('SwipeBox',SwipeBox) r('SwipeBox',SwipeBox)
r('ToggleItems',ToggleItems) r('ToggleItems',ToggleItems)
r('ExAccordion', ExAccordion)
r('Slider', Slider)
if platform == 'android': if platform == 'android':
r('PhoneButton',PhoneButton) r('PhoneButton',PhoneButton)
r('AWebView',AWebView) r('AWebView',AWebView)

View File

@ -19,12 +19,12 @@ def set_script_env(n,v):
class Script: class Script:
def __init__(self, root): def __init__(self, root):
print('root=', root)
self.root = root self.root = root
self.env = {} self.env = {}
self.handlers = {} self.handlers = {}
self.register('.tmpl', TemplateHandler) self.register('.tmpl', TemplateHandler)
self.register('.dspy', DspyHandler) self.register('.dspy', DspyHandler)
self.register('.ui', TemplateHandler)
def url2filepath(self, url): def url2filepath(self, url):
if url.startswith('file://'): if url.startswith('file://'):
@ -41,7 +41,7 @@ class Script:
env['root_path'] = self.root env['root_path'] = self.root
env['url'] = url env['url'] = url
env['filepath'] = filepath env['filepath'] = filepath
h = handler(env, **kw) h = handler(env)
d = h.render() d = h.render()
try: try:
return json.loads(d) return json.loads(d)
@ -60,9 +60,15 @@ class BaseHandler:
url.startswith('http://') or \ url.startswith('http://') or \
url.startswith('hppts://'): url.startswith('hppts://'):
return url return url
tokens = url.split('/')
if tokens[0] == '':
root = self.env['root_path']
tokens[0] = root
return '/'.join(tokens)
p1 = self.env['url'].split('/')[:-1] p1 = self.env['url'].split('/')[:-1]
p2 = url.split('/') return '/'.join(p1+tokens)
return '/'.join(p1+p2)
def __init__(self, env): def __init__(self, env):
self.env = env self.env = env
self.env['entire_url'] = self.entire_url self.env['entire_url'] = self.entire_url
@ -80,6 +86,7 @@ class TemplateHandler(BaseHandler):
cpath = join(cpath, p) cpath = join(cpath, p)
paths.append(cpath) paths.append(cpath)
paths.reverse()
self.engine = MyTemplateEngine(paths) self.engine = MyTemplateEngine(paths)
def render(self): def render(self):

View File

@ -12,7 +12,7 @@
"root":{ "root":{
"widgettype":"urlwidget", "widgettype":"urlwidget",
"options":{ "options":{
"url":"file://index.tmpl" "url":"file://index.ui"
} }
} }
} }

View File

@ -1,10 +1,12 @@
from kivyblocks.setconfig import config_set
from kivyblocks.blocksapp import BlocksApp from kivyblocks.blocksapp import BlocksApp
from kivyblocks.blocks import registerWidget, Blocks from kivyblocks.blocks import registerWidget, Blocks
import kivyblocks.register import kivyblocks.register
from kivyblocks.script import set_script_env
class ScriptApp(BlocksApp): class ScriptApp(BlocksApp):
pass pass
if __name__ == '__main__': if __name__ == '__main__':
set_script_env('userid', 'testuser')
ScriptApp().run() ScriptApp().run()

View File

@ -1,12 +0,0 @@
{
"widgettype":"VBox",
"options":{},
"subwidgets":[
{
"widgettype":"Button",
"options":{
"text":"Hello"
}
}
]
}