mirror of https://github.com/kivy/kivy.git
Add #:include directive. Implement circular reference guarding and sanity checks.
This commit is contained in:
parent
ec7685e132
commit
a875b6bc91
|
@ -0,0 +1,9 @@
|
|||
#:kivy 1.8.0
|
||||
|
||||
<SpecialButton>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1.0, 0.0, 0.0, 1.0
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: (self.size[0]/4, self.size[1]/4)
|
|
@ -0,0 +1,6 @@
|
|||
#:kivy 1.8.0
|
||||
#:include button.kv
|
||||
|
||||
<CustomLayout>:
|
||||
SpecialButton:
|
||||
text: 'Includes!'
|
|
@ -0,0 +1,20 @@
|
|||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.button import Button
|
||||
|
||||
|
||||
class SpecialButton(Button):
|
||||
pass
|
||||
|
||||
|
||||
class CustomLayout(BoxLayout):
|
||||
pass
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
def build(self):
|
||||
return Builder.load_file('layout.kv')
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
|
@ -0,0 +1,4 @@
|
|||
#:kivy 1.8.0
|
||||
#:include layout.kv
|
||||
|
||||
CustomLayout:
|
50
kivy/lang.py
50
kivy/lang.py
|
@ -618,7 +618,43 @@ Set a key that will be available anywhere in the kv. For example:
|
|||
canvas:
|
||||
Color:
|
||||
rgb: my_color if self.state == 'normal' else my_color_hl
|
||||
|
||||
include <file>
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
Syntax:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
#:include <file>
|
||||
|
||||
Includes an external kivy file. This allows you to split complex
|
||||
widgets into their own files. For example:
|
||||
|
||||
.. code-block:: kv
|
||||
# Test.kv
|
||||
#:include mybutton.kv
|
||||
|
||||
<Rule>:
|
||||
state: 'normal'
|
||||
MyButton:
|
||||
text: 'Includes!'
|
||||
|
||||
.. code-block:: kv
|
||||
# mybutton.kv
|
||||
|
||||
<MyButton>:
|
||||
canvas:
|
||||
Color:
|
||||
rgb: (1.0, 0.0, 0.0)
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: (self.size[0]/4, self.size[1]/4)
|
||||
|
||||
'''
|
||||
import os
|
||||
|
||||
__all__ = ('Builder', 'BuilderBase', 'BuilderException',
|
||||
'Parser', 'ParserException')
|
||||
|
@ -652,6 +688,9 @@ Instruction = None
|
|||
# register cache for creating new classtype (template)
|
||||
Cache.register('kv.lang')
|
||||
|
||||
# all previously included files
|
||||
__INCLUDES__ = []
|
||||
|
||||
# precompile regexp expression
|
||||
lang_str = re.compile('([\'"][^\'"]*[\'"])')
|
||||
lang_key = re.compile('([a-zA-Z_]+)')
|
||||
|
@ -1006,6 +1045,7 @@ class Parser(object):
|
|||
self.parse(content)
|
||||
|
||||
def execute_directives(self):
|
||||
global __INCLUDES__
|
||||
for ln, cmd in self.directives:
|
||||
cmd = cmd.strip()
|
||||
if __debug__:
|
||||
|
@ -1027,7 +1067,15 @@ class Parser(object):
|
|||
Logger.exception('')
|
||||
raise ParserException(self, ln, 'Invalid value')
|
||||
global_idmap[name] = value
|
||||
|
||||
elif cmd[:8] == 'include ':
|
||||
ref = cmd[8:].strip()
|
||||
if not os.path.isfile(ref):
|
||||
raise ParserException(self, ln, 'Invalid or unknown file: {0}'.format(ref))
|
||||
if ref in __INCLUDES__:
|
||||
raise ParserException(self, ln, 'Circular reference: {0} is already included!'.format(ref))
|
||||
Logger.debug('Including file: {0}'.format(0))
|
||||
__INCLUDES__.append(ref)
|
||||
Builder.load_file(ref)
|
||||
elif cmd[:7] == 'import ':
|
||||
package = cmd[7:].strip()
|
||||
l = package.split(' ')
|
||||
|
|
Loading…
Reference in New Issue