Merge branch 'master' of github.com:tito/kivy

Conflicts:
	kivy/data/style.uxl
	kivy/factory_registers.py
This commit is contained in:
Thomas Hansen 2010-11-06 00:31:06 -05:00
commit de6b81d9e3
8 changed files with 167 additions and 48 deletions

View File

@ -1,13 +1,22 @@
from kivy.app import App from kivy.app import App
from kivy.clock import Clock
from kivy.uix.widget import Widget from kivy.uix.widget import Widget
from kivy.uix.button import Button from kivy.uix.button import Button
from kivy.uix.label import Label from kivy.uix.label import Label
from kivy.core.text import Label as CoreLabel from kivy.core.text import Label as CoreLabel
from kivy.graphics import * from kivy.graphics import *
from random import random
class TestApp(App): class TestApp(App):
def build(self): def build(self):
return Button(text='Hello world') def print_fps(dt):
print 'FPS: ', Clock.get_fps()
Clock.schedule_interval(print_fps, 1)
a = Widget()
for x in xrange(100):
pos = random() * 500, random() * 500
a.add_widget(Button(text=str(x), pos=pos))
return a
TestApp().run() TestApp().run()

View File

@ -2,8 +2,8 @@
Widget: Widget:
Button: Button:
label: "Hello World" text: "Hello World"
Button: Button:
label: "I'm another label" text: "I'm another label"
pos: (200, 200) pos: (200, 200)

View File

@ -260,7 +260,6 @@ class LabelBase(object):
# update texture # update texture
self.texture.blit_data(data) self.texture.blit_data(data)
def refresh(self): def refresh(self):
'''Force re-rendering of the text''' '''Force re-rendering of the text'''
# first pass, calculating width/height # first pass, calculating width/height
@ -284,7 +283,6 @@ class LabelBase(object):
self._text = str(text) self._text = str(text)
except: except:
self._text = text self._text = text
self.refresh()
text = property(_get_text, _set_text, doc='Get/Set the text') text = property(_get_text, _set_text, doc='Get/Set the text')
label = property(_get_text, _set_text, doc='Get/Set the text') label = property(_get_text, _set_text, doc='Get/Set the text')

View File

@ -1,14 +1,19 @@
<Button>: <Button>:
canvas: canvas:
Color: Color:
rgb: (1, 0, 0) rgb: dict(normal=(0, 1, 1), down=(1, 0, 0))[root.state]
Rectangle: Rectangle:
pos: self.pos pos: self.pos
size: self.size size: self.size
Label: Label:
font_size: 30
canvas: canvas:
Rectangle: Color:
rgb: (1, 1, 1)
BorderRectangle:
texture: self.texture texture: self.texture
size: self.texture_size
pos: root.center[0] - self.texture_size[0] / 2., root.center[1] - self.texture_size[1] / 2.
<Slider>: <Slider>:
canvas: canvas:

58
kivy/factory_registers.py Normal file
View File

