mirror of https://github.com/kivy/kivy.git
Merge branch 'master' of ssh://github.com/kivy/kivy
This commit is contained in:
commit
4a70238fca
|
@ -10,6 +10,12 @@ Create a package for Android
|
|||
|
||||
.. _Packaging your application into APK:
|
||||
|
||||
TestDrive
|
||||
---------
|
||||
There is a VirtualBox Image we provide with the prerequisites along with
|
||||
Android SDK and NDK preinstalled to ease your installation woes. You can
|
||||
download it from `here <http://www.google.com/url?sa=D&q=https://docs.google.com/file/d/0B1WO07-OL50_VDNESDRUaDhXSmM/edit&usg=AFQjCNGrsg0SU8EMgAcLHWxbjSe8KM2kyA>`_.
|
||||
|
||||
Packaging your application into APK
|
||||
-----------------------------------
|
||||
|
||||
|
@ -29,7 +35,7 @@ First, follow the prerequisites needed for the project:
|
|||
|
||||
http://python-for-android.readthedocs.org/en/latest/prerequisites/
|
||||
|
||||
Then a console, and type::
|
||||
Then open a console, and type::
|
||||
|
||||
git clone git://github.com/kivy/python-for-android
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@ class TestApp(App):
|
|||
|
||||
def build(self):
|
||||
# create a button, and attach animate() method as a on_press handler
|
||||
button = Button(size_hint=(None, None), text='plop')
|
||||
button.bind(on_press=self.animate)
|
||||
button = Button(size_hint=(None, None), text='plop', on_press=self.animate)
|
||||
return button
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -34,14 +34,14 @@ class StressCanvasApp(App):
|
|||
|
||||
label = Label(text='0')
|
||||
|
||||
btn_add100 = Button(text='+ 100 rects')
|
||||
btn_add100.bind(on_press=partial(self.add_rects, label, wid, 100))
|
||||
btn_add100 = Button(text='+ 100 rects',
|
||||
on_press=partial(self.add_rects, label, wid, 100))
|
||||
|
||||
btn_add500 = Button(text='+ 500 rects')
|
||||
btn_add500.bind(on_press=partial(self.add_rects, label, wid, 500))
|
||||
btn_add500 = Button(text='+ 500 rects',
|
||||
on_press=partial(self.add_rects, label, wid, 500))
|
||||
|
||||
btn_reset = Button(text='Reset')
|
||||
btn_reset.bind(on_press=partial(self.reset_rects, label, wid))
|
||||
btn_reset = Button(text='Reset',
|
||||
on_press=partial(self.reset_rects, label, wid))
|
||||
|
||||
layout = BoxLayout(size_hint=(1, None), height=50)
|
||||
layout.add_widget(btn_add100)
|
||||
|
|
|
@ -259,8 +259,8 @@ class ShowcaseApp(App):
|
|||
auto_dismiss=False)
|
||||
btnclose.bind(on_release=popup.dismiss)
|
||||
button = Button(text='Open popup', size_hint=(None, None),
|
||||
size=('150sp', '70dp'))
|
||||
button.bind(on_release=popup.open)
|
||||
size=('150sp', '70dp'),
|
||||
on_release=popup.open)
|
||||
popup.open()
|
||||
col = AnchorLayout()
|
||||
col.add_widget(button)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
'''
|
||||
Carousel example with button inside.
|
||||
This is a tiny test for testing the scroll distance/timeout
|
||||
And ensure the down/up are dispatched if no gesture is done.
|
||||
'''
|
||||
from kivy.uix.carousel import Carousel
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
<Page>:
|
||||
cols: 3
|
||||
Label:
|
||||
text: str(id(root))
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
''')
|
||||
|
||||
class Page(GridLayout):
|
||||
pass
|
||||
|
||||
class TestApp(App):
|
||||
def build(self):
|
||||
root = Carousel()
|
||||
for x in xrange(10):
|
||||
root.add_widget(Page())
|
||||
return root
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
|
@ -22,8 +22,7 @@ class CustomPopup(Popup):
|
|||
|
||||
class TestApp(App):
|
||||
def build(self):
|
||||
b = Button()
|
||||
b.bind(on_press=self.show_popup)
|
||||
b = Button(on_press=self.show_popup)
|
||||
return b
|
||||
|
||||
def show_popup(self, b):
|
||||
|
|
|
@ -11,15 +11,15 @@ To see a list of the available screenid, just run::
|
|||
|
||||
Simulate a medium-density screen as Motolora Droid 2::
|
||||
|
||||
python main.py -m screen,droid2
|
||||
python main.py -m screen:droid2
|
||||
|
||||
Simulate a high-density screen as HTC One X, in portrait::
|
||||
|
||||
python main.py -m screen,onex,portrait
|
||||
python main.py -m screen:onex,portrait
|
||||
|
||||
Simulate the iPad 2 screen::
|
||||
|
||||
python main.py -m screen,ipad
|
||||
python main.py -m screen:ipad
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
|
|
@ -23,10 +23,18 @@ Example::
|
|||
|
||||
Example1().run()
|
||||
|
||||
.. versionchanged:: 1.5.0
|
||||
|
||||
The carousel now support active children, as
|
||||
:class:`~kivy.uix.scrollview.ScrollView`. It will detect a swipe gesture
|
||||
according to :data:`Carousel.scroll_timeout` and
|
||||
:data:`Carousel.scroll_distance`.
|
||||
'''
|
||||
|
||||
__all__ = ('Carousel', )
|
||||
|
||||
from functools import partial
|
||||
from kivy.clock import Clock
|
||||
from kivy.factory import Factory
|
||||
from kivy.animation import Animation
|
||||
from kivy.uix.stencilview import StencilView
|
||||
|
@ -166,13 +174,37 @@ class Carousel(StencilView):
|
|||
:data:`previous_slide` is a :class:`~kivy.properties.AliasProperty`.
|
||||
'''
|
||||
|
||||
scroll_timeout = NumericProperty(200)
|
||||
'''Timeout allowed to trigger the :data:`scroll_distance`, in milliseconds.
|
||||
If the user has not moved :data:`scroll_distance` within the timeout,
|
||||
the scrolling will be disabled, and the touch event will go to the children.
|
||||
|
||||
:data:`scroll_timeout` is a :class:`~kivy.properties.NumericProperty`,
|
||||
default to 200 (milliseconds)
|
||||
|
||||
.. versionadded:: 1.5.0
|
||||
'''
|
||||
|
||||
scroll_distance = NumericProperty('20dp')
|
||||
'''Distance to move before scrolling the :class:`ScrollView`, in pixels. As
|
||||
soon as the distance has been traveled, the :class:`ScrollView` will start
|
||||
to scroll, and no touch event will go to children.
|
||||
It is advisable that you base this value on the dpi of your target device's
|
||||
screen.
|
||||
|
||||
:data:`scroll_distance` is a :class:`~kivy.properties.NumericProperty`,
|
||||
default to 20dp.
|
||||
|
||||
.. versionadded:: 1.5.0
|
||||
'''
|
||||
|
||||
#### private properties, for internal use only ###
|
||||
_index = NumericProperty(0)
|
||||
_prev = ObjectProperty(None, allownone=True)
|
||||
_current = ObjectProperty(None, allownone=True)
|
||||
_next = ObjectProperty(None, allownone=True)
|
||||
_offset = NumericProperty(0)
|
||||
_drag_touches = ListProperty([])
|
||||
_touch = ObjectProperty(None, allownone=True)
|
||||
|
||||
def _insert_visible_slides(self):
|
||||
self._prev = self.previous_slide
|
||||
|
@ -248,10 +280,8 @@ class Carousel(StencilView):
|
|||
if self._offset >= self.height:
|
||||
self.index = self.index + 1
|
||||
|
||||
def on__drag_touches(self, *args):
|
||||
def _start_animation(self, *args):
|
||||
Animation.cancel_all(self)
|
||||
if self._drag_touches:
|
||||
return
|
||||
|
||||
# compute target offset for ease back, next or prev
|
||||
new_offset = 0
|
||||
|
@ -282,35 +312,98 @@ class Carousel(StencilView):
|
|||
anim = Animation(_offset=new_offset, d=dur, t='out_quad')
|
||||
anim.start(self)
|
||||
|
||||
def _get_uid(self, prefix='sv'):
|
||||
return '{0}.{1}'.format(prefix, self.uid)
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
if not self.collide_point(*touch.pos):
|
||||
touch.ud[self._get_uid('cavoid')] = True
|
||||
return
|
||||
if not super(Carousel, self).on_touch_down(touch):
|
||||
self._drag_touches.append(touch.uid)
|
||||
touch.grab(self)
|
||||
if self._touch:
|
||||
return super(Carousel, self).on_touch_down(touch)
|
||||
Animation.cancel_all(self)
|
||||
self._touch = touch
|
||||
uid = self._get_uid()
|
||||
touch.grab(self)
|
||||
touch.ud[uid] = {
|
||||
'mode': 'unknown',
|
||||
'time': touch.time_start}
|
||||
Clock.schedule_once(self._change_touch_mode,
|
||||
self.scroll_timeout / 1000.)
|
||||
return True
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
if touch.grab_current is self:
|
||||
if self._drag_touches.index(touch.uid) > 0:
|
||||
return True
|
||||
if self.direction in ['right', 'left']:
|
||||
self._offset += touch.dx
|
||||
if self.direction in ['top', 'bottom']:
|
||||
self._offset += touch.dy
|
||||
if self._get_uid('cavoid') in touch.ud:
|
||||
return
|
||||
if self._touch is not touch:
|
||||
super(Carousel, self).on_touch_move(touch)
|
||||
return self._get_uid() in touch.ud
|
||||
if touch.grab_current is not self:
|
||||
return True
|
||||
|
||||
if self.collide_point(*touch.pos):
|
||||
return super(Carousel, self).on_touch_move(touch)
|
||||
ud = touch.ud[self._get_uid()]
|
||||
direction = self.direction
|
||||
if ud['mode'] == 'unknown':
|
||||
if direction in ('right', 'left'):
|
||||
distance = abs(touch.ox - touch.x)
|
||||
else:
|
||||
distance = abs(touch.oy - touch.y)
|
||||
if distance > self.scroll_distance:
|
||||
Clock.unschedule(self._change_touch_mode)
|
||||
ud['mode'] = 'scroll'
|
||||
else:
|
||||
if direction in ('right', 'left'):
|
||||
self._offset += touch.dx
|
||||
if direction in ('top', 'bottom'):
|
||||
self._offset += touch.dy
|
||||
return True
|
||||
|
||||
def on_touch_up(self, touch):
|
||||
if touch.grab_current is self:
|
||||
self._drag_touches.remove(touch.uid)
|
||||
if self._get_uid('cavoid') in touch.ud:
|
||||
return
|
||||
if self in [x() for x in touch.grab_list]:
|
||||
touch.ungrab(self)
|
||||
return True
|
||||
self._touch = None
|
||||
ud = touch.ud[self._get_uid()]
|
||||
if ud['mode'] == 'unknown':
|
||||
Clock.unschedule(self._change_touch_mode)
|
||||
super(Carousel, self).on_touch_down(touch)
|
||||
Clock.schedule_once(partial(self._do_touch_up, touch), .1)
|
||||
else:
|
||||
self._start_animation()
|
||||
|
||||
if self.collide_point(*touch.pos):
|
||||
return super(Carousel, self).on_touch_move(touch)
|
||||
else:
|
||||
if self._touch is not touch and self.uid not in touch.ud:
|
||||
super(Carousel, self).on_touch_up(touch)
|
||||
return self._get_uid() in touch.ud
|
||||
|
||||
def _do_touch_up(self, touch, *largs):
|
||||
super(Carousel, self).on_touch_up(touch)
|
||||
# don't forget about grab event!
|
||||
for x in touch.grab_list[:]:
|
||||
touch.grab_list.remove(x)
|
||||
x = x()
|
||||
if not x:
|
||||
continue
|
||||
touch.grab_current = x
|
||||
super(Carousel, self).on_touch_up(touch)
|
||||
touch.grab_current = None
|
||||
|
||||
def _change_touch_mode(self, *largs):
|
||||
if not self._touch:
|
||||
return
|
||||
self._start_animation()
|
||||
uid = self._get_uid()
|
||||
touch = self._touch
|
||||
ud = touch.ud[uid]
|
||||
if ud['mode'] == 'unknown':
|
||||
touch.ungrab(self)
|
||||
self._touch = None
|
||||
touch.push()
|
||||
touch.apply_transform_2d(self.to_widget)
|
||||
touch.apply_transform_2d(self.to_parent)
|
||||
super(Carousel, self).on_touch_down(touch)
|
||||
touch.pop()
|
||||
return
|
||||
|
||||
def add_widget(self, widget, index=0):
|
||||
slide = RelativeLayout(size=self.size, x=self.x - self.width, y=self.y)
|
||||
|
|
|
@ -31,7 +31,7 @@ screen, you absolutely need to give a name to it::
|
|||
# Add few screens
|
||||
for i in xrange(4):
|
||||
screen = Screen(name='Title %d' % i)
|
||||
sm.add_widget(sm)
|
||||
sm.add_widget(screen)
|
||||
|
||||
# By default, the first screen added into the ScreenManager will be
|
||||
# displayed. Then, you can change to another screen:
|
||||
|
|
|
@ -154,9 +154,9 @@ class Widget(EventDispatcher):
|
|||
# Builder.idmap.pop('root')
|
||||
|
||||
# Bind all the events
|
||||
for argument, value in kwargs.items():
|
||||
if argument.startswith('on_'):
|
||||
self.bind(**{argument: value})
|
||||
for argument in kwargs:
|
||||
if argument[:3] == 'on_':
|
||||
self.bind(**{argument: kwargs[argument]})
|
||||
|
||||
#
|
||||
# Collision
|
||||
|
|
Loading…
Reference in New Issue