From 80b014fffa40bb715c70c725faf0f47eb3ffa721 Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Tue, 7 Aug 2012 23:42:58 +0200 Subject: [PATCH 01/21] spinner: fix doc/build --- kivy/uix/spinner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kivy/uix/spinner.py b/kivy/uix/spinner.py index ed5d0124c..77f74c818 100644 --- a/kivy/uix/spinner.py +++ b/kivy/uix/spinner.py @@ -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 ''' From 93b6622d2102eb69489ed8555d489d1b7ff7d8fd Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Wed, 8 Aug 2012 00:00:11 +0200 Subject: [PATCH 02/21] add missing files from tools/ in setup.py --- kivy/tools/extensions/__init__.py | 0 kivy/tools/highlight/__init__.py | 0 kivy/tools/highlight/pygments/__init__.py | 0 setup.py | 7 +++++++ 4 files changed, 7 insertions(+) create mode 100644 kivy/tools/extensions/__init__.py create mode 100644 kivy/tools/highlight/__init__.py create mode 100644 kivy/tools/highlight/pygments/__init__.py diff --git a/kivy/tools/extensions/__init__.py b/kivy/tools/extensions/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/kivy/tools/highlight/__init__.py b/kivy/tools/highlight/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/kivy/tools/highlight/pygments/__init__.py b/kivy/tools/highlight/pygments/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/setup.py b/setup.py index eae42874d..1c41845a7 100644 --- a/setup.py +++ b/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=[ From df3beb9e3c92a228027dca8aa058d4b651e36e5f Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Wed, 8 Aug 2012 01:09:57 +0200 Subject: [PATCH 03/21] fix url loader bug with querysrtings #547 --- kivy/core/image/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index c53716658..4ab78ef93 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -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. From 24589baf3c1a1b011eb54d74f8bb0d58295b6561 Mon Sep 17 00:00:00 2001 From: "Edwin Marshall (aspidites)" Date: Wed, 8 Aug 2012 11:16:24 -0500 Subject: [PATCH 04/21] - refactored recorder module --- kivy/input/recorder.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/kivy/input/recorder.py b/kivy/input/recorder.py index f0ad1a939..dca1adae4 100644 --- a/kivy/input/recorder.py +++ b/kivy/input/recorder.py @@ -105,8 +105,7 @@ from functools import partial class RecorderMotionEvent(MotionEvent): def depack(self, args): - for key, value in args.iteritems(): - setattr(self, key, value) + [setattr(self, key, value) for key, value in args.items()] super(RecorderMotionEvent, self).depack(args) @@ -183,10 +182,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 +199,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 +262,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 +289,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: From 5f5bf9080cede288c0ce7f44036e620f38e26118 Mon Sep 17 00:00:00 2001 From: "Edwin Marshall (aspidites)" Date: Wed, 8 Aug 2012 12:22:51 -0500 Subject: [PATCH 05/21] - changed comprehension to for loop --- kivy/core/window/window_sfml.py | 1 + kivy/input/recorder.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 kivy/core/window/window_sfml.py diff --git a/kivy/core/window/window_sfml.py b/kivy/core/window/window_sfml.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/kivy/core/window/window_sfml.py @@ -0,0 +1 @@ + diff --git a/kivy/input/recorder.py b/kivy/input/recorder.py index dca1adae4..13348f93a 100644 --- a/kivy/input/recorder.py +++ b/kivy/input/recorder.py @@ -105,7 +105,8 @@ from functools import partial class RecorderMotionEvent(MotionEvent): def depack(self, args): - [setattr(self, key, value) for key, value in args.items()] + for key, value in args.items(): + setattr(self, key, value) super(RecorderMotionEvent, self).depack(args) From 189d89e89f4a7a936ab1fc94d7111064f78f2225 Mon Sep 17 00:00:00 2001 From: "Edwin Marshall (aspidites)" Date: Wed, 8 Aug 2012 12:31:34 -0500 Subject: [PATCH 06/21] - crept in from another branch --- kivy/core/window/window_sfml.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 kivy/core/window/window_sfml.py diff --git a/kivy/core/window/window_sfml.py b/kivy/core/window/window_sfml.py deleted file mode 100644 index 8b1378917..000000000 --- a/kivy/core/window/window_sfml.py +++ /dev/null @@ -1 +0,0 @@ - From 56e1a1b52605506f1bd9ece7e37dcb7beef1d25d Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 9 Aug 2012 00:12:36 +0200 Subject: [PATCH 07/21] add filechooser events doc, fix #99 --- kivy/uix/filechooser.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/kivy/uix/filechooser.py b/kivy/uix/filechooser.py index 44a9c087e..d8bf770ed 100644 --- a/kivy/uix/filechooser.py +++ b/kivy/uix/filechooser.py @@ -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 From c75f92ecfc98189e9cf3dfbe833cb8a7d1147564 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 9 Aug 2012 00:20:10 +0200 Subject: [PATCH 08/21] add info about compiling docs --- doc/sources/contribute.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/sources/contribute.rst b/doc/sources/contribute.rst index 39f2ab6d3..9c1c86b3c 100644 --- a/doc/sources/contribute.rst +++ b/doc/sources/contribute.rst @@ -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 && make force && make html + +The doc will be generated in ``build/html``. Unit tests contributions ------------------------ From 3d60b4436eab48ad6e418c335e4da35c823c8d4e Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 9 Aug 2012 00:27:23 +0200 Subject: [PATCH 09/21] add events docs + PEP8 fixes --- kivy/uix/vkeyboard.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/kivy/uix/vkeyboard.py b/kivy/uix/vkeyboard.py index d527839d2..a70ff0cfc 100644 --- a/kivy/uix/vkeyboard.py +++ b/kivy/uix/vkeyboard.py @@ -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 From 60927a5aca8230bac626e1d3f1772f54fd8e397d Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 9 Aug 2012 00:50:18 +0200 Subject: [PATCH 10/21] typos and pep8. fix some of #175 --- kivy/app.py | 4 ++-- kivy/uix/image.py | 2 +- kivy/uix/label.py | 8 ++++---- kivy/uix/layout.py | 11 +++++------ kivy/uix/rst.py | 2 +- kivy/uix/scatter.py | 4 ++-- kivy/uix/settings.py | 2 +- kivy/uix/treeview.py | 2 +- kivy/uix/widget.py | 10 +++++----- 9 files changed, 22 insertions(+), 23 deletions(-) diff --git a/kivy/app.py b/kivy/app.py index ef387b91c..dfde9ac03 100644 --- a/kivy/app.py +++ b/kivy/app.py @@ -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 :methc:`build` method or by the + #: :meth:`load_kv` method if the kv file contains a root widget. self.root = None def build(self): diff --git a/kivy/uix/image.py b/kivy/uix/image.py index 38c49a93e..978842788 100644 --- a/kivy/uix/image.py +++ b/kivy/uix/image.py @@ -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) diff --git a/kivy/uix/label.py b/kivy/uix/label.py index b73239333..d1b58ea99 100644 --- a/kivy/uix/label.py +++ b/kivy/uix/label.py @@ -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) diff --git a/kivy/uix/layout.py b/kivy/uix/layout.py index ee8490753..7c58e0742 100644 --- a/kivy/uix/layout.py +++ b/kivy/uix/layout.py @@ -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) - diff --git a/kivy/uix/rst.py b/kivy/uix/rst.py index 795f5af57..b914d79bc 100644 --- a/kivy/uix/rst.py +++ b/kivy/uix/rst.py @@ -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 diff --git a/kivy/uix/scatter.py b/kivy/uix/scatter.py index ebd86a8fe..317b49f6c 100644 --- a/kivy/uix/scatter.py +++ b/kivy/uix/scatter.py @@ -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 ----- diff --git a/kivy/uix/settings.py b/kivy/uix/settings.py index 5ba599df2..f05e1d63c 100644 --- a/kivy/uix/settings.py +++ b/kivy/uix/settings.py @@ -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 diff --git a/kivy/uix/treeview.py b/kivy/uix/treeview.py index 4e365e0bf..2c57f8bfb 100644 --- a/kivy/uix/treeview.py +++ b/kivy/uix/treeview.py @@ -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. diff --git a/kivy/uix/widget.py b/kivy/uix/widget.py index 8256d12b2..0d8463303 100644 --- a/kivy/uix/widget.py +++ b/kivy/uix/widget.py @@ -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. ''' From d94ef8a60c4daf8eb53600587769ad3ea7291e6d Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 9 Aug 2012 01:10:17 +0200 Subject: [PATCH 11/21] some more doc fixes --- doc/sources/contribute.rst | 4 ++-- kivy/app.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/sources/contribute.rst b/doc/sources/contribute.rst index 9c1c86b3c..b2dcea3b4 100644 --- a/doc/sources/contribute.rst +++ b/doc/sources/contribute.rst @@ -251,11 +251,11 @@ this makes `:doc:` prefered, for the cleaner url. To build your documentation, run:: - make html + make html If you updated your kivy install, and have some trouble compiling docs, run:: - make clean && make force && make html + make clean force html The doc will be generated in ``build/html``. diff --git a/kivy/app.py b/kivy/app.py index dfde9ac03..44454a4bb 100644 --- a/kivy/app.py +++ b/kivy/app.py @@ -299,7 +299,7 @@ class App(EventDispatcher): #: configuration. Can be used to query some config token in the build() self.config = None - #: Root widget set by the :methc:`build` method or by the + #: 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 From 3faa7231bb10eaa22fa180c9ba4b5a5b8c8fdfb3 Mon Sep 17 00:00:00 2001 From: Qua-non Date: Thu, 9 Aug 2012 05:08:00 +0530 Subject: [PATCH 12/21] Core: markup and text allow for blanks lines when using \n for empty lines should fix issue #619 --- kivy/core/text/__init__.py | 2 ++ kivy/core/text/markup.py | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/kivy/core/text/__init__.py b/kivy/core/text/__init__.py index fc3155c67..90d869d67 100644 --- a/kivy/core/text/__init__.py +++ b/kivy/core/text/__init__.py @@ -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 diff --git a/kivy/core/text/markup.py b/kivy/core/text/markup.py index 46e41ea35..092d89eda 100644 --- a/kivy/core/text/markup.py +++ b/kivy/core/text/markup.py @@ -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]: From d178f02c5baee2e3202d55ccf85a8cf45bed62aa Mon Sep 17 00:00:00 2001 From: Dominik Kozaczko Date: Thu, 9 Aug 2012 13:07:07 +0200 Subject: [PATCH 13/21] small corrections to docs --- doc/Makefile | 2 +- doc/sources/guide/other-frameworks.rst | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 571a0b883..de560f124 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -PYTHON = python +PYTHON = python2 SPHINXOPTS = -W #SPHINXOPTS = SPHINXBUILD = sphinx-build diff --git a/doc/sources/guide/other-frameworks.rst b/doc/sources/guide/other-frameworks.rst index 13eb7f9d9..164159769 100644 --- a/doc/sources/guide/other-frameworks.rst +++ b/doc/sources/guide/other-frameworks.rst @@ -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. From e68d68d1ac4e71093262d513782edef34c6cadeb Mon Sep 17 00:00:00 2001 From: Dominik Kozaczko Date: Thu, 9 Aug 2012 13:20:14 +0200 Subject: [PATCH 14/21] README links to correct API doc location --- doc/README | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/README b/doc/README index 5af6ddb43..9f124bfcd 100644 --- a/doc/README +++ b/doc/README @@ -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 From d1eefab85171f162c2401d37127e6b4e1faf7adc Mon Sep 17 00:00:00 2001 From: Dominik Kozaczko Date: Thu, 9 Aug 2012 13:50:05 +0200 Subject: [PATCH 15/21] more corrections to docs --- doc/Makefile | 2 +- doc/sources/guide/designwithkv.rst | 9 ++++--- doc/sources/tutorials/pong.rst | 38 ++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index de560f124..571a0b883 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -PYTHON = python2 +PYTHON = python SPHINXOPTS = -W #SPHINXOPTS = SPHINXBUILD = sphinx-build diff --git a/doc/sources/guide/designwithkv.rst b/doc/sources/guide/designwithkv.rst index 0d1c34062..3291d3ae4 100644 --- a/doc/sources/guide/designwithkv.rst +++ b/doc/sources/guide/designwithkv.rst @@ -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 diff --git a/doc/sources/tutorials/pong.rst b/doc/sources/tutorials/pong.rst index b7bbd3171..da76c9906 100644 --- a/doc/sources/tutorials/pong.rst +++ b/doc/sources/tutorials/pong.rst @@ -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 ```` rule we have is a canvas block:: +The first block inside the ```` rule we have is a canvas block: + +.. code-block:: kv : 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 : - ... + # ... 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 : 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 : 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? From 82ee2b49d4237d41e9e496c596dffccda70cb062 Mon Sep 17 00:00:00 2001 From: Qua-non Date: Thu, 9 Aug 2012 17:23:03 +0530 Subject: [PATCH 16/21] Core: Image: skip keep_data check for images created from texture should fix #631 and #629 --- kivy/core/image/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index 4ab78ef93..8946365e0 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -569,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) From 735299d28c19489fb9fb8b7895ea6451a865688e Mon Sep 17 00:00:00 2001 From: Qua-non Date: Thu, 9 Aug 2012 18:18:11 +0530 Subject: [PATCH 17/21] Pep8 Fixes: as per suggestions by tshirtman and aspidites --- kivy/core/image/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index 8946365e0..3e97e34bc 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -571,8 +571,8 @@ class Image(EventDispatcher): self.image = image # 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: + if (image.__class__ != self.__class__ and + not image.keep_data and self._keep_data): self.remove_from_cache() self._filename = '' self._set_filename(value) From d0cdce6cc01e01b5ca8a5c7564b87f786c9547e5 Mon Sep 17 00:00:00 2001 From: Thomas Hansen Date: Thu, 9 Aug 2012 13:52:46 -0500 Subject: [PATCH 18/21] uix.screenmanager.ScreenManager: * this fixes issue #634 * remove exception when new screen with same name as existing is added * instead warn when switching to a screen by name, and there are multiple * adds `screen_names` property, to get list of all screen names --- kivy/uix/screenmanager.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/kivy/uix/screenmanager.py b/kivy/uix/screenmanager.py index 2d451002c..6537269d7 100644 --- a/kivy/uix/screenmanager.py +++ b/kivy/uix/screenmanager.py @@ -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 @@ -560,21 +561,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 +609,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 +627,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. From f747e0d6cb1a7835ccc46fce8c09f2e1b9c5c5c8 Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Fri, 10 Aug 2012 11:17:54 +0200 Subject: [PATCH 19/21] mouse: fix ghost touch that can appear on window (due to a race condition between mousemotion / mouserelease). closes #621 --- kivy/input/providers/mouse.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kivy/input/providers/mouse.py b/kivy/input/providers/mouse.py index bb9c45da3..241db2e7d 100644 --- a/kivy/input/providers/mouse.py +++ b/kivy/input/providers/mouse.py @@ -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) From b3999f3a11fb0bdf2532574a208374887ee31d2b Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Fri, 10 Aug 2012 11:31:14 +0200 Subject: [PATCH 20/21] app: fix invalid configuration filename >_< --- kivy/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kivy/app.py b/kivy/app.py index 44454a4bb..f31d8f2fb 100644 --- a/kivy/app.py +++ b/kivy/app.py @@ -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) % { From bdc4c131198b9df0a44701aefeb2919e129a1e79 Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Fri, 10 Aug 2012 12:10:41 +0200 Subject: [PATCH 21/21] screenmanager: raise exception if start() is called twice. closes #618 --- kivy/uix/screenmanager.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kivy/uix/screenmanager.py b/kivy/uix/screenmanager.py index 6537269d7..7a280c951 100644 --- a/kivy/uix/screenmanager.py +++ b/kivy/uix/screenmanager.py @@ -243,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, @@ -564,16 +566,16 @@ class ScreenManager(FloatLayout): def _get_screen_names(self): return [s.name for s in self.screens] - screen_names = AliasProperty(_get_screen_names, None, bind=('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`, + :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)