@ -0,0 +1,58 @@
# Auto-generated file by setup.py build_factory
from kivy.factory import Factory
Factory.register('Gesture', module='kivy.gesture')
Factory.register('GestureDatabase', module='kivy.gesture')
Factory.register('GesturePoint', module='kivy.gesture')
Factory.register('GestureStroke', module='kivy.gesture')
Factory.register('Cache', module='kivy.cache')
Factory.register('Vector', module='kivy.vector')
Factory.register('LoggerHistory', module='kivy.logger')
Factory.register('ExceptionHandler', module='kivy.exceptions')
Factory.register('Texture', module='kivy.texture')
Factory.register('TextureRegion', module='kivy.texture')
Factory.register('SafeList', module='kivy.utils')
Factory.register('OBJ', module='kivy.obj')
Factory.register('Material', module='kivy.obj')
Factory.register('MaterialGroup', module='kivy.obj')
Factory.register('Mesh', module='kivy.obj')
Factory.register('MTContext', module='kivy.plugin')
Factory.register('MTPlugins', module='kivy.plugin')
Factory.register('FactoryException', module='kivy.factory')
Factory.register('ProxyImage', module='kivy.loader')
Factory.register('EventDispatcher', module='kivy.c_ext.event')
Factory.register('Canvas', module='kivy.c_ext.graphics')
Factory.register('GraphicInstruction', module='kivy.c_ext.graphics')
Factory.register('ContextInstruction', module='kivy.c_ext.graphics')
Factory.register('PushMatrix', module='kivy.c_ext.graphics')
Factory.register('PopMatrix', module='kivy.c_ext.graphics')
Factory.register('MatrixInstruction', module='kivy.c_ext.graphics')
Factory.register('Transform', module='kivy.c_ext.graphics')
Factory.register('Rotate', module='kivy.c_ext.graphics')
Factory.register('Scale', module='kivy.c_ext.graphics')
Factory.register('Translate', module='kivy.c_ext.graphics')
Factory.register('LineWidth', module='kivy.c_ext.graphics')
Factory.register('Color', module='kivy.c_ext.graphics')
Factory.register('BindTexture', module='kivy.c_ext.graphics')
Factory.register('VertexDataInstruction', module='kivy.c_ext.graphics')
Factory.register('Triangle', module='kivy.c_ext.graphics')
Factory.register('Rectangle', module='kivy.c_ext.graphics')
Factory.register('BorderRectangle', module='kivy.c_ext.graphics')
Factory.register('Ellipse', module='kivy.c_ext.graphics')
Factory.register('Path', module='kivy.c_ext.graphics')
Factory.register('PathInstruction', module='kivy.c_ext.graphics')
Factory.register('PathStart', module='kivy.c_ext.graphics')
Factory.register('PathLineTo', module='kivy.c_ext.graphics')
Factory.register('PathClose', module='kivy.c_ext.graphics')
Factory.register('PathEnd', module='kivy.c_ext.graphics')
Factory.register('PathStroke', module='kivy.c_ext.graphics')
Factory.register('PathFill', module='kivy.c_ext.graphics')
Factory.register('Slider', module='kivy.uix.slider')
Factory.register('Button', module='kivy.uix.button')
Factory.register('Label', module='kivy.uix.label')
Factory.register('Widget', module='kivy.uix.widget')
Factory.register('TouchShape', module='kivy.input.shape')
Factory.register('TouchShapeRect', module='kivy.input.shape')
Factory.register('TouchProvider', module='kivy.input.provider')
Factory.register('TouchFactory', module='kivy.input.factory')

View File

@ -4,6 +4,7 @@ Label:
__all__ = ('Label', ) __all__ = ('Label', )
from kivy.utils import curry
from kivy.clock import Clock from kivy.clock import Clock
from kivy.uix.widget import Widget from kivy.uix.widget import Widget
from kivy.core.text import Label as CoreLabel from kivy.core.text import Label as CoreLabel
@ -49,34 +50,42 @@ class Label(Widget):
#: Texture of the label #: Texture of the label
texture = ObjectProperty(None, allownone=True) texture = ObjectProperty(None, allownone=True)
#: Texture size of the label
texture_size = ListProperty([0, 0])
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(Label, self).__init__(**kwargs) super(Label, self).__init__(**kwargs)
# bind all the property for recreating the texture # bind all the property for recreating the texture
d = ('text', 'font_size', 'font_name', 'bold', 'italic', 'halign', d = ('text', 'font_size', 'font_name', 'bold', 'italic', 'halign',
'valign', 'padding_x', 'padding_y') 'valign', 'padding_x', 'padding_y')
dkw = dict(zip(d, [self._trigger_texture_update] * len(d))) dkw = {}
for x in d:
dkw[x] = curry(self._trigger_texture_update, x)
self.bind(**dkw) self.bind(**dkw)
dkw = dict(zip(d, [getattr(self, x) for x in d])) dkw = dict(zip(d, [getattr(self, x) for x in d]))
print dkw
self._label = CoreLabel(**dkw) self._label = CoreLabel(**dkw)
# force the texture creation # force the texture creation
self._trigger_texture_update() self._texture_update()
'''
import pprint
def printm(sender, value): def printm(sender, value):
print sender, value print self.text, sender, value
self.bind(texture=printm) self.bind(texture=printm)
'''
def _trigger_texture_update(self, source=None, value=None): def _trigger_texture_update(self, name=None, source=None, value=None):
print '_trigger_texture_update()', source, value
if source: if source:
self._label.options[source.name] = value if name == 'text':
self._label.text = value
else:
self._label.options[name] = value
Clock.unschedule(self._texture_update) Clock.unschedule(self._texture_update)
Clock.schedule_once(self._texture_update) Clock.schedule_once(self._texture_update)
def _texture_update(self, *largs): def _texture_update(self, *largs):
self._label.refresh() self._label.refresh()
self.texture = None
self.texture = self._label.texture self.texture = self._label.texture
self.texture_size = list(self.texture.size)

