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

Please enter a commit message to explain why this merge is necessary,
This commit is contained in:
Mathieu Virbel 2014-04-02 15:28:29 +02:00
commit e74d8dde11
19 changed files with 292 additions and 67 deletions

9
.gitignore vendored
View File

@ -31,6 +31,7 @@ kivy/core/window/sdl.c
python
python.exe
.idea
dist
MANIFEST
@ -47,3 +48,11 @@ kivy/lib/vidcore_lite/bcm.c
kivy/lib/vidcore_lite/bcm.h
kivy/lib/vidcore_lite/egl.c
# PyDev
.project
.pydevproject
# Virtualenv
venv

View File

@ -204,18 +204,153 @@ Mageia 1 onwards
# pip install --upgrade cython
# pip install pygments
*Installation*
==============
*Installation in a Virtual Environment with System Site Packages*
=================================================================
This is a recommended compromise between installing Kivy and its dependencies
system wide and installing as much as possible into a virtual environment.
Ubuntu 12.04 with Python 2.7
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you're installing Kivy for the first time, do::
$ sudo easy_install kivy
Install System-wide Dependencies
--------------------------------
If you already installed kivy before, you can upgrade it with::
Note that these commands will remove any pre-existing versions of
python-virtualenv and replace it with the current version. It will also remove
cython, numpy, and pygame installed from your Linux distro's repository and
replace them with current versions from pip or the pygame Mercurial repository.
$ sudo easy_install --upgrade kivy
::
# Install necessary system packages
sudo apt-get install -y build-essential mercurial git python2.7 \
python-setuptools python-dev ffmpeg libsdl-image1.2-dev \
libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsmpeg-dev libsdl1.2-dev \
libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev zlib1g-dev
# Bootstrap a current Python environment
sudo apt-get remove --purge -y python-virtualenv python-pip
sudo easy_install-2.7 -U pip
sudo pip2.7 install -U virtualenv
# Install current version of Cython
sudo apt-get remove --purge -y cython
sudo pip2.7 install -U cython
# Install other PyGame dependencies
sudo apt-get remove --purge -y python-numpy
sudo pip2.7 install -U numpy
# Install PyGame
sudo apt-get remove --purge python-pygame
hg clone https://bitbucket.org/pygame/pygame
cd pygame
python2.7 setup.py build
sudo python2.7 setup.py install
cd ..
sudo rm -rf pygame
Create a Kivy Virtualenv
~~~~~~~~~~~~~~~~~~~~~~~~
::
# Create a vitualenv
rm -rf venv
virtualenv -p python2.7 --system-site-packages venv
# Install stable version of Kivy into the virtualenv
venv/bin/pip install kivy
# For the development version of Kivy, use the following command instead
# venv/bin/pip install git+https://github.com/kivy/kivy.git@master
# Install development version of buildozer into the virtualenv
venv/bin/pip install git+https://github.com/kivy/buildozer.git@master
# Install development version of plyer into the virtualenv
venv/bin/pip install git+https://github.com/kivy/plyer.git@master
# Install a couple of dependencies for KivyCatalog
venv/bin/pip install -U pygments docutils
Ubuntu 12.04 with Python 3.3
----------------------------
Install System-wide Dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that these commands will remove any pre-existing versions of
python-virtualenv and replace it with the current version. It will also remove
cython, numpy, and pygame installed from your Linux distro's repository and
replace them with current versions from pip or the pygame Mercurial repository.
::
# Bootstrap Python3.3
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:fkrull/deadsnakes
sudo apt-get update
# Install necessary system packages
sudo apt-get install -y build-essential mercurial git python3.3 \
python3.3-dev ffmpeg libsdl-image1.2-dev libsdl-mixer1.2-dev \
libsdl-ttf2.0-dev libsmpeg-dev libsdl1.2-dev libportmidi-dev \
libswscale-dev libavformat-dev libavcodec-dev zlib1g-dev
# Bootstrap current setuptools
wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | sudo python3.3
# Bootstrap a current Python environment
sudo apt-get remove --purge -y python-virtualenv python-pip
sudo easy_install-3.3 -U pip
sudo pip3.3 install -U virtualenv
# Install current version of Cython
sudo apt-get remove --purge -y cython
sudo pip3.3 install -U cython
# Install other PyGame dependencies
sudo apt-get remove --purge -y python-numpy
sudo pip3.3 install -U numpy
# Install PyGame
hg clone https://bitbucket.org/pygame/pygame
cd pygame
python3.3 setup.py build
sudo python3.3 setup.py install
cd ..
sudo rm -rf pygame
Create a Kivy Virtualenv
~~~~~~~~~~~~~~~~~~~~~~~~
::
# Create a vitualenv
rm -rf venv
virtualenv -p python3.3 --system-site-packages venv
# Install stable version of Kivy into the virtualenv
venv/bin/pip install kivy
# For the development version of Kivy, use the following command instead
# venv/bin/pip install git+https://github.com/kivy/kivy.git@master
# Install development version of buildozer into the virtualenv
#venv/bin/pip install git+https://github.com/kivy/buildozer.git@master
# Install development version of plyer into the virtualenv
venv/bin/pip install git+https://github.com/kivy/plyer.git@master
# Install a couple of dependencies for KivyCatalog
venv/bin/pip install -U pygments docutils
.. _linux-run-app:

View File

@ -97,6 +97,7 @@ void main() {
}
'''
class ShaderWidget(FloatLayout):
# property to set the source code for fragment shader
@ -132,7 +133,7 @@ class ShaderWidget(FloatLayout):
def update_glsl(self, *largs):
self.canvas['time'] = Clock.get_boottime()
self.canvas['resolution'] = map(float, self.size)
self.canvas['resolution'] = [float(v) for v in self.size]
def on_fs(self, instance, value):
# set the fragment shader to our source code
@ -191,6 +192,7 @@ class ShaderTreeApp(App):
# shader
btn = Button(text='Change fragment shader', size_hint=(1, None),
height=50)
def change(*largs):
sw.fs = available_shaders[self.shader_index]
self.shader_index = (self.shader_index + 1) % len(available_shaders)

View File

@ -19,7 +19,7 @@ PageLayout:
Button:
text: 'test'
on_press: print "test"
on_press: print("test")
BoxLayout:
orientation: 'vertical'
@ -51,7 +51,7 @@ PageLayout:
source: 'http://kivy.org/slides/kivyandroid-thumb.jpg'
Button:
text: 'test'
on_press: print "test last page"
on_press: print("test last page")
AsyncImage:
source: 'http://kivy.org/slides/kivypictures-thumb.jpg'
Widget

View File

@ -182,7 +182,7 @@ class ImageLoaderBase(object):
imagedata = self._data[count]
imagedata.source = '{}{}|{}'.format(
'zip|' if self.filename.endswith('.zip') else '',
self._nocache, uid)
self._nocache, uid)
texture = Texture.create_from_data(
imagedata, mipmap=self._mipmap)
if not self._nocache:

View File

@ -91,6 +91,10 @@ cdef extern from "CoreGraphics/CGColorSpace.h":
CGColorSpaceRef CGColorSpaceCreateDeviceRGB()
void CGColorSpaceRelease(CGColorSpaceRef cs)
cdef extern from "CoreGraphics/CGAffineTransform.h":
ctypedef void *CGAffineTransform
CGAffineTransform CGAffineTransformMake(float a, float b, float c, float d, float tx, float ty)
cdef extern from "CoreGraphics/CGContext.h":
ctypedef void *CGContextRef
void CGContextRelease(CGContextRef c)
@ -98,6 +102,7 @@ cdef extern from "CoreGraphics/CGContext.h":
int kCGBlendModeCopy
int kCGBlendModeNormal
void CGContextSetBlendMode(CGContextRef, int)
void CGContextConcatCTM(CGContextRef fc, CGAffineTransform matrix)
cdef extern from "CoreGraphics/CGBitmapContext.h":
CGImageRef CGBitmapContextCreateImage(CGColorSpaceRef)
@ -181,11 +186,11 @@ def load_image_data(bytes _url):
return (width, height, 'rgba', r_data)
def save_image_rgba(filename, width, height, data):
def save_image_rgba(filename, width, height, data, flipped):
# compatibility, could be removed i guess
save_image(filename, width, height, 'rgba', data)
save_image(filename, width, height, 'rgba', data, flipped)
def save_image(filename, width, height, fmt, data):
def save_image(filename, width, height, fmt, data, flipped):
# save a RGBA string into filename using CoreGraphics
# FIXME only png output are accepted.
@ -232,12 +237,39 @@ def save_image(filename, width, height, fmt, data):
cdef CGImageDestinationRef dest = CGImageDestinationCreateWithURL(url,
ctype, 1, NULL)
# release everything
CGImageDestinationAddImage(dest, cgImage, NULL)
# copy the image into a transformed context
cdef CGContextRef flippedContext
cdef CGImageRef newImageRef
if flipped:
flippedContext = CGBitmapContextCreate(
NULL, width, height,
8, # bitsPerComponent
fmt_length * width, # bytesPerRow
colorSpace,
kCGImageAlphaNoneSkipLast)
CGContextConcatCTM(flippedContext, CGAffineTransformMake(1.0, 0.0,
0.0, -1.0,
0.0, height))
CGContextDrawImage(flippedContext,
CGRectMake(0, 0, width, height),
cgImage)
newImageRef = CGBitmapContextCreateImage(flippedContext)
CGImageDestinationAddImage(dest, newImageRef, NULL)
CGImageDestinationFinalize(dest)
CFRelease(newImageRef)
CFRelease(flippedContext)
else:
CGImageDestinationAddImage(dest, cgImage, NULL)
CGImageDestinationFinalize(dest)
#Release everything
CFRelease(cgImage)
CFRelease(bitmapContext)
CFRelease(colorSpace)
CGImageDestinationFinalize(dest)
free(pixels)
class ImageLoaderImageIO(ImageLoaderBase):
@ -267,8 +299,8 @@ class ImageLoaderImageIO(ImageLoaderBase):
return True
@staticmethod
def save(filename, width, height, fmt, pixels):
save_image(filename, width, height, fmt, pixels)
def save(filename, width, height, fmt, pixels, flipped=False):
save_image(filename, width, height, fmt, pixels, flipped)
return True
# register

View File

@ -795,10 +795,11 @@ class WindowBase(EventDispatcher):
self.close()
return True
if Config:
on_keyboard.exit_on_escape = Config.get('kivy', 'exit_on_escape')
on_keyboard.exit_on_escape = Config.getboolean('kivy', 'exit_on_escape')
def __exit(section, name, value):
WindowBase.on_keyboard.exit_on_escape = value
WindowBase.__dict__['on_keyboard'].exit_on_escape = \
Config.getboolean('kivy', 'exit_on_escape')
Config.add_callback(__exit, 'kivy', 'exit_on_escape')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -37,6 +37,7 @@ cdef class Texture:
cdef void allocate(self)
cpdef flip_vertical(self)
cpdef flip_horizontal(self)
cpdef get_region(self, x, y, width, height)
cpdef bind(self)

View File

@ -731,6 +731,16 @@ cdef class Texture:
self._uvh = -self._uvh
self.update_tex_coords()
cpdef flip_horizontal(self):
'''Flip tex_coords for horizontal display.
.. versionadded:: 1.8.1
'''
self._uvx += self._uvw
self._uvw = -self._uvw
self.update_tex_coords()
cpdef get_region(self, x, y, width, height):
'''Return a part of the texture defined by the rectangular arguments
(x, y, width, height). Returns a :class:`TextureRegion` instance.'''

View File

@ -26,9 +26,9 @@ class FileChooserUnicodeTestCase(unittest.TestCase):
# this will test creating unicode and bytes filesnames
ufiles = [u'कीवीtestu',
u'कीवीtestu' + unicode_char(0xFFFF),
u'कीवीtestu' + unicode_char(0xFFFF - 1),
u'कीवीtestu' + unicode_char(0xFF)]
u'कीवीtestu' + unicode_char(0xEEEE),
u'कीवीtestu' + unicode_char(0xEEEE - 1),
u'कीवीtestu' + unicode_char(0xEE)]
# don't use non-ascii directly because that will test source file
# text conversion, not path issues :)
bfiles = [b'\xc3\xa0\xc2\xa4\xe2\x80\xa2\xc3\xa0\xc2\xa5\xe2\x82\xac\

View File

@ -13,7 +13,7 @@
{ "match": ".*?:$",
"name": "support.function.kivy" },
{ "name": "entity.name.section.kivy",
"match": "(.*?):" },
"match": "(.*?):$" },
{ "include": "source.python" }
],
"uuid": "49cecc44-5094-48ec-a876-91f597e8bf81"

View File

@ -42,7 +42,7 @@
</dict>
<dict>
<key>match</key>
<string>(.*?):</string>
<string>(.*?):$</string>
<key>name</key>
<string>entity.name.section.kivy</string>
</dict>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -284,8 +284,8 @@ the cls or template.
.. note::
Only the ListItemLabel, ListItemButton or custom classes like them, and
neither the bare Label nor Button classes, are to be used in the listview
Only the ListItemLabel, ListItemButton or custom classes like them (and
not the simple Label or Button classes) are to be used in the listview
system.
.. warning::
@ -449,12 +449,12 @@ custom class you have defined and registered with the system.
An args_converter needs to be constructed that goes along with such a kv
template. For example, to use the kv template above::
list_item_args_converter = \
list_item_args_converter = \\
lambda row_index, rec: {'text': rec['text'],
'is_selected': rec['is_selected'],
'size_hint_y': None,
'height': 25}
integers_dict = \
integers_dict = \\
{ str(i): {'text': str(i), 'is_selected': False} for i in range(100)}
dict_adapter = DictAdapter(sorted_keys=[str(i) for i in range(100)],

View File

@ -851,6 +851,11 @@ class Settings(BoxLayout):
:Events:
`on_config_change`: ConfigParser instance, section, key, value
Fired when section/key/value of a ConfigParser changes.
.. warning:
value will be str/unicode type, regardless of the setting
type (numeric, boolean, etc)
`on_close`
Fired by the default panel when the Close button is pressed.

View File

@ -374,9 +374,16 @@ class TextInput(Widget):
self.bind(pos=self._trigger_update_graphics)
self._trigger_position_handles = Clock.create_trigger(
self._position_handles)
self._trigger_show_handles = Clock.create_trigger(
self._show_handles, .05)
self._trigger_refresh_line_options()
self._trigger_refresh_text()
self.bind(pos=self._trigger_position_handles,
size=self._trigger_position_handles)
# when the gl context is reloaded, trigger the text rendering again.
_textinput_list.append(ref(self, TextInput._reload_remove_observer))
@ -1009,19 +1016,25 @@ class TextInput(Widget):
on_release=self._handle_released)
if not self._handle_middle.parent and self.text:
self._win.add_widget(handle_middle)
self._position_handles('middle')
self._position_handles(mode='middle')
return True
def _handle_pressed(self, instance):
self._hide_cut_copy_paste()
sf, st = self._selection_from, self.selection_to
if sf > st:
self._selection_from , self._selection_to = st, sf
def _handle_released(self, instance):
if self.selection_to != self.selection_from:
self._update_selection()
self._show_cut_copy_paste(
(instance.x + ((1 if instance is self._handle_left else - 1)
* self._bubble.width / 2) if self._bubble else 0,
instance.y + self.line_height), self._win)
sf, st = self._selection_from, self.selection_to
if sf == st:
return
self._update_selection()
self._show_cut_copy_paste(
(instance.x + ((1 if instance is self._handle_left else - 1)
* self._bubble.width / 2) if self._bubble else 0,
instance.y + self.line_height), self._win)
def _handle_move(self, instance, touch):
if touch.grab_current != instance:
@ -1031,51 +1044,65 @@ class TextInput(Widget):
handle_left = self._handle_left
handle_middle = self._handle_middle
x, y = self.to_widget(*touch.pos)
cursor = get_cursor(
touch.x, touch.y + instance._touch_diff + (self.line_height / 2))
x,
y + instance._touch_diff + (self.line_height / 2))
if instance != touch.grab_current:
return
if instance == handle_middle:
self.cursor = cursor
self._position_handles('middle')
self._position_handles(mode='middle')
return
ci = self.cursor_index(cursor=cursor)
sf, st = self._selection_from, self.selection_to
if instance == handle_left:
self._selection_from = self.cursor_index(cursor=cursor)
self._selection_from = ci
elif instance == handle_right:
self._selection_to = self.cursor_index(cursor=cursor)
self._selection_to = ci
self._trigger_update_graphics()
Clock.schedule_once(lambda dt: self._position_handles())
self._trigger_position_handles()
def _position_handles(self, *args, **kwargs):
if not self.text:
return
mode = kwargs.get('mode', 'both')
def _position_handles(self, mode='both'):
group = self.canvas.get_group('selection')
lh = self.line_height
to_win = self.to_window
if mode[0] == 'm':
handle_middle = self._handle_middle
handle_middle = self._handle_middle
if handle_middle:
hp_mid = self.cursor_pos
pos = self.to_window(*hp_mid)
pos = to_win(*hp_mid)
handle_middle.x = pos[0] - handle_middle.width / 2
handle_middle.top = pos[1] - lh
if mode[0] == 'm':
return
group = self.canvas.get_group('selection')
if not group:
return
self._win.remove_widget(self._handle_middle)
if mode[0] != 'm':
handle_left = self._handle_left
hp_left = group[2].pos
handle_left.pos = self.to_window(*hp_left)
handle_left.x -= handle_left.width
handle_left.y -= handle_left.height
handle_left = self._handle_left
if not handle_left:
return
hp_left = group[2].pos
handle_left.pos = to_win(*hp_left)
handle_left.x -= handle_left.width
handle_left.y -= handle_left.height
#if mode[0] in ('b', 'r'):
handle_right = self._handle_right
last_rect = group[-1]
hp_right = last_rect.pos[0], last_rect.pos[1]
handle_right.pos = self.to_window(*hp_right)
handle_right.x += last_rect.size[0]
handle_right.y -= handle_right.height
handle_right = self._handle_right
last_rect = group[-1]
hp_right = last_rect.pos[0], last_rect.pos[1]
x, y = to_win(*hp_right)
handle_right.x = x + last_rect.size[0]
handle_right.y = y - handle_right.height
def _hide_handles(self, win=None):
win = win or self._win
@ -1095,10 +1122,11 @@ class TextInput(Widget):
anim.bind(on_complete=lambda *args: win.remove_widget(bubble))
anim.start(bubble)
def _show_handles(self, win):
if not self.use_handles:
def _show_handles(self, dt):
if not self.use_handles or not self.text:
return
win = self._win
if not win:
self._set_window()
win = self._win
@ -1121,12 +1149,13 @@ class TextInput(Widget):
on_touch_move=self._handle_move,
on_release=self._handle_released)
else:
win.remove_widget(self._handle_left)
win.remove_widget(self._handle_right)
if self._handle_left.parent:
self._position_handles()
return
if not self.parent:
return
Clock.schedule_once(lambda dt: self._position_handles())
self._trigger_position_handles()
if self.selection_from != self.selection_to:
self._handle_left.opacity = self._handle_right.opacity = 0
win.add_widget(self._handle_left)
@ -1221,7 +1250,7 @@ class TextInput(Widget):
return
else:
#XXX where do `value` comes from?
Clock.schedule_once(partial(self.on_focus, self, value), 0)
Clock.schedule_once(partial(self.on_focus, self, largs), 0)
return
def on_focus(self, instance, value, *largs):
@ -1681,6 +1710,7 @@ class TextInput(Widget):
padding_left, padding_right, x,
canvas_add, selection_color)
y -= dy
self._position_handles('both')
def _draw_selection(self, *largs):
pos, size, line_num, (s1c, s1r), (s2c, s2r),\
@ -2375,8 +2405,8 @@ class TextInput(Widget):
'''
def on_selection_text(self, instance, value):
if value:
self._show_handles(self._win)
if value and self.use_handles:
self._trigger_show_handles()
focus = BooleanProperty(False)
'''If focus is True, the keyboard will be requested and you can start