mirror of https://github.com/kivy/kivy.git
Merge remote-tracking branch 'upstream/master' into uix-listview
This commit is contained in:
commit
8ea94003e7
|
@ -2,8 +2,7 @@ Kivy - Documentation
|
|||
====================
|
||||
|
||||
You can access the API documentation on web :
|
||||
* last released version : http://kivy.org/docs/api
|
||||
* trunk version, updated nightly : http://kivy.org/docs/api-trunk/
|
||||
* last released version : http://kivy.org/docs/api-index.html
|
||||
|
||||
|
||||
How to build the documentation
|
||||
|
|
|
@ -249,6 +249,15 @@ Will result in:
|
|||
`:doc:` and `:mod:` are essentially the same, except for an anchor in the url,
|
||||
this makes `:doc:` prefered, for the cleaner url.
|
||||
|
||||
To build your documentation, run::
|
||||
|
||||
make html
|
||||
|
||||
If you updated your kivy install, and have some trouble compiling docs, run::
|
||||
|
||||
make clean force html
|
||||
|
||||
The doc will be generated in ``build/html``.
|
||||
|
||||
Unit tests contributions
|
||||
------------------------
|
||||
|
|
|
@ -27,8 +27,9 @@ create the UI around the ``Controller`` class in a file named `controller.kv`,
|
|||
which will be loaded when we run the ``ControllerApp``. How this is done and
|
||||
what files are loaded is described in the :func:`kivy.app.App.load_kv` method.
|
||||
|
||||
.. include:: ../../../examples/guide/designwithkv/controller.kv
|
||||
:literal:
|
||||
.. literalinclude:: ../../../examples/guide/designwithkv/controller.kv
|
||||
:language: kv
|
||||
:linenos:
|
||||
|
||||
One label and one button in a vertical ``BoxLayout``. Seems very simple. There
|
||||
are 3 things going on here:
|
||||
|
@ -52,7 +53,9 @@ are 3 things going on here:
|
|||
the current widget.
|
||||
|
||||
* You can use any id declared in the rule the same as ``root`` and
|
||||
``self``. For example, you could do this in the ``on_press()``::
|
||||
``self``. For example, you could do this in the ``on_press()``:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
Button:
|
||||
on_press: root.do_action(); my_custom_label.font_size = 18
|
||||
|
|
|
@ -13,13 +13,13 @@ Using Twisted inside Kivy
|
|||
install a twisted reactor that will run inside the kivy event loop.
|
||||
|
||||
Any arguments or keyword arguments passed to this function will be
|
||||
passed on the the threadedselect reactors interleave function, these
|
||||
passed on the threadedselect reactors interleave function, these
|
||||
are the arguments one would usually pass to twisted's reactor.startRunning
|
||||
|
||||
.. warning::
|
||||
Unlike the default twisted reactor, the installed reactor will not handle
|
||||
any signals unnless you set the 'installSignalHandlers' keyword argument
|
||||
to 1 explicitly. This is done to allow kivy to handle teh signals as
|
||||
to 1 explicitly. This is done to allow kivy to handle the signals as
|
||||
usual, unless you specifically want the twisted reactor to handle the
|
||||
signals (e.g. SIGINT).
|
||||
|
||||
|
@ -27,14 +27,15 @@ Using Twisted inside Kivy
|
|||
|
||||
The kivy examples include a small example for a twisted server and client.
|
||||
The server app has a simple twisted server running and log any messages.
|
||||
The client app can send messages to teh server and will print its message
|
||||
The client app can send messages to the server and will print its message
|
||||
and the repsonse it got. The examples are based mostly on simple Echo example
|
||||
from the twisted docs, which you can find here:
|
||||
|
||||
- http://twistedmatrix.com/documents/current/core/examples/simpleserv.py
|
||||
- http://twistedmatrix.com/documents/current/core/examples/simpleclient.py
|
||||
|
||||
To try the example run echo_server_app.py first, and then launch
|
||||
echo_client_app.py. The server will, reply with simple echo messages to
|
||||
echo_client_app.py. The server will reply with simple echo messages to
|
||||
anything the client app sends, when you hit enter after typing something
|
||||
in the textbox.
|
||||
|
||||
|
|
|
@ -74,8 +74,9 @@ called ``pong.kv`` in the same directory that will be automatically loaded
|
|||
when the application is run. So create a new file called ``*pong.kv*`` and add
|
||||
the following contents.
|
||||
|
||||
.. include:: ../../../examples/tutorials/pong/steps/step2/pong.kv
|
||||
:literal:
|
||||
.. literalinclude:: ../../../examples/tutorials/pong/steps/step2/pong.kv
|
||||
:language: kv
|
||||
:linenos:
|
||||
|
||||
If you run the app now, you should see a vertical bar in the middle, and two
|
||||
zeros where the player scores will be displayed.
|
||||
|
@ -127,7 +128,9 @@ child widgets that will be automatically added, or a `canvas` section in
|
|||
which you can add Graphics instructions that define how the widget itself is
|
||||
rendered.
|
||||
|
||||
The first block inside the ``<PongGame>`` rule we have is a canvas block::
|
||||
The first block inside the ``<PongGame>`` rule we have is a canvas block:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
<PongGame>:
|
||||
canvas:
|
||||
|
@ -150,10 +153,12 @@ score once we have the logic for that implemented. But the labels already
|
|||
look good, since we set a bigger font_size, and positioned them relatively
|
||||
to the root widget. The ``root`` keyword can be used inside child block to
|
||||
refer back to the parent/root widget the rule applies to (``PongGame`` in this
|
||||
case)::
|
||||
case):
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
<PongGame>:
|
||||
...
|
||||
# ...
|
||||
|
||||
Label:
|
||||
font_size: 70
|
||||
|
@ -207,7 +212,9 @@ Here is the python code for the PongBall class::
|
|||
self.pos = Vector(*self.velocity) + self.pos
|
||||
|
||||
|
||||
And here is the kv rule used to draw the ball as a white circle::
|
||||
And here is the kv rule used to draw the ball as a white circle:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
<PongBall>:
|
||||
size: 50, 50
|
||||
|
@ -232,8 +239,9 @@ Here is the entire updated python code and kv file for this step:
|
|||
:literal:
|
||||
|
||||
pong.kv:
|
||||
.. include:: ../../../examples/tutorials/pong/steps/step3/pong.kv
|
||||
:literal:
|
||||
.. literalinclude:: ../../../examples/tutorials/pong/steps/step3/pong.kv
|
||||
:language: kv
|
||||
:linenos:
|
||||
|
||||
|
||||
Adding ball animation
|
||||
|
@ -308,7 +316,9 @@ inside the ``update`` method and even make it bounce of the edges::
|
|||
self.ball.velocity_x *= -1
|
||||
|
||||
Don't forget to hook it up in the kv file, by giving the child widget an id
|
||||
and setting the games property to that id::
|
||||
and setting the games property to that id:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
<PongGame>:
|
||||
ball: pong_ball
|
||||
|
@ -337,8 +347,9 @@ Here is the entire code for this step:
|
|||
:literal:
|
||||
|
||||
pong.kv:
|
||||
.. include:: ../../../examples/tutorials/pong/steps/step4/pong.kv
|
||||
:literal:
|
||||
.. literalinclude:: ../../../examples/tutorials/pong/steps/step4/pong.kv
|
||||
:language: kv
|
||||
:linenos:
|
||||
|
||||
Connect input event
|
||||
-------------------
|
||||
|
@ -401,8 +412,9 @@ And here it is in context. Pretty much done:
|
|||
|
||||
pong.kv:
|
||||
|
||||
.. include:: ../../../examples/tutorials/pong/steps/step5/pong.kv
|
||||
:literal:
|
||||
.. literalinclude:: ../../../examples/tutorials/pong/steps/step5/pong.kv
|
||||
:language: kv
|
||||
:linenos:
|
||||
|
||||
|
||||
Where to go now?
|
||||
|
|
|
@ -299,8 +299,8 @@ class App(EventDispatcher):
|
|||
#: configuration. Can be used to query some config token in the build()
|
||||
self.config = None
|
||||
|
||||
#: Root widget set by the :func:`build` method or by the
|
||||
#: :func:`load_kv` method if the kv file contains a root widget.
|
||||
#: Root widget set by the :meth:`build` method or by the
|
||||
#: :meth:`load_kv` method if the kv file contains a root widget.
|
||||
self.root = None
|
||||
|
||||
def build(self):
|
||||
|
@ -440,9 +440,9 @@ class App(EventDispatcher):
|
|||
'''
|
||||
|
||||
if platform == 'android':
|
||||
defaultpath = '/sdcard/.%(appname).ini'
|
||||
defaultpath = '/sdcard/.%(appname)s.ini'
|
||||
elif platform == 'ios':
|
||||
defaultpath = '~/Documents/%(appname).ini'
|
||||
defaultpath = '~/Documents/%(appname)s.ini'
|
||||
elif platform == 'win':
|
||||
defaultpath = defaultpath.replace('/', sep)
|
||||
return expanduser(defaultpath) % {
|
||||
|
|
|
@ -316,6 +316,10 @@ class ImageLoader(object):
|
|||
# extract extensions
|
||||
ext = filename.split('.')[-1].lower()
|
||||
|
||||
# prevent url querystrings
|
||||
if filename.startswith((('http://', 'https://'))):
|
||||
ext = ext.split('?')[0]
|
||||
|
||||
# special case. When we are trying to load a "zip" file with image, we
|
||||
# will use the special zip_loader in ImageLoader. This might return a
|
||||
# sequence of images contained in the zip.
|
||||
|
@ -565,7 +569,10 @@ class Image(EventDispatcher):
|
|||
if image:
|
||||
# we found an image, yeah ! but reset the texture now.
|
||||
self.image = image
|
||||
if not image.keep_data and self._keep_data:
|
||||
# if image.__class__ is core image then it's a texture
|
||||
# from atlas or other sources and has no data so skip
|
||||
if (image.__class__ != self.__class__ and
|
||||
not image.keep_data and self._keep_data):
|
||||
self.remove_from_cache()
|
||||
self._filename = ''
|
||||
self._set_filename(value)
|
||||
|
|
|
@ -287,6 +287,8 @@ class LabelBase(object):
|
|||
|
||||
# calculate the word width
|
||||
ww, wh = 0, 0
|
||||
if word == '':
|
||||
ww, wh = get_extents(' ')
|
||||
for glyph in word:
|
||||
gw, gh = cache[glyph]
|
||||
ww += gw
|
||||
|
|
|
@ -198,6 +198,7 @@ class MarkupLabel(MarkupLabelBase):
|
|||
|
||||
# verify that each glyph have size
|
||||
glyphs = list(set(word))
|
||||
glyphs.append(' ')
|
||||
get_extents = self.get_extents
|
||||
for glyph in glyphs:
|
||||
if not glyph in cache:
|
||||
|
@ -219,7 +220,7 @@ class MarkupLabel(MarkupLabelBase):
|
|||
for part in re.split(r'( |\n)', word):
|
||||
|
||||
if part == '':
|
||||
continue
|
||||
part = ' '
|
||||
|
||||
if part == '\n':
|
||||
# put a new line!
|
||||
|
@ -266,7 +267,7 @@ class MarkupLabel(MarkupLabelBase):
|
|||
y = 0
|
||||
w, h = self._size
|
||||
refs = self._refs
|
||||
no_of_lines = len(self._lines)
|
||||
txt_height = sum(line[1] for line in self._lines)
|
||||
|
||||
for line in self._lines:
|
||||
lh = line[1]
|
||||
|
@ -283,9 +284,9 @@ class MarkupLabel(MarkupLabelBase):
|
|||
# vertical alignement
|
||||
if y == 0:
|
||||
if av == 1:
|
||||
y = int((h - (lh*no_of_lines))/2)
|
||||
y = int((h - txt_height)/2)
|
||||
elif av == 2:
|
||||
y = h - (lh*(no_of_lines))
|
||||
y = h - (txt_height)
|
||||
|
||||
|
||||
for pw, ph, part, options in line[2]:
|
||||
|
|
|
@ -206,10 +206,7 @@ class MouseMotionEventProvider(MotionEventProvider):
|
|||
self.remove_touch(cur)
|
||||
self.current_drag = None
|
||||
|
||||
width, height = EventLoop.window.system_size
|
||||
rx = x / float(width)
|
||||
ry = 1. - y / float(height)
|
||||
cur = self.find_touch(rx, ry)
|
||||
cur = self.current_drag
|
||||
if (button in ('left', 'scrollup', 'scrolldown') or
|
||||
self.disable_multitouch) and cur and not ('ctrl' in modifiers):
|
||||
self.remove_touch(cur)
|
||||
|
|
|
@ -105,7 +105,7 @@ from functools import partial
|
|||
class RecorderMotionEvent(MotionEvent):
|
||||
|
||||
def depack(self, args):
|
||||
for key, value in args.iteritems():
|
||||
for key, value in args.items():
|
||||
setattr(self, key, value)
|
||||
super(RecorderMotionEvent, self).depack(args)
|
||||
|
||||
|
@ -183,10 +183,10 @@ class Recorder(EventDispatcher):
|
|||
def on_motion(self, window, etype, motionevent):
|
||||
if not self.record:
|
||||
return
|
||||
args = {}
|
||||
for arg in self.record_attrs:
|
||||
if hasattr(motionevent, arg):
|
||||
args[arg] = getattr(motionevent, arg)
|
||||
|
||||
args = dict((arg, getattr(motionevent, arg))
|
||||
for arg in self.record_attrs if hasattr(motionevent, arg))
|
||||
|
||||
args['profile'] = [x for x in motionevent.profile if x in
|
||||
self.record_profile_mask]
|
||||
self.record_fd.write('%r\n' % (
|
||||
|
@ -200,7 +200,7 @@ class Recorder(EventDispatcher):
|
|||
(time() - self.record_time, etype, 0, {
|
||||
'key': key,
|
||||
'scancode': kwargs.get('scancode'),
|
||||
'codepoint': kwargs.get('codepoint') or kwargs.get('unicode'),
|
||||
'codepoint': kwargs.get('codepoint', kwargs.get('unicode')),
|
||||
'modifier': kwargs.get('modifier'),
|
||||
'is_touch': False}), ))
|
||||
self.counter += 1
|
||||
|
@ -263,12 +263,12 @@ class Recorder(EventDispatcher):
|
|||
EventLoop.add_input_provider(self)
|
||||
|
||||
def update(self, dispatch_fn):
|
||||
if len(self.play_data) == 0:
|
||||
if not self.play_data:
|
||||
Logger.info('Recorder: Playing finished.')
|
||||
self.play = False
|
||||
|
||||
dt = time() - self.play_time
|
||||
while len(self.play_data):
|
||||
while self.play_data:
|
||||
event = self.play_data[0]
|
||||
assert(len(event) == 4)
|
||||
if event[0] > dt:
|
||||
|
@ -290,21 +290,21 @@ class Recorder(EventDispatcher):
|
|||
'on_key_down',
|
||||
args['key'],
|
||||
args['scancode'],
|
||||
args['codepoint'] or args['unicode'],
|
||||
args['codepoint'],
|
||||
args['modifier'])
|
||||
elif etype == 'keyup':
|
||||
self.window.dispatch(
|
||||
'on_key_up',
|
||||
args['key'],
|
||||
args['scancode'],
|
||||
args['codepoint'] or args['unicode'],
|
||||
args['codepoint'],
|
||||
args['modifier'])
|
||||
elif etype == 'keyboard':
|
||||
self.window.dispatch(
|
||||
'on_keyboard',
|
||||
args['key'],
|
||||
args['scancode'],
|
||||
args['codepoint'] or args['unicode'],
|
||||
args['codepoint'],
|
||||
args['modifier'])
|
||||
|
||||
if me:
|
||||
|
|
|
@ -127,6 +127,20 @@ class FileChooserController(FloatLayout):
|
|||
'''Base for implementing a FileChooser. Don't use that class directly,
|
||||
preferring to use an implementation like :class:`FileChooserListView` or
|
||||
:class:`FileChooserIconView`.
|
||||
|
||||
:Events:
|
||||
`on_entry_added`: entry, parent
|
||||
Fired when a root-level entry is added to the file list.
|
||||
`on_entries_cleared`
|
||||
Fired when the the entries list is cleared. Usally when the
|
||||
root is refreshed.
|
||||
`on_subentry_to_entry`: entry, parent
|
||||
Fired when a sub-entry is added to an existing entry.
|
||||
`on_remove_subentry`: entry, parent
|
||||
Fired when entries are removed from an entry. Usually when
|
||||
a node is closed.
|
||||
`on_submit`: selection, touch
|
||||
Fired when a file has been selected with a double-tap.
|
||||
'''
|
||||
_ENTRY_TEMPLATE = None
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class Image(Widget):
|
|||
source = StringProperty(None)
|
||||
'''Filename / source of your image.
|
||||
|
||||
:data:`source` a :class:`~kivy.properties.StringProperty`, default to None.
|
||||
:data:`source` is a :class:`~kivy.properties.StringProperty`, default to None.
|
||||
'''
|
||||
|
||||
texture = ObjectProperty(None, allownone=True)
|
||||
|
|
|
@ -169,7 +169,7 @@ class Label(Widget):
|
|||
def texture_update(self, *largs):
|
||||
'''Force texture recreation with the current Label properties.
|
||||
|
||||
After this function call, the :data:`texture` and :data`texture_size`
|
||||
After this function call, the :data:`texture` and :data:`texture_size`
|
||||
will be updated in this order.
|
||||
'''
|
||||
self.texture = None
|
||||
|
@ -365,7 +365,7 @@ class Label(Widget):
|
|||
|
||||
The :data:`texture` update is scheduled for the next frame. If you need
|
||||
the texture immediately after changing a property, you have to call
|
||||
the :func:`texture_update` function before accessing :data:`texture`::
|
||||
the :meth:`texture_update` method before accessing :data:`texture`::
|
||||
|
||||
l = Label(text='Hello world')
|
||||
# l.texture is good
|
||||
|
@ -383,9 +383,9 @@ class Label(Widget):
|
|||
|
||||
.. warning::
|
||||
|
||||
The data:`texture_size` is set after the :data:`texture` property. If
|
||||
The :data:`texture_size` is set after the :data:`texture` property. If
|
||||
you listen for changes to :data:`texture`, :data:`texture_size` will not
|
||||
be up-to-date in your callback. Bind to data:`texture_size` instead.
|
||||
be up-to-date in your callback. Bind to :data:`texture_size` instead.
|
||||
'''
|
||||
|
||||
mipmap = BooleanProperty(False)
|
||||
|
|
|
@ -64,7 +64,7 @@ class Layout(Widget):
|
|||
def do_layout(self, *largs):
|
||||
'''This function is called when a layout is needed, by a trigger.
|
||||
If you are doing a new Layout subclass, don't call this function
|
||||
directly, use :data:`_trigger_layout` instead.
|
||||
directly, use :meth:`_trigger_layout` instead.
|
||||
|
||||
.. versionadded:: 1.0.8
|
||||
'''
|
||||
|
@ -72,13 +72,12 @@ class Layout(Widget):
|
|||
|
||||
def add_widget(self, widget, index=0):
|
||||
widget.bind(
|
||||
size = self._trigger_layout,
|
||||
size_hint = self._trigger_layout)
|
||||
size=self._trigger_layout,
|
||||
size_hint=self._trigger_layout)
|
||||
return super(Layout, self).add_widget(widget, index)
|
||||
|
||||
def remove_widget(self, widget):
|
||||
widget.unbind(
|
||||
size = self._trigger_layout,
|
||||
size_hint = self._trigger_layout)
|
||||
size=self._trigger_layout,
|
||||
size_hint=self._trigger_layout)
|
||||
return super(Layout, self).remove_widget(widget)
|
||||
|
||||
|
|
|
@ -434,7 +434,7 @@ class RstDocument(ScrollView):
|
|||
|
||||
toctrees = DictProperty({})
|
||||
'''Toctree of all loaded or preloaded documents. This dictionary is filled
|
||||
when a rst document is explicitly loaded, or where :func:`preload` has been
|
||||
when a rst document is explicitly loaded, or where :meth:`preload` has been
|
||||
called.
|
||||
|
||||
If the document has no filename, e.g., when the document is loaded from a
|
||||
|
|
|
@ -21,8 +21,8 @@ constraints that you should consider:
|
|||
|
||||
For touch events, the scatter converts from the parent matrix to the scatter matrix
|
||||
automatically in on_touch_down/move/up events. If you are doing things
|
||||
manually, you will need to use :func:`~kivy.uix.widget.Widget.to_parent`,
|
||||
:func:`~kivy.uix.widget.Widget.to_local`.
|
||||
manually, you will need to use :meth:`~kivy.uix.widget.Widget.to_parent`,
|
||||
:meth:`~kivy.uix.widget.Widget.to_local`.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
|
|
@ -115,9 +115,10 @@ __all__ = ('Screen', 'ScreenManager', 'ScreenManagerException',
|
|||
'TransitionBase', 'ShaderTransition', 'SlideTransition', 'SwapTransition',
|
||||
'FadeTransition', 'WipeTransition')
|
||||
|
||||
from kivy.logger import Logger
|
||||
from kivy.event import EventDispatcher
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.properties import StringProperty, ObjectProperty, \
|
||||
from kivy.properties import StringProperty, ObjectProperty, AliasProperty, \
|
||||
NumericProperty, ListProperty, OptionProperty, BooleanProperty
|
||||
from kivy.animation import Animation, AnimationTransition
|
||||
from kivy.uix.relativelayout import RelativeLayout
|
||||
|
@ -242,6 +243,8 @@ class TransitionBase(EventDispatcher):
|
|||
'''(internal) Start the transition. This is automatically called by the
|
||||
:class:`ScreenManager`.
|
||||
'''
|
||||
if self.is_active:
|
||||
raise ScreenManagerException('start() is called twice!')
|
||||
self.manager = manager
|
||||
self._anim = Animation(d=self.duration, s=0)
|
||||
self._anim.bind(on_progress=self._on_progress,
|
||||
|
@ -560,21 +563,37 @@ class ScreenManager(FloatLayout):
|
|||
default to None, read-only.
|
||||
'''
|
||||
|
||||
def _get_screen_names(self):
|
||||
return [s.name for s in self.screens]
|
||||
|
||||
screen_names = AliasProperty(_get_screen_names,
|
||||
None, bind=('screens', ))
|
||||
'''List of the names of all the :class:`Screen` widgets added. The list
|
||||
is read only.
|
||||
|
||||
:data:`screens_names` is a :class:`~kivy.properties.AliasProperty`,
|
||||
it is read-only and updated if the screen list changes, or the name
|
||||
of a screen changes.
|
||||
'''
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ScreenManager, self).__init__(**kwargs)
|
||||
self.bind(pos=self._update_pos)
|
||||
|
||||
def _screen_name_changed(self, screen, name):
|
||||
self.property('screen_names').dispatch(self)
|
||||
if screen == self.current_screen:
|
||||
self.current = name
|
||||
|
||||
def add_widget(self, screen):
|
||||
if not isinstance(screen, Screen):
|
||||
raise ScreenManagerException(
|
||||
'ScreenManager accept only Screen widget.')
|
||||
if screen.name in [s.name for s in self.screens]:
|
||||
raise ScreenManagerException(
|
||||
'Name %r already used' % screen.name)
|
||||
if screen.manager:
|
||||
raise ScreenManagerException(
|
||||
'Screen already managed by another ScreenManager.')
|
||||
screen.manager = self
|
||||
screen.bind(name=self._screen_name_changed)
|
||||
self.screens.append(screen)
|
||||
if self.current is None:
|
||||
self.current = screen.name
|
||||
|
@ -592,6 +611,8 @@ class ScreenManager(FloatLayout):
|
|||
screen = self.get_screen(value)
|
||||
if not screen:
|
||||
return
|
||||
if screen == self.current_screen:
|
||||
return
|
||||
|
||||
previous_screen = self.current_screen
|
||||
self.current_screen = screen
|
||||
|
@ -608,9 +629,13 @@ class ScreenManager(FloatLayout):
|
|||
'''Return the screen widget associated to the name, or None if not
|
||||
found.
|
||||
'''
|
||||
for screen in self.screens:
|
||||
if screen.name == name:
|
||||
return screen
|
||||
matches = [s for s in self.screens if s.name == name]
|
||||
num_matches = len(matches)
|
||||
if num_matches == 0:
|
||||
raise ScreenManagerException('No Screen with name "%s".' % name)
|
||||
if num_matches > 1:
|
||||
Logger.warn('Multiple screens named "%s": %s' % (name, matches))
|
||||
return matches[0]
|
||||
|
||||
def next(self):
|
||||
'''Return the name of the next screen from the screen list.
|
||||
|
|
|
@ -84,7 +84,7 @@ pairs to the properties of that class, i.e., "title": "Windows" sets the
|
|||
:data:`SettingTitle.title` property to "Windows".
|
||||
|
||||
To load the JSON example to a :class:`Settings` instance, use the
|
||||
:data:`Settings.add_json_panel` method. It will automatically instantiate
|
||||
:meth:`Settings.add_json_panel` method. It will automatically instantiate
|
||||
:class:`SettingsPanel` and add it to :class:`Settings`::
|
||||
|
||||
from kivy.config import ConfigParser
|
||||
|
|
|
@ -97,8 +97,8 @@ class Spinner(Button):
|
|||
is_open = BooleanProperty(False)
|
||||
'''By default, the spinner is not open. Set to true to open it.
|
||||
|
||||
:data: `is_open` is a :class: `~kivy.properties.BooleanProperty`,
|
||||
default to False.
|
||||
:data:`is_open` is a :class:`~kivy.properties.BooleanProperty`, default to
|
||||
False.
|
||||
|
||||
.. versionadded:: 1.4.0
|
||||
'''
|
||||
|
|
|
@ -543,7 +543,7 @@ class TreeView(Widget):
|
|||
|
||||
selected_node = AliasProperty(get_selected_node, None,
|
||||
bind=('_selected_node', ))
|
||||
'''Node selected by :func:`TreeView.select_node`, or by touch.
|
||||
'''Node selected by :meth:`TreeView.select_node`, or by touch.
|
||||
|
||||
:data:`selected_node` is a :class:`~kivy.properties.AliasProperty`, defaults
|
||||
to None, and is read-only.
|
||||
|
|
|
@ -128,6 +128,12 @@ class VKeyboard(Scatter):
|
|||
VKeyboard is an onscreen keyboard with multitouch support.
|
||||
Its layout is entirely customizable and you can switch between available
|
||||
layouts using a button in the bottom right of the widget.
|
||||
|
||||
:Events:
|
||||
`on_key_down`: keycode, internal, modifiers
|
||||
Fired when the keyboard received a key down event (key press).
|
||||
`on_key_up`: keycode, internal, modifiers
|
||||
Fired when the keyboard received a key up event (key release).
|
||||
'''
|
||||
|
||||
target = ObjectProperty(None, allownone=True)
|
||||
|
@ -434,7 +440,6 @@ class VKeyboard(Scatter):
|
|||
# the goal now is to map both point, calculate the diff between them
|
||||
diff = dpos - cpos
|
||||
|
||||
|
||||
# we still have an issue, self.pos represent the bounding box, not the
|
||||
# 0,0 coordinate of the scatter. we need to apply also the diff between
|
||||
# them (inside and outside coordinate matrix). It's hard to explain, but
|
||||
|
@ -582,7 +587,7 @@ class VKeyboard(Scatter):
|
|||
key_nb = 0
|
||||
for pos, size in layout_geometry['LINE_%d' % line_nb]:
|
||||
# retrieve the relative text
|
||||
text = layout[layout_mode +'_'+ str(line_nb)][key_nb][0]
|
||||
text = layout[layout_mode + '_' + str(line_nb)][key_nb][0]
|
||||
l = Label(text=text, font_size=font_size, pos=pos, size=size,
|
||||
font_name=self.font_name)
|
||||
self.add_widget(l)
|
||||
|
@ -604,8 +609,8 @@ class VKeyboard(Scatter):
|
|||
mtop, mright, mbottom, mleft = self.margin_hint
|
||||
|
||||
# get the line of the layout
|
||||
e_height = h - (mbottom + mtop) * h # efficient height in pixels
|
||||
line_height = e_height / layout_rows # line height in px
|
||||
e_height = h - (mbottom + mtop) * h # efficient height in pixels
|
||||
line_height = e_height / layout_rows # line height in px
|
||||
y = y - mbottom * h
|
||||
line_nb = layout_rows - int(y / line_height)
|
||||
|
||||
|
@ -616,13 +621,13 @@ class VKeyboard(Scatter):
|
|||
|
||||
# get the key within the line
|
||||
key_index = ''
|
||||
current_key_index =0
|
||||
current_key_index = 0
|
||||
for key in layout_geometry['LINE_HINT_%d' % line_nb]:
|
||||
if x_hint >= key[0][0] and x_hint < key[0][0] + key[1][0]:
|
||||
key_index = current_key_index
|
||||
break
|
||||
else:
|
||||
current_key_index +=1
|
||||
current_key_index += 1
|
||||
if key_index == '':
|
||||
return None
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@ Our widget class is designed with a couple of principles in mind:
|
|||
Often you want to know if a certain point is within the bounds of your
|
||||
widget. An example would be a button widget where you want to only
|
||||
trigger an action when the button itself is actually touched.
|
||||
For this, you can use the :func:`Widget.collide_point` method, which
|
||||
For this, you can use the :meth:`Widget.collide_point` method, which
|
||||
will return True if the point you pass it is inside the axis-aligned
|
||||
bounding box defined by the widget's position and size.
|
||||
If a simple AABB is not sufficient, you can override the method to
|
||||
perform the collision checks with more complex shapes, e.g., a polygon.
|
||||
You can also check if a widget collides with another widget with
|
||||
:func:`Widget.collide_widget`.
|
||||
:meth:`Widget.collide_widget`.
|
||||
|
||||
Using Properties
|
||||
----------------
|
||||
|
@ -187,7 +187,7 @@ class Widget(EventDispatcher):
|
|||
def on_touch_move(self, touch):
|
||||
'''Receive a touch move event.
|
||||
|
||||
See :func:`on_touch_down` for more information
|
||||
See :meth:`on_touch_down` for more information
|
||||
'''
|
||||
for child in self.children[:]:
|
||||
if child.dispatch('on_touch_move', touch):
|
||||
|
@ -196,7 +196,7 @@ class Widget(EventDispatcher):
|
|||
def on_touch_up(self, touch):
|
||||
'''Receive a touch up event.
|
||||
|
||||
See :func:`on_touch_down` for more information
|
||||
See :meth:`on_touch_down` for more information
|
||||
'''
|
||||
for child in self.children[:]:
|
||||
if child.dispatch('on_touch_up', touch):
|
||||
|
@ -468,7 +468,7 @@ class Widget(EventDispatcher):
|
|||
:data:`children` is a :class:`~kivy.properties.ListProperty` instance,
|
||||
default to an empty list.
|
||||
|
||||
Use :func:`add_widget` and :func:`remove_widget` for manipulating the
|
||||
Use :meth:`add_widget` and :meth:`remove_widget` for manipulating the
|
||||
children list. Don't manipulate the children list directly until you know
|
||||
what you are doing.
|
||||
'''
|
||||
|
|
7
setup.py
7
setup.py
|
@ -325,6 +325,9 @@ setup(
|
|||
'kivy.tools',
|
||||
'kivy.tools.packaging',
|
||||
'kivy.tools.packaging.pyinstaller_hooks',
|
||||
'kivy.tools.highlight',
|
||||
'kivy.tools.highlight.pygments',
|
||||
'kivy.tools.extensions',
|
||||
'kivy.uix', ],
|
||||
package_dir={'kivy': 'kivy'},
|
||||
package_data={'kivy': [
|
||||
|
@ -340,10 +343,14 @@ setup(
|
|||
'data/glsl/*.png',
|
||||
'data/glsl/*.vs',
|
||||
'data/glsl/*.fs',
|
||||
'tools/highlight/*.vim',
|
||||
'tools/highlight/*.el',
|
||||
'tools/packaging/README.txt',
|
||||
'tools/packaging/win32/kivy.bat',
|
||||
'tools/packaging/win32/kivyenv.sh',
|
||||
'tools/packaging/win32/README.txt',
|
||||
'tools/packaging/osx/Info.plist',
|
||||
'tools/packaging/osx/InfoPlist.strings',
|
||||
'tools/packaging/osx/kivy.sh']},
|
||||
data_files=examples.items(),
|
||||
classifiers=[
|
||||
|
|
Loading…
Reference in New Issue