View File

@ -12,7 +12,6 @@ __all__ = ('intersection', 'difference', 'curry', 'strtotuple',
import inspect import inspect
import re import re
import functools import functools
from kivy.logger import Logger
def boundary(value, minvalue, maxvalue): def boundary(value, minvalue, maxvalue):
'''Limit a value between a minvalue and maxvalue''' '''Limit a value between a minvalue and maxvalue'''
@ -140,6 +139,7 @@ def deprecated(func):
func.func_code.co_filename, func.func_code.co_filename,
func.func_code.co_firstlineno + 1, func.func_code.co_firstlineno + 1,
file, line, caller) file, line, caller)
from kivy.logger import Logger
Logger.warn(warning) Logger.warn(warning)
if func.__doc__: if func.__doc__:
Logger.warn(func.__doc__) Logger.warn(func.__doc__)

View File

@ -25,6 +25,8 @@ Example of Uxl files ::
__all__ = ('Uxl', 'UxlParser') __all__ = ('Uxl', 'UxlParser')
import re
from copy import copy
from kivy.factory import Factory from kivy.factory import Factory
from kivy.logger import Logger from kivy.logger import Logger
@ -221,9 +223,49 @@ class UxlParser(object):
with open(filename, 'r') as fd: with open(filename, 'r') as fd:
return fd.read() return fd.read()
def create_handler(element, key): def create_handler(element, key, value, idmap):
def call_fn(sender, value):
setattr(element, key, value) # detect key.value inside value
kw = re.findall('([a-zA-Z0-9_.]+\.[a-zA-Z0-9_.]+)', value)
if not kw:
# look like no reference, just pass it
return eval(value)
# create an handler
idmap = copy(idmap)
def call_fn(sender, _value):
trace('Uxl: call_fn %s, key=%s, value=%s' % (element, key, value))
trace('Uxl: call_fn => value=%s' % str(eval(value, {}, idmap)))
setattr(element, key, eval(value, {}, idmap))
# bind every key.value
for x in kw:
k = x.split('.')
if len(k) != 2:
continue
f = idmap[k[0]]
f.bind(**{k[1]: call_fn})
return eval(value, {}, idmap)
# is the value is a string, numeric, tuple, list ?
if value[0] in ['(', '[', '"', '\'', '-'] + range(9):
value = eval(value, {}, self.idmap)
# must be an object.property
else:
value = value.split('.', 2)
if len(value) != 2:
raise UxlError(ctx, ln, 'Reference format should '
'be <id>.<property>')
# bind
m = self.idmap[value[0]]
kw = { value[1]: create_handler(element, key) }
m.bind(**kw)
trace('Uxl: bind %s.%s to %s.%s' % (
m, value[1], element, key))
value = getattr(self.idmap[value[0]], value[1])
trace('Uxl: set %s=%s for %s' % (key, value, element))
return call_fn return call_fn
class UxlRule(object): class UxlRule(object):
@ -256,6 +298,7 @@ class UxlBase(object):
super(UxlBase, self).__init__() super(UxlBase, self).__init__()
self.rules = [] self.rules = []
self.idmap = {} self.idmap = {}
self.idmaps = []
def add_rule(self, rule, defs): def add_rule(self, rule, defs):
trace('Uxl: add rule %s' % str(rule)) trace('Uxl: add rule %s' % str(rule))
@ -285,21 +328,32 @@ class UxlBase(object):
def apply(self, widget): def apply(self, widget):
'''Apply all the Uxl rules matching the widget on the widget. '''Apply all the Uxl rules matching the widget on the widget.
''' '''
trace('Uxl: Apply uxl to %s' % widget)
matches = self.match(widget) matches = self.match(widget)
trace('Uxl: Found %d matches for %s' % (len(matches), widget)) trace('Uxl: Found %d matches for %s' % (len(matches), widget))
if not matches: if not matches:
return return
self._push_ids()
have_root = 'root' in self.idmap
if not have_root:
self.idmap['root'] = widget self.idmap['root'] = widget
for defs in matches: for defs in matches:
self.build_item(widget, defs, is_instance=True) self.build_item(widget, defs, is_instance=True)
if not have_root:
del self.idmap['root'] del self.idmap['root']
self._pop_ids()
# #
# Private # Private
# #
def _push_ids(self):
self.idmaps.append(self.idmap)
self.idmap = copy(self.idmap)
def _pop_ids(self):
self.idmap = self.idmaps.pop()
def build(self, objects): def build(self, objects):
root = None root = None
for item, params in objects: for item, params in objects:
@ -313,6 +367,8 @@ class UxlBase(object):
return root return root
def build_item(self, item, params, is_instance=False): def build_item(self, item, params, is_instance=False):
self._push_ids()
if is_instance is False: if is_instance is False:
trace('Uxl: build item %s' % item) trace('Uxl: build item %s' % item)
if item.startswith('<'): if item.startswith('<'):
@ -338,17 +394,13 @@ class UxlBase(object):
pass pass
else: else:
try: try:
value = eval(value) value = create_handler(widget, key, value, self.idmap)
''' trace('Uxl: set %s=%s for %s' % (key, value, widget))
# XXX FIXME be able to create live property
if not hasattr(widget, key):
widget.create_property(key, value)
else:
setattr(widget, key, value)
'''
setattr(widget, key, value) setattr(widget, key, value)
except Exception, e: except Exception, e:
raise UxlError(ctx, ln, str(e)) m = UxlError(ctx, ln, str(e))
print m
raise
# second loop, only for canvas # second loop, only for canvas
for key, value in params.iteritems(): for key, value in params.iteritems():
@ -358,6 +410,7 @@ class UxlBase(object):
with widget.canvas: with widget.canvas:
self.build_canvas(item, value) self.build_canvas(item, value)
self._pop_ids()
return widget return widget
def build_canvas(self, item, elements): def build_canvas(self, item, elements):
@ -369,26 +422,13 @@ class UxlBase(object):
continue continue
value, ln, ctx = value value, ln, ctx = value
try: try:
# is the value is a string, numeric, tuple, list ? value = create_handler(element, key, value, self.idmap)
if value[0] in ['(', '[', '"', '\'', '-'] + range(9):
print dir(self.idmap['self'])
value = eval(value, {}, self.idmap)
# must be an object.property
else:
value = value.split('.')
if len(value) != 2:
raise UxlError(ctx, ln, 'Reference format should '
'be <id>.<property>')
# bind
m = self.idmap[value[0]]
kw = { value[1]: create_handler(element, key) }
m.bind(**kw)
value = getattr(self.idmap[value[0]], value[1])
trace('Uxl: set %s=%s for %s' % (key, value, element)) trace('Uxl: set %s=%s for %s' % (key, value, element))
setattr(element, key, value) setattr(element, key, value)
except Exception, e: except Exception, e:
m = UxlError(ctx, ln, str(e))
print m.message
raise raise
raise UxlError(ctx, ln, str(e))
def build_rule(self, item, params): def build_rule(self, item, params):
trace('Uxl: build rule for %s' % item) trace('Uxl: build rule for %s' % item)