diff --git a/kivy/core/window/__init__.py b/kivy/core/window/__init__.py index 4e23d07b1..c235deeea 100755 --- a/kivy/core/window/__init__.py +++ b/kivy/core/window/__init__.py @@ -195,6 +195,8 @@ class WindowBase(EventDispatcher): Fired when a key is down `on_key_up`: key, scancode, unicode Fired when a key is up + `on_dropfile`: str + Fired when a file is dropped on the application ''' __instance = None @@ -367,6 +369,7 @@ class WindowBase(EventDispatcher): self.register_event_type('on_keyboard') self.register_event_type('on_key_down') self.register_event_type('on_key_up') + self.register_event_type('on_dropfile') super(WindowBase, self).__init__() @@ -714,6 +717,19 @@ class WindowBase(EventDispatcher): '''Event called when a key is up (same arguments as on_keyboard)''' pass + def on_dropfile(self, filename): + '''Event called when a file is dropped on the application. + + .. warning:: + + This event is actually used only on MacOSX with a patched version of + pygame. But this will be a place for a further evolution (ios, + android etc.) + + .. versionadded:: 1.1.2 + ''' + pass + def configure_keyboards(self): # Configure how to provide keyboards (virtual or not) diff --git a/kivy/core/window/window_pygame.py b/kivy/core/window/window_pygame.py index 48038643f..ff3dd2bfa 100644 --- a/kivy/core/window/window_pygame.py +++ b/kivy/core/window/window_pygame.py @@ -274,6 +274,11 @@ class WindowPygame(WindowBase): elif event.type == pygame.ACTIVEEVENT: pass + # drop file (pygame patch needed) + elif event.type == pygame.USEREVENT and hasattr(pygame, + 'USEREVENT_DROPFILE') and event.code == pygame.USEREVENT_DROPFILE: + self.dispatch('on_dropfile', event.filename) + ''' # unhandled event ! else: diff --git a/kivy/data/style.kv b/kivy/data/style.kv index 86742f3b5..0c5920ad0 100644 --- a/kivy/data/style.kv +++ b/kivy/data/style.kv @@ -33,7 +33,7 @@ rgba: self.parent.background_color if self.parent else (1, 1, 1, 1) BorderImage: border: self.parent.border if self.parent else (16, 16, 16, 16) - texture: root.parent.background_texture if root.parent else None + texture: root.parent._bk_img.texture if root.parent else None size: self.size pos: self.pos diff --git a/kivy/graphics/instructions.pyx b/kivy/graphics/instructions.pyx index 44f6c4c81..9a7e8647c 100644 --- a/kivy/graphics/instructions.pyx +++ b/kivy/graphics/instructions.pyx @@ -305,7 +305,7 @@ cdef class VertexInstruction(Instruction): size: self.size .. note:: - + The filename will be searched with the :func:`kivy.resources.resource_find` function. @@ -356,7 +356,7 @@ cdef class VertexInstruction(Instruction): cdef class Callback(Instruction): '''.. versionadded:: 1.0.4 - + A Callback is an instruction that will be called when the drawing operation is performed. When adding instructions to a canvas, you can do this:: @@ -418,6 +418,9 @@ cdef class Callback(Instruction): cdef Shader shader cdef int i + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) + glBindBuffer(GL_ARRAY_BUFFER, 0) + if self.func(self): self.flag_update_done() @@ -561,7 +564,7 @@ cdef CanvasBase getActiveCanvas(): global ACTIVE_CANVAS return ACTIVE_CANVAS -# Canvas Stack, for internal use so canvas can be bound +# Canvas Stack, for internal use so canvas can be bound # inside other canvas, and restroed when other canvas is done cdef list CANVAS_STACK = list() @@ -575,7 +578,7 @@ cdef popActiveCanvas(): ACTIVE_CANVAS = CANVAS_STACK.pop() -#TODO: same as canvas, move back to context.pyx..fix circular import +#TODO: same as canvas, move back to context.pyx..fix circular import #on actual import from python problem include "common.pxi" from vertex cimport * diff --git a/kivy/graphics/vbo.pxd b/kivy/graphics/vbo.pxd index 1a5d069c2..7c19e93dc 100644 --- a/kivy/graphics/vbo.pxd +++ b/kivy/graphics/vbo.pxd @@ -34,6 +34,10 @@ cdef class VertexBatch: cdef Buffer vbo_index cdef GLuint mode cdef str mode_str + cdef GLuint id + cdef int usage + cdef int elements_size + cdef int need_upload cdef void clear_data(self) cdef void set_data(self, vertex_t *vertices, int vertices_count, diff --git a/kivy/graphics/vbo.pyx b/kivy/graphics/vbo.pyx index 2fa5f3abe..8fb6043c1 100644 --- a/kivy/graphics/vbo.pyx +++ b/kivy/graphics/vbo.pyx @@ -3,7 +3,7 @@ Vertex Buffer ============= The :class:`VBO` class handle the creation and update of Vertex Buffer Object in -OpenGL. +OpenGL. ''' __all__ = ('VBO', 'VertexBatch') @@ -129,16 +129,27 @@ cdef class VBO: cdef class VertexBatch: def __init__(self, **kwargs): + self.usage = GL_DYNAMIC_DRAW cdef object lushort = sizeof(unsigned short) self.vbo = kwargs.get('vbo') if self.vbo is None: self.vbo = VBO() self.vbo_index = Buffer(lushort) #index of every vertex in the vbo self.elements = Buffer(lushort) #indices translated to vbo indices + self.elements_size = 0 + self.need_upload = 1 + glGenBuffers(1, &self.id) self.set_data(NULL, 0, NULL, 0) self.set_mode(kwargs.get('mode')) + def __dealloc__(self): + # Add texture deletion outside GC call. + if _vbo_release_list is not None: + _vbo_release_list.append(self.id) + if _vbo_release_trigger is not None: + _vbo_release_trigger() + cdef void clear_data(self): # clear old vertices from vbo and then reset index buffer self.vbo.remove_vertex_data(self.vbo_index.pointer(), @@ -146,7 +157,6 @@ cdef class VertexBatch: self.vbo_index.clear() self.elements.clear() - cdef void set_data(self, vertex_t *vertices, int vertices_count, unsigned short *indices, int indices_count): #clear old vertices first @@ -155,6 +165,7 @@ cdef class VertexBatch: # now append the vertices and indices to vbo self.append_data(vertices, vertices_count, indices, indices_count) + self.need_upload = 1 cdef void append_data(self, vertex_t *vertices, int vertices_count, unsigned short *indices, int indices_count): @@ -174,12 +185,28 @@ cdef class VertexBatch: for i in xrange(indices_count): local_index = indices[i] self.elements.add(&vbi[local_index], NULL, 1) + self.need_upload = 1 cdef void draw(self): + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.id) + # cache indices in a gpu buffer too + if self.need_upload: + if self.elements_size == self.elements.size(): + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, self.elements_size, + self.elements.pointer()) + else: + glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.elements.size(), + self.elements.pointer(), self.usage) + self.elements_size = self.elements.size() + self.need_upload = 0 self.vbo.bind() glDrawElements(self.mode, self.elements.count(), - GL_UNSIGNED_SHORT, self.elements.pointer()) - self.vbo.unbind() + GL_UNSIGNED_SHORT, NULL) + + # XXX if the user is doing its own things, Callback instruction will + # reset the context. + # self.vbo.unbind() + # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) cdef void set_mode(self, str mode): # most common case in top; diff --git a/kivy/uix/bubble.py b/kivy/uix/bubble.py index 519281152..71934751c 100644 --- a/kivy/uix/bubble.py +++ b/kivy/uix/bubble.py @@ -131,13 +131,6 @@ class Bubble(GridLayout): default to 'bottom_mid'. ''' - background_texture = ObjectProperty(None) - '''Specifies the background texture of the bubble - - :data:`background_texture` is a :class:`~kivy.properties.ObjectProperty`, - default to 'None'. - ''' - content = ObjectProperty(None) '''This is the object where the main content of the bubble is held @@ -165,12 +158,8 @@ class Bubble(GridLayout): self.content = content = BubbleContent(parent=self) super(Bubble, self).__init__(**kwargs) self.add_widget(content) - self._bk_img.bind(on_texture=self._on_texture) self.on_arrow_pos() - def _on_texture(self, *l): - self.background_texture = self._bk_img.texture - def add_widget(self, *l): content = self.content if content is None: diff --git a/kivy/uix/button.py b/kivy/uix/button.py index 1a527305e..781240176 100644 --- a/kivy/uix/button.py +++ b/kivy/uix/button.py @@ -67,7 +67,8 @@ class Button(Label): default to [1, 1, 1, 1]. ''' - background_normal = StringProperty('atlas://data/images/defaulttheme/button') + background_normal = StringProperty( + 'atlas://data/images/defaulttheme/button') '''Background image of the button used for default graphical representation, when the button is not pressed. @@ -77,7 +78,8 @@ class Button(Label): default to 'atlas://data/images/defaulttheme/button' ''' - background_down = StringProperty('atlas://data/images/defaulttheme/button_pressed') + background_down = StringProperty( + 'atlas://data/images/defaulttheme/button_pressed') '''Background image of the button used for default graphical representation, when the button is pressed. @@ -111,6 +113,8 @@ class Button(Label): self.state = 'normal' def on_touch_down(self, touch): + if super(Button, self).on_touch_down(touch): + return True if not self.collide_point(touch.x, touch.y): return False if self in touch.ud: @@ -122,11 +126,15 @@ class Button(Label): return True def on_touch_move(self, touch): + if touch.grab_current is self: + return True + if super(Button, self).on_touch_move(touch): + return True return self in touch.ud def on_touch_up(self, touch): if touch.grab_current is not self: - return + return super(Button, self).on_touch_up(touch) assert(self in touch.ud) touch.ungrab(self) self._do_release() diff --git a/kivy/uix/label.py b/kivy/uix/label.py index 2d3b9a937..c752dd7ae 100644 --- a/kivy/uix/label.py +++ b/kivy/uix/label.py @@ -179,6 +179,8 @@ class Label(Widget): self.texture_size = list(self.texture.size) def on_touch_down(self, touch): + if super(Label, self).on_touch_down(touch): + return True if not len(self.refs): return False tx, ty = touch.pos