From 2b98c27864e2f1daf2abbe564b17173c51918506 Mon Sep 17 00:00:00 2001 From: qua-non Date: Sat, 6 Jul 2013 02:28:56 +0530 Subject: [PATCH] minor compatibility fixes making sure some widgets and examples are working with py3.3+ and 2.7.x --- examples/demo/kivycatalog/main.py | 2 +- .../sequenced_images/uix/custom_button.py | 8 +- kivy/core/video/video_gstreamer.py | 84 +++++++++++++++---- kivy/support.py | 9 +- kivy/uix/button.py | 11 ++- 5 files changed, 88 insertions(+), 26 deletions(-) diff --git a/examples/demo/kivycatalog/main.py b/examples/demo/kivycatalog/main.py index 6ed66fb26..22fea7a6e 100644 --- a/examples/demo/kivycatalog/main.py +++ b/examples/demo/kivycatalog/main.py @@ -143,7 +143,7 @@ class Catalog(BoxLayout): self.show_error(e) def show_error(self, e): - self.info_label.text = e.message + self.info_label.text = str(e) self.anim = Animation(top=190.0, opacity=1, d=2, t='in_back') +\ Animation(top=190.0, d=3) +\ Animation(top=0, opacity=0, d=2) diff --git a/examples/widgets/sequenced_images/uix/custom_button.py b/examples/widgets/sequenced_images/uix/custom_button.py index 30434ee23..00b12353e 100644 --- a/examples/widgets/sequenced_images/uix/custom_button.py +++ b/examples/widgets/sequenced_images/uix/custom_button.py @@ -66,10 +66,10 @@ class AnimatedButton(Label): def on_touch_down(self, touch): if not self.collide_point(touch.x, touch.y): return False - if self in touch.ud: + if repr(self) in touch.ud: return False touch.grab(self) - touch.ud[self] = True + touch.ud[repr(self)] = True _animdelay = self.img.anim_delay self.img.source = self.background_down self.img.anim_delay = _animdelay @@ -78,12 +78,12 @@ class AnimatedButton(Label): return True def on_touch_move(self, touch): - return self in touch.ud + return repr(self) in touch.ud def on_touch_up(self, touch): if touch.grab_current is not self: return - assert(self in touch.ud) + assert(repr(self) in touch.ud) touch.ungrab(self) _animdelay = self.img._coreimage.anim_delay self.img.source = self.background_normal diff --git a/kivy/core/video/video_gstreamer.py b/kivy/core/video/video_gstreamer.py index d09792961..7dc008aa2 100644 --- a/kivy/core/video/video_gstreamer.py +++ b/kivy/core/video/video_gstreamer.py @@ -8,19 +8,26 @@ VideoGStreamer: implementation of VideoBase with GStreamer # To prevent memory leak, you must connect() to a func, and you might want to # pass the referenced object with weakref() # - +from kivy.compat import PY2 try: - import pygst - if not hasattr(pygst, '_gst_already_checked'): - pygst.require('0.10') - pygst._gst_already_checked = True - import gst + #import pygst + #if not hasattr(pygst, '_gst_already_checked'): + # pygst.require('0.10') + # pygst._gst_already_checked = True + if PY2: + import gst + else: + import gi + from gi.repository import Gst as gst except: raise from os import path from threading import Lock -from urllib.request import pathname2url +if PY2: + from urllib import pathname2url +else: + from urllib.request import pathname2url from kivy.graphics.texture import Texture from kivy.logger import Logger from functools import partial @@ -31,20 +38,42 @@ from kivy.core.video import VideoBase from kivy.support import install_gobject_iteration install_gobject_iteration() - +BUF_SAMPLE = 'buffer' _VIDEO_CAPS = ','.join([ 'video/x-raw-rgb', 'red_mask=(int)0xff0000', 'green_mask=(int)0x00ff00', 'blue_mask=(int)0x0000ff']) +if not PY2: + gst.init(None) + gst.STATE_NULL = gst.State.NULL + gst.STATE_READY = gst.State.READY + gst.STATE_PLAYING = gst.State.PLAYING + gst.STATE_PAUSED = gst.State.PAUSED + gst.FORMAT_TIME = gst.Format.TIME + gst.SEEK_FLAG_FLUSH = gst.SeekFlags.KEY_UNIT + gst.SEEK_FLAG_KEY_UNIT = gst.SeekFlags.KEY_UNIT + gst.MESSAGE_ERROR = gst.MessageType.ERROR + BUF_SAMPLE = 'sample' + + _VIDEO_CAPS = ','.join([ + 'video/x-raw', + 'format=RGB', + 'red_mask=(int)0xff0000', + 'green_mask=(int)0x00ff00', + 'blue_mask=(int)0x0000ff']) + + + + def _gst_new_buffer(obj, appsink): obj = obj() if not obj: return with obj._buffer_lock: - obj._buffer = obj._videosink.emit('pull-buffer') + obj._buffer = obj._videosink.emit('pull-' + BUF_SAMPLE) def _on_gst_message(bus, message): @@ -74,19 +103,28 @@ class VideoGStreamer(VideoBase): def _gst_init(self): # self._videosink will receive the buffers so we can upload them to GPU - self._videosink = gst.element_factory_make('appsink', 'videosink') - self._videosink.set_property('caps', gst.Caps(_VIDEO_CAPS)) + if PY2: + self._videosink = gst.element_factory_make('appsink', 'videosink') + self._videosink.set_property('caps', gst.Caps(_VIDEO_CAPS)) + else: + self._videosink = gst.ElementFactory.make('appsink', 'videosink') + self._videosink.set_property('caps', gst.caps_from_string(_VIDEO_CAPS)) + + self._videosink.set_property('async', True) self._videosink.set_property('drop', True) self._videosink.set_property('qos', True) self._videosink.set_property('emit-signals', True) - self._videosink.connect('new-buffer', partial( + self._videosink.connect('new-' + BUF_SAMPLE, partial( _gst_new_buffer, ref(self))) # playbin, takes care of all, loading, playing, etc. # XXX playbin2 have some issue when playing some video or streaming :/ #self._playbin = gst.element_factory_make('playbin2', 'playbin') - self._playbin = gst.element_factory_make('playbin', 'playbin') + if PY2: + self._playbin = gst.element_factory_make('playbin', 'playbin') + else: + self._playbin = gst.ElementFactory.make('playbin', 'playbin') self._playbin.set_property('video-sink', self._videosink) # gstreamer bus, to attach and listen to gst messages @@ -98,15 +136,29 @@ class VideoGStreamer(VideoBase): def _update_texture(self, buf): # texture will be updated with newest buffer/frame - caps = buf.get_caps()[0] - size = caps['width'], caps['height'] + caps = buf.get_caps() + _s = caps.get_structure(0) + if PY2: + size = _s['width'], _s['height'] + else: + size = _s.get_int('width')[1], _s.get_int('height')[1] if not self._texture: # texture is not allocated yet, so create it first self._texture = Texture.create(size=size, colorfmt='rgb') self._texture.flip_vertical() self.dispatch('on_load') # upload texture data to GPU - self._texture.blit_buffer(buf.data, size=size, colorfmt='rgb') + if not PY2: + buf = buf.get_buffer() + # TODO: FIXME + # see bug at https://bugzilla.gnome.org/show_bug.cgi?id=678663 + #map_info = buf.map_range(0, -1, gst.MapFlags.READ)[1] + #data = map_info.to_bytes().unref_to_array() + #print (mp.data) + #self._texture.blit_buffer(mp.data.to_bytes(mp.size, 'big'), size=size, colorfmt='rgb') + #buf.unmap(mp) + else: + self._texture.blit_buffer(buf.data, size=size, colorfmt='rgb') def _update(self, dt): buf = None diff --git a/kivy/support.py b/kivy/support.py index 0f54dd30e..8876f64fa 100644 --- a/kivy/support.py +++ b/kivy/support.py @@ -8,6 +8,8 @@ Activate other framework/toolkit inside our event loop __all__ = ('install_gobject_iteration', 'install_twisted_reactor', 'install_android') +from kivy.compat import PY2 + def install_gobject_iteration(): '''Import and install gobject context iteration inside our event loop. @@ -15,7 +17,12 @@ def install_gobject_iteration(): ''' from kivy.clock import Clock - import gobject + + if PY2: + import gobject + else: + from gi.repository import GObject as gobject + if hasattr(gobject, '_gobject_already_installed'): # already installed, don't do it twice. return diff --git a/kivy/uix/button.py b/kivy/uix/button.py index 81049e99b..b7989272a 100644 --- a/kivy/uix/button.py +++ b/kivy/uix/button.py @@ -39,6 +39,7 @@ from kivy.uix.label import Label from kivy.properties import OptionProperty, StringProperty, ListProperty from kivy.clock import Clock + class Button(Label): '''Button class, see module documentation for more information. @@ -138,10 +139,10 @@ class Button(Label): return False if not self.collide_point(touch.x, touch.y): return False - if self in touch.ud: + if repr(self) in touch.ud: return False touch.grab(self) - touch.ud[self] = True + touch.ud[repr(self)] = True self._do_press() self.dispatch('on_press') return True @@ -151,12 +152,12 @@ class Button(Label): return True if super(Button, self).on_touch_move(touch): return True - return self in touch.ud + return repr(self) in touch.ud def on_touch_up(self, touch): if touch.grab_current is not self: return super(Button, self).on_touch_up(touch) - assert(self in touch.ud) + assert(repr(self) in touch.ud) touch.ungrab(self) self._do_release() self.dispatch('on_release') @@ -181,9 +182,11 @@ class Button(Label): ''' self._do_press() self.dispatch("on_press") + def trigger_release(dt): self._do_release() self.dispatch("on_release") + if not duration: trigger_release(0) else: