diff --git a/doc/gallery.py b/doc/gallery.py index 045547ac93..2c5c11ff31 100644 --- a/doc/gallery.py +++ b/doc/gallery.py @@ -191,17 +191,17 @@ def t(left='', right=''): This gallery contains: * Examples from the examples/ directory that show specific capabilities of - different libraries and attributes of Kivy. - * Demonstrations from the examples/demos/ directory that explore many - Kivy abilities. + different libraries and features of Kivy. + * Demonstrations from the examples/demos/ directory that explore many of + Kivy's abilities. There are more Kivy programs elsewhere: - * Tutorials_ walk through the development of complete Kivy applications. + * Tutorials_ walks through the development of complete Kivy applications. * Unit tests found in the source code under the subdirectory kivy/tests/ can also be useful. -We hope your journey in to learning Kivy is exciting and fun! +We hope your journey into learning Kivy is exciting and fun! ''' output = [gallery_top] diff --git a/doc/sources/guide/environment.rst b/doc/sources/guide/environment.rst index 75c36695d2..bb81ab5bb2 100644 --- a/doc/sources/guide/environment.rst +++ b/doc/sources/guide/environment.rst @@ -95,7 +95,7 @@ selector to a specific implementation. KIVY_WINDOW Implementation to use for creating the Window - Values: pygame, x11, sdl, egl_rpi + Values: pygame, x11, sdl2, egl_rpi KIVY_TEXT Implementation to use for rendering text @@ -110,7 +110,7 @@ KIVY_VIDEO KIVY_AUDIO Implementation to use for playing audio - Values: gstplayer, pygst, sdl, pygame + Values: gstplayer, pygst, ffpyplayer, sdl2, pygame KIVY_IMAGE Implementation to use for reading image diff --git a/examples/application/app_suite.py b/examples/application/app_suite.py index 1000a138cf..e7c7ab876b 100644 --- a/examples/application/app_suite.py +++ b/examples/application/app_suite.py @@ -4,8 +4,8 @@ This explores different methods of starting an application. If you run this without a command line parameter, you should see a menu in your terminal. -For example, you can rerun this with 'r' command to pick a random method. -There are lots of logging options to make this easier to debug: execution +You can also run this with a 'r' parameter to pick a random method. +There are lots of logging options to make this easier to debug: the execution order may not be obvious. Each time you run the command, only one kivy application is created. @@ -137,8 +137,8 @@ def print_class(class_name): d - Use a kv file from a different directory f - Use a kv file with the widget object p - Use prebuilt widget inside a layout - s - Use a kiva language string to create the widget - r - pick one of the demos at random. + s - Use a kivy language string to create the widget + r - pick one of the options at random. h - show this help message. diff --git a/examples/application/app_with_kv_in_template1.py b/examples/application/app_with_kv_in_template1.py index 9cc91d5bb9..ba5d76123c 100644 --- a/examples/application/app_with_kv_in_template1.py +++ b/examples/application/app_with_kv_in_template1.py @@ -8,7 +8,7 @@ As kivy instantiates the TestApp subclass of App, the variable kv_directory is set. Kivy then implicitly searches for a .kv file matching the name of the subclass in that directory, finding the file template1/test.kv. That -file contains a root of class Widget. +file contains the root widget. ''' diff --git a/examples/canvas/lines_extended.py b/examples/canvas/lines_extended.py index 720fe06458..8f82c45b7b 100644 --- a/examples/canvas/lines_extended.py +++ b/examples/canvas/lines_extended.py @@ -54,7 +54,9 @@ rgba: .1, 1, .1, .9 Line: width: 2. - circle: (self.center_x, self.center_y, min(self.width, self.height) / 2) + circle: + (self.center_x, self.center_y, min(self.width, self.height) + / 2) Label: center: root.center text: 'Circle' @@ -65,7 +67,9 @@ rgba: .1, 1, .1, .9 Line: width: 2. - circle: (self.center_x, self.center_y, min(self.width, self.height) / 2, 90, 180) + circle: + (self.center_x, self.center_y, min(self.width, self.height) + / 2, 90, 180) Label: center: root.center text: 'Circle from 90 to 180' @@ -76,7 +80,9 @@ rgba: .1, 1, .1, .9 Line: width: 2. - circle: (self.center_x, self.center_y, min(self.width, self.height) / 2, 90, 180, 10) + circle: + (self.center_x, self.center_y, min(self.width, self.height) + / 2, 90, 180, 10) Label: center: root.center text: 'Circle from 90 to 180\\n10 segments' @@ -88,7 +94,9 @@ rgba: .1, 1, .1, .9 Line: width: 2. - circle: (self.center_x, self.center_y, min(self.width, self.height) / 2, 0, 360) + circle: + (self.center_x, self.center_y, min(self.width, self.height) + / 2, 0, 360) Label: center: root.center text: 'Circle from 0 to 360' @@ -111,7 +119,9 @@ rgba: .1, .1, 1, .9 Line: width: 2. - bezier: (self.x, self.y, self.center_x - 40, self.y + 100, self.center_x + 40, self.y - 100, self.right, self.y) + bezier: + (self.x, self.y, self.center_x - 40, self.y + 100, + self.center_x + 40, self.y - 100, self.right, self.y) Label: center: root.center text: 'Bezier' diff --git a/examples/canvas/scale.py b/examples/canvas/scale.py new file mode 100644 index 0000000000..34fdd28158 --- /dev/null +++ b/examples/canvas/scale.py @@ -0,0 +1,36 @@ +''' +Scaling Example +================ + +This example scales a button using PushMatrix and PopMatrix. It shows +a static button with the words 'hello world', stretched about its centre by +a factor of 1.5 horizontally and 5 vertically. +''' + + +from kivy.app import App +from kivy.lang import Builder + +kv = ''' +FloatLayout: + + Button: + text: 'hello world' + size_hint: None, None + pos_hint: {'center_x': .5, 'center_y': .5} + canvas.before: + PushMatrix + Scale: + x: 1.5 + y: 5 + origin: self.center + canvas.after: + PopMatrix +''' + + +class ScalingApp(App): + def build(self): + return Builder.load_string(kv) + +ScalingApp().run() diff --git a/examples/canvas/stencil_canvas.py b/examples/canvas/stencil_canvas.py index 92ff878de7..31b059da3e 100644 --- a/examples/canvas/stencil_canvas.py +++ b/examples/canvas/stencil_canvas.py @@ -3,8 +3,8 @@ ============ This is a test of the stencil graphics instruction inside the stencil view -widget. When you use a stencil, every draw outside the bounding box of the -stencil view will be avoid. All the graphics will draw only in the stencil view. +widget. When you use a stencil, nothing will be drawn outside the bounding +box. All the graphics will draw only in the stencil view. You can "draw" a stencil view by touch & draw. The touch down will set the position, and the drag will set the size. diff --git a/examples/container/main.py b/examples/container/main.py index 8a94f99cb9..856ea3bf93 100644 --- a/examples/container/main.py +++ b/examples/container/main.py @@ -43,7 +43,8 @@ def build(self): return self.root def next_screen(self, screen): - '''Clear container and load the given screen object from file in kv folder + '''Clear container and load the given screen object from file in kv + folder. :param screen: name of the screen object made from the loaded .kv file :type screen: str diff --git a/examples/gestures/my_gestures.py b/examples/gestures/my_gestures.py index fd7f8512f4..2151ae376b 100644 --- a/examples/gestures/my_gestures.py +++ b/examples/gestures/my_gestures.py @@ -4,13 +4,88 @@ gdb = GestureDatabase() cross = gdb.str_to_gesture( - 'eNq1l9tu3DYQhu/1It6bLjicE+cFtrcF/ACBYwv2Iqkt7G7a5u1DDqlT0lZ7I2Mxsj5JP2f4kxR1OH85//X9+Npfb98uffd7Ow6hO7wM0D0+vD/92T90Q8z/5gN218eH6+3y8aW/5lPqDl8H7g7/KvLot3WDFCnNzw8f5/dbeSyVx+w/Hvuj3NUNUDMoKXzPj0DsTuGIGiRJGCOVbP4pV7E7/RaORJZMwhS1u35++v9WyFvh7rU2ENEMJI1RuLu+NnEEgyhpjEG2xb1y0H3Ek4vbKA6kEmyKEWdxWPaJsaVN8eidH2Ef8ejiOIqHdbeQLvolaLTFLxlty7ulsVlaNBKChCnmEpp+uRSSIozRBLbl3dSoe8m7rdF2kkc3FmGSB1FVphYT6qSejY2sOsXtyYRuLOIkHgEtGrZIKJP4Spk13ZG524qzrXFWLlHmfok/9UvcFndTUe8Rz8OVA7RIYXtAoluKdke3hJU42j0dQ24pwV7ybiptm1oGE+Rz4ilu9w25q8R3qQtnZ2WKd+TutpLeox4pZmt1jHlh3VR3X8nuUceFdIm4qc5uKy9mapCY339jXKb+08tjewlmN5VxH3H3lBcLcASZfzGv4osFPiVk5SnmCb6p766y7qbvvvL0Zg2GKtHGCDjPJ2FKicfI2wuNuKsCu2i7qYLzdiP3BXGLYIs1DEAo0hh1eyaJeyq8i7b7KdM26ddNXpPO7SCSTnHbSnErxXaQVndSJyeJGQOMMe+RJm1aLrk5bku7kYp7SLuPOvlI6/FHs4+87hH2Fats/p8vff8+beVVyl5etTucMA/a7kSE+XAbNHVPmcGK2ZKBsxSciTPUyqAwUmdRKouFCToDqgwLU3MWQmVUmDnD1O7jwsCfOuXFt0JxGKNDaS1rhVwhV5gqpBW0CnEJLaw0G4QKwwrGmlJaQaxw1bp5QRBsBb2iZMvczQtSWjGvx09m5uXwmnk1tNKDEGYbZli94TX0aqg1nRrE5Z3WoFdDtWyFBr0aqR2URljLqa1bbNDrsToywth69QfqGIrcaDVoPSoBqkNtbDE1Wi3iqsAtV6gesSdL0vKCalLNdqa5rjpB3vrz69utfJTmz8qTFclM/z6/3N4cSteSyvT28bW/PL0/935Ffdsd1n9Q7muT+dNw+Xj59lzFU+6WY5L8ug5qwTR/PFH5bDz+AM/6Dqo=') + 'eNq1l9tu3DYQhu/1It6bLjicE+cFtrcF/ACBYwv2Iqkt7G7a5u1DDqlT0lZ7I2Mxsj5JP2f4k' + 'xR1OH85//X9+Npfb98uffd7Ow6hO7wM0D0+vD/92T90Q8z/5gN218eH6+3y8aW/5lPqDl8H7g' + '7/KvLot3WDFCnNzw8f5/dbeSyVx+w/Hvuj3NUNUDMoKXzPj0DsTuGIGiRJGCOVbP4pV7E7/Ra' + 'ORJZMwhS1u35++v9WyFvh7rU2ENEMJI1RuLu+NnEEgyhpjEG2xb1y0H3Ek4vbKA6kEmyKEWdx' + 'WPaJsaVN8eidH2Ef8ejiOIqHdbeQLvolaLTFLxlty7ulsVlaNBKChCnmEpp+uRSSIozRBLbl3' + 'dSoe8m7rdF2kkc3FmGSB1FVphYT6qSejY2sOsXtyYRuLOIkHgEtGrZIKJP4Spk13ZG524qzrX' + 'FWLlHmfok/9UvcFndTUe8Rz8OVA7RIYXtAoluKdke3hJU42j0dQ24pwV7ybiptm1oGE+Rz4il' + 'u9w25q8R3qQtnZ2WKd+TutpLeox4pZmt1jHlh3VR3X8nuUceFdIm4qc5uKy9mapCY339jXKb+' + '08tjewlmN5VxH3H3lBcLcASZfzGv4osFPiVk5SnmCb6p766y7qbvvvL0Zg2GKtHGCDjPJ2FKi' + 'cfI2wuNuKsCu2i7qYLzdiP3BXGLYIs1DEAo0hh1eyaJeyq8i7b7KdM26ddNXpPO7SCSTnHbSn' + 'ErxXaQVndSJyeJGQOMMe+RJm1aLrk5bku7kYp7SLuPOvlI6/FHs4+87hH2Fats/p8vff8+beV' + 'Vyl5etTucMA/a7kSE+XAbNHVPmcGK2ZKBsxSciTPUyqAwUmdRKouFCToDqgwLU3MWQmVUmDnD' + '1O7jwsCfOuXFt0JxGKNDaS1rhVwhV5gqpBW0CnEJLaw0G4QKwwrGmlJaQaxw1bp5QRBsBb2iZ' + 'MvczQtSWjGvx09m5uXwmnk1tNKDEGYbZli94TX0aqg1nRrE5Z3WoFdDtWyFBr0aqR2URljLqa' + '1bbNDrsToywth69QfqGIrcaDVoPSoBqkNtbDE1Wi3iqsAtV6gesSdL0vKCalLNdqa5rjpB3vr' + 'z69utfJTmz8qTFclM/z6/3N4cSteSyvT28bW/PL0/935Ffdsd1n9Q7muT+dNw+Xj59lzFU+6W' + 'Y5L8ug5qwTR/PFH5bDz+AM/6Dqo=') circle = gdb.str_to_gesture( - 'eNq1WNtyGzcMfd8fiV+iIS4EyB9QXzuTD+g4icbxpLU1ttI2f18QoHa5jpy12qlGAyUw9hA4ByQh3dx/vf/z++7u8Hz69nSYfumfxzTdfD7C9OHdw+0fh3fTEe2f9kHT84d3z6enx6+HZ/svTze/H/N0cxHkg4dNR2lQas8fH+8fTu2x0h6rrzz2a4uajhAZtBS+2yOA0z7tCDMkqjk1y0W1pfN3+zNN+/dpl0pGqmdLJcv0/PH25+uwr5Onu74EMxErVLeGMT3fNXQDT4C1kopbLVBhG92LB91Gh6RJinRb5A2ZF8euM/aP5JyxhVVShbBiJW9ho7OPcMZG1YTzWzTP2LgAm8XyBmx0bJqxsfSkm8UqMzaRluVduW5ju5o4qwkKmFWruM28cGLNcW3eriXOWi5kv8zbNK7GcwmbabtP0LXEWcuB7MY3pSVxVuRMiGFJaBOcXEzqYrZtwglLEsluBdOSen7R5LiN7nISzehAwsQZwC3yfwJ3PSnP4FZ31fnNrZX/PS8uKOkCvpBiFkfSF2Sz3PpoC9wVpTqDExXKmkvYmoc274S8nRZ2RXlR1B5u5xGG1bKcK7a5rtz77ILyIihVSVzL2bb8zuB4LefsgnJ+AzjQtTuUXVBeBCVRTKSMbq1HA/u9b7DMohpWSLbPFnZFuf4/6NklzYOki57N1rzAQ8YV/HY3Ztc0L5piXR0BMqAj1GItLmELb/OeXdQ87FKB8QhIOKDXOXGzOb2BGVc1D9sUaNxJNiPM6LQkbpbS9lbKrmpeVAXluRtTTloXdDs2B95z3UYXV1UWVe2aPydutqAO6HIt7+KqCm0f7A2+Fk1JkNyiTQ+b8C6rzJdpyrkoQUlhUx6IZ61XEi8uqyzXKSODTSphAcsAjnBlz4irKvN9CjVxsXEwu2UZ9iopXcmLuqgKWwOMb2JJNoh2y284B9Q11WU6En2NFuRrFVVXVJdhN71QdDhjBIe3a/3xtg3/n54Oh4d5lFdps7zNmjd7Rt2laY9ad3V88XQ6apluW0TxiAL2Yc7qTkqjs6RwSjgxnOBOhpUTw6krJ7kz06up2D3iETUiNB7L7pT+WLZhf3hJi5CIiLyU4zENZ5SlPYWoVSNZTeGMWv25vWnqzhq1amBKYNaotcTjuUdGrSXy8+rMGbWW7E6u66SpRUStJRbgvGZDW0QUXqICjgqqjE6q4dSVM19Yrawi4MJqwUIJyTBqg5TGOpC6F1be9ON6ttdGVkB+XNA2ZYREjwFfCgmSNJKC8/JBjMbyAN0bzLjS5k3dG9RoLJJK95axY9K52KBAohGShBeCAgncdIFcABj79nJI8JHzT0L6/kg/CQk+mFd5Q/BBtKoRZNzXZz4g+MC0YhSCD+hqXWhGgCAn1dcFxWAqdV0uND1gMJWCTIyeBnRy7CtZeLl7KbxRLPaykMObXu1k+1rpIb2VL20Hm9siJFKlTiTqylu7t4SXx31o35ZW3p4zpZVXLyxNsAq5xBIFH/1syH1FCj76Hs69PSn4KHU8k2w+D5aCZ+lbhKLqGvVJF5+i6hp0yRk3WiLFWSedfepdQOMBCtyFl/GsBe5a9xO4r8axESCNh7UNo+GFVw95YB57VHuaHL0Pebwy7DYPb79IevLcex/W3n7/0dobhWI+X1buzVEoytprhcYN/OVwf/fl1H70sql+ry83CbbfxP66/3z64iF2m9sJZxjmPT3+fni6ffh08L9w/IixfkGL68PDb8enx8/fPsVSedrnnc05diDYoIA2CpbUvu7t/gFuoPx3') + 'eNq1WNtyGzcMfd8fiV+iIS4EyB9QXzuTD+g4icbxpLU1ttI2f18QoHa5jpy12qlGAyUw9hA4B' + 'yQh3dx/vf/z++7u8Hz69nSYfumfxzTdfD7C9OHdw+0fh3fTEe2f9kHT84d3z6enx6+HZ/svTz' + 'e/H/N0cxHkg4dNR2lQas8fH+8fTu2x0h6rrzz2a4uajhAZtBS+2yOA0z7tCDMkqjk1y0W1pfN' + '3+zNN+/dpl0pGqmdLJcv0/PH25+uwr5Onu74EMxErVLeGMT3fNXQDT4C1kopbLVBhG92LB91G' + 'h6RJinRb5A2ZF8euM/aP5JyxhVVShbBiJW9ho7OPcMZG1YTzWzTP2LgAm8XyBmx0bJqxsfSkm' + '8UqMzaRluVduW5ju5o4qwkKmFWruM28cGLNcW3eriXOWi5kv8zbNK7GcwmbabtP0LXEWcuB7M' + 'Y3pSVxVuRMiGFJaBOcXEzqYrZtwglLEsluBdOSen7R5LiN7nISzehAwsQZwC3yfwJ3PSnP4FZ' + '31fnNrZX/PS8uKOkCvpBiFkfSF2Sz3PpoC9wVpTqDExXKmkvYmoc274S8nRZ2RXlR1B5u5xGG' + '1bKcK7a5rtz77ILyIihVSVzL2bb8zuB4LefsgnJ+AzjQtTuUXVBeBCVRTKSMbq1HA/u9b7DMo' + 'hpWSLbPFnZFuf4/6NklzYOki57N1rzAQ8YV/HY3Ztc0L5piXR0BMqAj1GItLmELb/OeXdQ87F' + 'KB8QhIOKDXOXGzOb2BGVc1D9sUaNxJNiPM6LQkbpbS9lbKrmpeVAXluRtTTloXdDs2B95z3UY' + 'XV1UWVe2aPydutqAO6HIt7+KqCm0f7A2+Fk1JkNyiTQ+b8C6rzJdpyrkoQUlhUx6IZ61XEi8u' + 'qyzXKSODTSphAcsAjnBlz4irKvN9CjVxsXEwu2UZ9iopXcmLuqgKWwOMb2JJNoh2y284B9Q11' + 'WU6En2NFuRrFVVXVJdhN71QdDhjBIe3a/3xtg3/n54Oh4d5lFdps7zNmjd7Rt2laY9ad3V88X' + 'Q6apluW0TxiAL2Yc7qTkqjs6RwSjgxnOBOhpUTw6krJ7kz06up2D3iETUiNB7L7pT+WLZhf3h' + 'Ji5CIiLyU4zENZ5SlPYWoVSNZTeGMWv25vWnqzhq1amBKYNaotcTjuUdGrSXy8+rMGbWW7E6u' + '66SpRUStJRbgvGZDW0QUXqICjgqqjE6q4dSVM19Yrawi4MJqwUIJyTBqg5TGOpC6F1be9ON6t' + 'tdGVkB+XNA2ZYREjwFfCgmSNJKC8/JBjMbyAN0bzLjS5k3dG9RoLJJK95axY9K52KBAohGShB' + 'eCAgncdIFcABj79nJI8JHzT0L6/kg/CQk+mFd5Q/BBtKoRZNzXZz4g+MC0YhSCD+hqXWhGgCA' + 'n1dcFxWAqdV0uND1gMJWCTIyeBnRy7CtZeLl7KbxRLPaykMObXu1k+1rpIb2VL20Hm9siJFKl' + 'TiTqylu7t4SXx31o35ZW3p4zpZVXLyxNsAq5xBIFH/1syH1FCj76Hs69PSn4KHU8k2w+D5aCZ' + '+lbhKLqGvVJF5+i6hp0yRk3WiLFWSedfepdQOMBCtyFl/GsBe5a9xO4r8axESCNh7UNo+GFVw' + '95YB57VHuaHL0Pebwy7DYPb79IevLcex/W3n7/0dobhWI+X1buzVEoytprhcYN/OVwf/fl1H7' + '0sql+ry83CbbfxP66/3z64iF2m9sJZxjmPT3+fni6ffh08L9w/IixfkGL68PDb8enx8/fPsVS' + 'edrnnc05diDYoIA2CpbUvu7t/gFuoPx3') check = gdb.str_to_gesture( - 'eNq1l0tuI0cMhvd9EXsTofgmL6BsA/gAgcYWbGMmtmBpksztwyY1kgZI0rNpbdr+u+pjkX+9+v718+uf3zbP++Pp68d++vX8PIzp/ukA08Pd2+6P/d10wPwzHzQdH+6Op4/3z/tj/svT/ZeDTPf/CnmoZtNBZ5Rl/8P769tp7uZzt/iPbr/NraYD9AjmIXzLLoDTdmxgBLsSMMIw5OHzcP6eX9O0/WVsCMFGmCuaGgjBdPy0+/8wXGFkeu4Ig7LzgISbMw/j6fh8hmMMBDIkdBYPimV4pQ7W8EQMUA4LMhMzCyW5watKgJoOHhxsuIz3wscVb8ExhpIxDoIgvcEzhoaiZ1geA20Rj+UAwlp4LDxd8OkqO4KHYXLI4oYOwEai4oPRmHiZXr6iXOiY9mXBFUNYacAVDm4uIOCiaXws24plK9oq7PIUr56iOqsyg+acyOrezJicpTCI3YYy5HtapFNZSldLCcRgCCk4hqniDZ2dHZjCMf1EXh47laNEN2MfEjkzJFgtK3BLHwEAGTcnlSu7LNPLUbo6+n2m5GbAuVzUr/ShYQzoSBSWi5iXJwyVqWRr4ctX+om1mq+GR7ibAA8dJuHLfC5nGVbjl7dMS/tk1g3tB3OXZyWXsyyrsMtWtlXY5SnHGmwpPwW+s3M15h5CkVvM8FyWcWH3Uce5io00A/8Eu7wUWoVdXoqswi4v5eIlseTWl6e9Cqh6+IUt6OoUwAJD88KwjC4rJVZAazmpsAa6jFRaA10+qqyBLht1DRu1bNQ1bLSy0S425mWFOc9khtxcnRwuaEW6PZnH8sFp5aPRKuwy0i5GMnsmHJE32dz73a5oG3nJgLyemqDgXKtPu/m2//ix379d7u6m8+XdbLrf5jg2Y9picD5OB/NpN4vQIrYYLWKJHiX6aJFblBahRSvRvEUsETuQjRapxe6uHSjPsBK7u0CL0mKUyLKJ25/NLbRaUI+PzwGsRWrxzOr0qKNy5+ydHnVUzsftj7JFdK7cAUSrW3SugrdpReeqdluV6Fxdu6hdv6hcCeYabQl7KFG5ElWpiM6itqgtWovWorXYlU6/d234y/71+eWUVud1dRvz2xT/en06vcwfWiP7QFU51dP7l/3H7u1xX2+gP9F+/MHc7jw1fz98vD99fTxV65yN6YfP81jE8nDMa8j81bD5B2R9zCo=') + 'eNq1l0tuI0cMhvd9EXsTofgmL6BsA/gAgcYWbGMmtmBpksztwyY1kgZI0rNpbdr+u+pjkX+9+' + 'v718+uf3zbP++Pp68d++vX8PIzp/ukA08Pd2+6P/d10wPwzHzQdH+6Op4/3z/tj/svT/ZeDTP' + 'f/CnmoZtNBZ5Rl/8P769tp7uZzt/iPbr/NraYD9AjmIXzLLoDTdmxgBLsSMMIw5OHzcP6eX9O' + '0/WVsCMFGmCuaGgjBdPy0+/8wXGFkeu4Ig7LzgISbMw/j6fh8hmMMBDIkdBYPimV4pQ7W8EQM' + 'UA4LMhMzCyW5watKgJoOHhxsuIz3wscVb8ExhpIxDoIgvcEzhoaiZ1geA20Rj+UAwlp4LDxd8' + 'OkqO4KHYXLI4oYOwEai4oPRmHiZXr6iXOiY9mXBFUNYacAVDm4uIOCiaXws24plK9oq7PIUr5' + '6iOqsyg+acyOrezJicpTCI3YYy5HtapFNZSldLCcRgCCk4hqniDZ2dHZjCMf1EXh47laNEN2M' + 'fEjkzJFgtK3BLHwEAGTcnlSu7LNPLUbo6+n2m5GbAuVzUr/ShYQzoSBSWi5iXJwyVqWRr4ctX' + '+om1mq+GR7ibAA8dJuHLfC5nGVbjl7dMS/tk1g3tB3OXZyWXsyyrsMtWtlXY5SnHGmwpPwW+s' + '3M15h5CkVvM8FyWcWH3Uce5io00A/8Eu7wUWoVdXoqswi4v5eIlseTWl6e9Cqh6+IUt6OoUwA' + 'JD88KwjC4rJVZAazmpsAa6jFRaA10+qqyBLht1DRu1bNQ1bLSy0S425mWFOc9khtxcnRwuaEW' + '6PZnH8sFp5aPRKuwy0i5GMnsmHJE32dz73a5oG3nJgLyemqDgXKtPu/m2//ix379d7u6m8+Xd' + 'bLrf5jg2Y9picD5OB/NpN4vQIrYYLWKJHiX6aJFblBahRSvRvEUsETuQjRapxe6uHSjPsBK7u' + '0CL0mKUyLKJ25/NLbRaUI+PzwGsRWrxzOr0qKNy5+ydHnVUzsftj7JFdK7cAUSrW3SugrdpRe' + 'eqdluV6Fxdu6hdv6hcCeYabQl7KFG5ElWpiM6itqgtWovWorXYlU6/d234y/71+eWUVud1dRv' + 'z2xT/en06vcwfWiP7QFU51dP7l/3H7u1xX2+gP9F+/MHc7jw1fz98vD99fTxV65yN6YfP81jE' + '8nDMa8j81bD5B2R9zCo=') square = gdb.str_to_gesture( - 'eNq1mEluIzcYRvd1EXsT4Z+HC6i3AXyAwG0LttEdW7DUSfr2YZHVEgk4KQGCtZH8RD4OH4eSb1++vfz1c/O0Oxx/vO+mL8v7Hqbbxz1Odzev93/ubqY9lY/ljafD3c3h+P72bXcof8p0+32v0+2HkrtabNrbrPJSf//28nqcq8VcLf+j2u9zqWmPrQdzF36WKkjTFjasKZKMaJwqGTp355/5a562v8FGREAVLIINymebDl/v/78Zqc3o9LS04EgogK6ECeSlhadFTomIHElsKqoS6/I6dPQL5JiWaSTKYMZEuS6PKs8L5DD03DB11U51+gnX7EVuGOQUgqDIxHGBnKqc1+XkJXLMyAyXUFkPlGqgpJ/irnmSr7s5kThBIhAB5RJ3jZPOcYpbiIG6elkc81Je3DL222TVzTVMPoVJggFESoEGBIJndyirWWpYRonyAnfNkk9ZQkQYghuLSlnI7tfIa5i8hDmvZFBSUwdH5ixDgKv6XvNkP+mxbDxgo1S2JIhr3DVPzpOb0IGQ3DTVhTPP8nEH+bpcaqCCJzkHOjlqpISFAp/lZMqMZqIBLnCBvCYqfJKLEqNyCgkFFNlZjt0qJaD1rS81UTknKuEGqYgRGUZdnsxlnapilrkiKafjurzmKec8Sy12KTPvTmWn5lle9mS/B2z9MJcaqOSqvC7TflRlkZZ7bM2vNVPFT/PXWJUv8ZO5hkiAQVkz5Wpat9dcVT/JXoNVv8Quoz3Wl43WZDU/x241V1vfq+UrRTFhLicyAxpecG1YTdXOqVLXP4XSRmcHCg/NIPGAcnOs22uqdk4Vx777dfaaqp2uU+jPWGdkvcpeU7X8HLvXVP10pWJKOdSFksIMSgNXyWuofrpTyyUKaewgxuCJeJW8ZuqnB6TxIATspkXGJ16r8vkHwMP7bvd6epx3m5/ny0V/uy1X4wamLaWVt+PeY7qfoQ8wG8wGvcKACjMGiDMsj/EDpApRB8gV0lhdKpSxulaoI7QKDQfoDfIAY4Cyyf4lc4lsJaSV4FotYYDzCd69bC6BfYloU5XUQ88GeYBLA9JD+6BfqX0J1VZtGThVKD72i+cS3k+NUKvWZkFbhMwfVMu+BOXYHy8lENqcaMuM2vyWp+WB2kJpoLrQNhOqI21Toa3HJAttw5c2fOKFtvGzjrSNmWikbdAAI11WMw8U23L2HCkOdBkxUk8/msyyCVsj0IeAKAP9aI5R+yJ1+mZqPXVYqPc0fjUSA82FZk9zmWNqo45hG5WfSB1lWOaCqDMwLDkTD/SXoQy0nTzPu5en52P9f4BO25jbLfTvl8fjc4VWoDZ4fPu+e79/fdjVL7we0jC+cC63nJJ/7N/fHn88NHdM29xw+VUXOp+Mzm7FcPi6+ReGcFi7') + 'eNq1mEluIzcYRvd1EXsT4Z+HC6i3AXyAwG0LttEdW7DUSfr2YZHVEgk4KQGCtZH8RD4OH4eSb' + '1++vfz1c/O0Oxx/vO+mL8v7Hqbbxz1Odzev93/ubqY9lY/ljafD3c3h+P72bXcof8p0+32v0+' + '2HkrtabNrbrPJSf//28nqcq8VcLf+j2u9zqWmPrQdzF36WKkjTFjasKZKMaJwqGTp355/5a56' + '2v8FGREAVLIINymebDl/v/78Zqc3o9LS04EgogK6ECeSlhadFTomIHElsKqoS6/I6dPQL5JiW' + 'aSTKYMZEuS6PKs8L5DD03DB11U51+gnX7EVuGOQUgqDIxHGBnKqc1+XkJXLMyAyXUFkPlGqgp' + 'J/irnmSr7s5kThBIhAB5RJ3jZPOcYpbiIG6elkc81Je3DL222TVzTVMPoVJggFESoEGBIJndy' + 'irWWpYRonyAnfNkk9ZQkQYghuLSlnI7tfIa5i8hDmvZFBSUwdH5ixDgKv6XvNkP+mxbDxgo1S' + '2JIhr3DVPzpOb0IGQ3DTVhTPP8nEH+bpcaqCCJzkHOjlqpISFAp/lZMqMZqIBLnCBvCYqfJKL' + 'EqNyCgkFFNlZjt0qJaD1rS81UTknKuEGqYgRGUZdnsxlnapilrkiKafjurzmKec8Sy12KTPvT' + 'mWn5lle9mS/B2z9MJcaqOSqvC7TflRlkZZ7bM2vNVPFT/PXWJUv8ZO5hkiAQVkz5Wpat9dcVT' + '/JXoNVv8Quoz3Wl43WZDU/x241V1vfq+UrRTFhLicyAxpecG1YTdXOqVLXP4XSRmcHCg/NIPG' + 'AcnOs22uqdk4Vx777dfaaqp2uU+jPWGdkvcpeU7X8HLvXVP10pWJKOdSFksIMSgNXyWuofrpT' + 'yyUKaewgxuCJeJW8ZuqnB6TxIATspkXGJ16r8vkHwMP7bvd6epx3m5/ny0V/uy1X4wamLaWVt' + '+PeY7qfoQ8wG8wGvcKACjMGiDMsj/EDpApRB8gV0lhdKpSxulaoI7QKDQfoDfIAY4Cyyf4lc4' + 'lsJaSV4FotYYDzCd69bC6BfYloU5XUQ88GeYBLA9JD+6BfqX0J1VZtGThVKD72i+cS3k+NUKv' + 'WZkFbhMwfVMu+BOXYHy8lENqcaMuM2vyWp+WB2kJpoLrQNhOqI21Toa3HJAttw5c2fOKFtvGz' + 'jrSNmWikbdAAI11WMw8U23L2HCkOdBkxUk8/msyyCVsj0IeAKAP9aI5R+yJ1+mZqPXVYqPc0f' + 'jUSA82FZk9zmWNqo45hG5WfSB1lWOaCqDMwLDkTD/SXoQy0nTzPu5en52P9f4BO25jbLfTvl8' + 'fjc4VWoDZ4fPu+e79/fdjVL7we0jC+cC63nJJ/7N/fHn88NHdM29xw+VUXOp+Mzm7FcPi6+Re' + 'GcFi7') diff --git a/examples/widgets/colorpicker.py b/examples/widgets/colorpicker.py index 29bb7b72de..fccaa817df 100644 --- a/examples/widgets/colorpicker.py +++ b/examples/widgets/colorpicker.py @@ -18,12 +18,12 @@ # as soon as the image is loaded, ensure that the center is changed # to the center of the screen. on_size: self.center = app.main_root_widget.center - size: image.size + size: img.size size_hint: None, None - on_touch_down: if self.collide_point(*args[1].pos): app.current_image = image + on_touch_down: if self.collide_point(*args[1].pos): app.current_image = img Image: - id: image + id: img source: root.source # create initial image to be 400 pixels width @@ -32,12 +32,12 @@ # add shadow background canvas.before: Color: - rgba: 1,1,1,1 + rgba: 1, 1, 1, 1 BorderImage: source: '../demo/pictures/shadow32.png' - border: (36,36,36,36) - size:(self.width+72, self.height+72) - pos: (-36,-36) + border: (36, 36, 36, 36) + size:(self.width + 72, self.height + 72) + pos: (-36, -36) : color: 1, 1, 1, 1 @@ -77,7 +77,9 @@ valign: 'middle' halign: 'center' height: self.texture.size[1] if self.texture else 10 - text: 'Selected Image:\\n' + app.current_image.source.split(os.sep)[2] if app.current_image else 'None' + text: + ("Selected Image:\\n' + app.current_image.source.split(os.sep)[2] " + "if app.current_image else 'None'") Button: text: 'Brush' size_hint_y: None @@ -150,9 +152,9 @@ def on_touch_down(self, touch): return super(Picture, self).on_touch_down(touch) ud = touch.ud ud['group'] = g = str(touch.uid) - _pos = list(self.ids.image.to_widget(*touch.pos)) + _pos = list(self.ids.img.to_widget(*touch.pos)) _pos[0] += self.parent.x - with self.ids.image.canvas.after: + with self.ids.img.canvas.after: ud['color'] = Color(*_app.color_selector.color, group=g) ud['lines'] = Point(points=(_pos), source='../examples/demo/touchtracer/particle.png', @@ -167,7 +169,7 @@ def on_touch_move(self, touch): if _app.color_mode[0] == 'c' or not self.collide_point(*touch.pos): return super(Picture, self).on_touch_move(touch) ud = touch.ud - _pos = list(self.ids.image.to_widget(*touch.pos)) + _pos = list(self.ids.img.to_widget(*touch.pos)) _pos[0] += self.parent.x points = ud['lines'].points oldx, oldy = points[-2], points[-1] diff --git a/examples/widgets/tabbedpanel.py b/examples/widgets/tabbedpanel.py index 67b1223abb..9d08d0ac30 100644 --- a/examples/widgets/tabbedpanel.py +++ b/examples/widgets/tabbedpanel.py @@ -31,7 +31,9 @@ TabbedPanelItem: text: 'tab3' RstDocument: - text: '\\n'.join(("Hello world", "-----------", "You are in the third tab.")) + text: + '\\n'.join(("Hello world", "-----------", + "You are in the third tab.")) """) diff --git a/examples/widgets/unicode_textinput.py b/examples/widgets/unicode_textinput.py index c306f254ca..8b5a5bef9c 100644 --- a/examples/widgets/unicode_textinput.py +++ b/examples/widgets/unicode_textinput.py @@ -28,7 +28,9 @@ Spinner: id: fnt_spnr text: 'DroidSansMono' - fnt_name: font.match_font(self.text) if font.match_font(self.text) else '' + fnt_name: + (font.match_font(self.text) if font.match_font(self.text) + else '') font_name: self.fnt_name if self.fnt_name else self.font_name values: sorted(font.get_fonts()) option_cls: Factory.FntSpinnerOption @@ -75,9 +77,12 @@ text_size: self.size on_release: _platform = root.platform - filechooser.path = os.path.expanduser('~/.fonts')\ -if _platform == 'linux' else '/system/fonts' if _platform == 'android' else os.path.expanduser('~/Library/Fonts')\ -if _platform == 'macosx' else os.environ['WINDIR'] + '\Fonts\' + filechooser.path = (os.path.expanduser('~/.fonts') + if _platform == 'linux' else '/system/fonts' + if _platform == 'android' + else os.path.expanduser('~/Library/Fonts') + if _platform == 'macosx' + else os.environ['WINDIR'] +'\Fonts\') Button: size_hint: 1, .2 text: 'System Font directory' @@ -86,10 +91,11 @@ text_size: self.size on_release: _platform = root.platform - filechooser.path = '/usr/share/fonts' \ -if _platform == 'linux' else '/system/fonts' if _platform == 'android' else os.path.expanduser\ -('/System/Library/Fonts') if _platform == 'macosx' else os.environ['WINDIR']\ -+ "\Fonts\" + filechooser.path = ('/usr/share/fonts' + if _platform == 'linux' else '/system/fonts' + if _platform == 'android' else os.path.expanduser + ('/System/Library/Fonts') if _platform == 'macosx' + else os.environ['WINDIR'] + "\Fonts\") Label: text: 'BookMarks' BoxLayout: @@ -126,8 +132,8 @@ class Unicode_TextInput(BoxLayout): List of major languages taken from Google Translate ____________________________________________________ -Try changing the font to see if the font can render the glyphs you need in your application. -Scroll to see all languages in list +Try changing the font to see if the font can render the glyphs you need in your +application. Scroll to see all languages in the list. Basic Latin: The quick brown fox jumps over the lazy old dog. Albanian: Kafe të shpejtë dhelpra hedhje mbi qen lazy vjetër. diff --git a/kivy/__init__.py b/kivy/__init__.py index 79c9effadb..49c0d608f0 100644 --- a/kivy/__init__.py +++ b/kivy/__init__.py @@ -191,8 +191,8 @@ def kivy_usage(): 'camera': ('opencv', 'gi', 'pygst', 'videocapture', 'avfoundation'), 'spelling': ('enchant', 'osxappkit', ), 'clipboard': ( - 'android', 'winctypes', 'xsel', 'dbusklipper', 'nspaste', 'sdl2', 'pygame', - 'dummy'), } + 'android', 'winctypes', 'xsel', 'dbusklipper', 'nspaste', 'sdl2', + 'pygame', 'dummy')} # Read environment for option in kivy_options: diff --git a/kivy/cache.py b/kivy/cache.py index bee4b9efbd..5b23f1a8c4 100644 --- a/kivy/cache.py +++ b/kivy/cache.py @@ -57,7 +57,7 @@ def register(category, limit=None, timeout=None): 'timeout': timeout} Cache._objects[category] = {} Logger.debug( - 'Cache: register <%s> with limit=%s, timeout=%ss' % + 'Cache: register <%s> with limit=%s, timeout=%s' % (category, str(limit), str(timeout))) @staticmethod diff --git a/kivy/core/clipboard/__init__.py b/kivy/core/clipboard/__init__.py index 813083ec11..ac858edf60 100644 --- a/kivy/core/clipboard/__init__.py +++ b/kivy/core/clipboard/__init__.py @@ -59,8 +59,8 @@ def _ensure_clipboard(self): if platform == 'win': self._clip_mime_type = 'text/plain;charset=utf-8' - # windows clipboard uses a utf-16 encoding - self._encoding = 'utf-16' + # windows clipboard uses a utf-16 little endian encoding + self._encoding = 'utf-16-le' elif platform == 'linux': self._clip_mime_type = 'UTF8_STRING' self._encoding = 'utf-8' @@ -127,7 +127,7 @@ def _paste(self): ('winctypes', 'clipboard_winctypes', 'ClipboardWindows')) elif platform == 'linux': _clipboards.append( - ('xsel', 'clipboard_xsel', 'Clipboardxsel')) + ('xsel', 'clipboard_xsel', 'ClipboardXsel')) _clipboards.append( ('dbusklipper', 'clipboard_dbusklipper', 'ClipboardDbusKlipper')) diff --git a/kivy/core/clipboard/clipboard_dbusklipper.py b/kivy/core/clipboard/clipboard_dbusklipper.py index f7891281a0..48a9467aee 100644 --- a/kivy/core/clipboard/clipboard_dbusklipper.py +++ b/kivy/core/clipboard/clipboard_dbusklipper.py @@ -38,4 +38,4 @@ def put(self, data, mimetype='text/plain'): def get_types(self): self.init() - return 'text/plain' + return list('text/plain',) diff --git a/kivy/core/clipboard/clipboard_nspaste.py b/kivy/core/clipboard/clipboard_nspaste.py index f251a7a32a..05db7b0030 100644 --- a/kivy/core/clipboard/clipboard_nspaste.py +++ b/kivy/core/clipboard/clipboard_nspaste.py @@ -29,7 +29,10 @@ def __init__(self): def get(self, mimetype='text/plain'): pb = self._clipboard - return pb.stringForType_('public.utf8-plain-text').UTF8String() + data = pb.stringForType_('public.utf8-plain-text') + if not data: + return "" + return data.UTF8String() def put(self, data, mimetype='text/plain'): pb = self._clipboard diff --git a/kivy/core/clipboard/clipboard_sdl2.py b/kivy/core/clipboard/clipboard_sdl2.py index 660d881254..aabaa1ed44 100644 --- a/kivy/core/clipboard/clipboard_sdl2.py +++ b/kivy/core/clipboard/clipboard_sdl2.py @@ -19,12 +19,15 @@ class ClipboardSDL2(ClipboardBase): - def paste(self): + def get(self, mimetype): return _get_text() if _has_text() else '' - def copy(self, data=''): - data = data.encode('utf-8') + def _ensure_clipboard(self): + super(ClipboardSDL2, self)._ensure_clipboard() + self._encoding = 'utf8' + + def put(self, data=b'', mimetype='text/plain'): _set_text(data) def get_types(self): - return 'text/plain' + return ['text/plain'] diff --git a/kivy/core/clipboard/clipboard_winctypes.py b/kivy/core/clipboard/clipboard_winctypes.py index 4b4318cff1..a5a433a5a5 100644 --- a/kivy/core/clipboard/clipboard_winctypes.py +++ b/kivy/core/clipboard/clipboard_winctypes.py @@ -26,7 +26,7 @@ def get(self, mimetype='text/plain'): pcontents = user32.GetClipboardData(13) if not pcontents: return '' - data = c_wchar_p(pcontents).value.encode('utf-16') + data = c_wchar_p(pcontents).value.encode(self._encoding) #ctypes.windll.kernel32.GlobalUnlock(pcontents) user32.CloseClipboard() return data diff --git a/kivy/core/clipboard/clipboard_xsel.py b/kivy/core/clipboard/clipboard_xsel.py index a5d67cb70b..ac7e18e1be 100644 --- a/kivy/core/clipboard/clipboard_xsel.py +++ b/kivy/core/clipboard/clipboard_xsel.py @@ -2,7 +2,7 @@ Clipboard xsel: an implementation of the Clipboard using xsel command line tool. ''' -__all__ = ('Clipboardxsel', ) +__all__ = ('ClipboardXsel', ) from kivy.utils import platform from kivy.core.clipboard import ClipboardBase @@ -18,10 +18,10 @@ raise -class Clipboardxsel(ClipboardBase): +class ClipboardXsel(ClipboardBase): def get(self, mimetype='text/plain'): - p = subprocess.Popen(['xsel', 'b'], stdout=subprocess.PIPE) + p = subprocess.Popen(['xsel', '-bo'], stdout=subprocess.PIPE) data, _ = p.communicate() return data @@ -30,4 +30,4 @@ def put(self, data, mimetype='text/plain'): p.communicate(data) def get_types(self): - return 'text/plain' + return list('text/plain',) diff --git a/kivy/core/window/__init__.py b/kivy/core/window/__init__.py index bfb57b5025..4deae1200d 100755 --- a/kivy/core/window/__init__.py +++ b/kivy/core/window/__init__.py @@ -61,7 +61,7 @@ class Keyboard(EventDispatcher): # specials keys 'backspace': 8, 'tab': 9, 'enter': 13, 'rshift': 303, 'shift': 304, 'alt': 308, 'rctrl': 306, 'lctrl': 305, - 'super': 309, 'alt-gr': 307, 'compose': 311, 'pipe': 310, + 'super': 309, 'alt-gr': 307, 'compose': 311, 'pipe': 310, 'capslock': 301, 'escape': 27, 'spacebar': 32, 'pageup': 280, 'pagedown': 281, 'end': 279, 'home': 278, 'left': 276, 'up': 273, 'right': 275, 'down': 274, 'insert': 277, 'delete': 127, @@ -82,7 +82,7 @@ class Keyboard(EventDispatcher): 'numpad4': 260, 'numpad5': 261, 'numpad6': 262, 'numpad7': 263, 'numpad8': 264, 'numpad9': 265, 'numpaddecimal': 266, 'numpaddivide': 267, 'numpadmul': 268, 'numpadsubstract': 269, - 'numpadadd': 270, 'numpadenter': 271, + 'numpadadd': 270, 'numpadenter': 271, # F1-15 'f1': 282, 'f2': 283, 'f3': 284, 'f4': 285, 'f5': 286, 'f6': 287, @@ -1137,9 +1137,10 @@ def on_key_up(self, key, scancode=None, codepoint=None, "semantics.") def on_textinput(self, text): - '''Event called whem text: i.e. alpha numeric non control keys or set of keys - is entered. As it is not gaurenteed whether we get one characyer or multiple - characters, this event supports handling multiple characters. + '''Event called whem text: i.e. alpha numeric non control keys or set + of keys is entered. As it is not gaurenteed whether we get one + character or multiple ones, this event supports handling multiple + characters. ..versionadded:: 1.9.0 ''' diff --git a/kivy/core/window/_window_sdl2.pyx b/kivy/core/window/_window_sdl2.pyx index 4856ac0961..42558191a2 100644 --- a/kivy/core/window/_window_sdl2.pyx +++ b/kivy/core/window/_window_sdl2.pyx @@ -25,7 +25,7 @@ cdef class _WindowSDL2Storage: self.win_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN IF USE_IOS: - self.win_flags |= SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_FULLSCREEN + self.win_flags |= SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_ALLOW_HIGHDPI ELSE: if resizable: self.win_flags |= SDL_WINDOW_RESIZABLE @@ -44,6 +44,10 @@ cdef class _WindowSDL2Storage: if PY3: orientations = bytes(environ.get('KIVY_ORIENTATION', 'LandscapeLeft LandscapeRight'), encoding='utf8') + elif USE_IOS: + # ios should use all if available + orientations = environ.get('KIVY_ORIENTATION', + 'LandscapeLeft LandscapeRight Portrait PortraitUpsideDown') else: orientations = environ.get('KIVY_ORIENTATION', 'LandscapeLeft LandscapeRight') @@ -87,6 +91,13 @@ cdef class _WindowSDL2Storage: self.die() cdef SDL_DisplayMode mode SDL_GetWindowDisplayMode(self.win, &mode) + + cdef int w, h + SDL_GL_GetDrawableSize(self.win, &w, &h) + mode.w = w + mode.h = h + SDL_SetWindowDisplayMode(self.win, &mode) + SDL_JoystickOpen(0) SDL_EventState(SDL_DROPFILE, SDL_ENABLE) @@ -94,11 +105,20 @@ cdef class _WindowSDL2Storage: def resize_display_mode(self, w, h): cdef SDL_DisplayMode mode + cdef int draw_w, draw_h SDL_GetWindowDisplayMode(self.win, &mode) - mode.w = w - mode.h = h - SDL_SetWindowDisplayMode(self.win, &mode) - SDL_GetWindowDisplayMode(self.win, &mode) + if USE_IOS: + SDL_GL_GetDrawableSize(self.win, &draw_w, &draw_h) + mode.w = draw_w + mode.h = draw_h + SDL_SetWindowDisplayMode(self.win, &mode) + else: + mode.w = w + mode.h = h + SDL_SetWindowDisplayMode(self.win, &mode) + SDL_GetWindowDisplayMode(self.win, &mode) + + return mode.w, mode.h def resize_window(self, w, h): if self.window_size != [w, h]: diff --git a/kivy/core/window/window_sdl2.py b/kivy/core/window/window_sdl2.py index e6fefcca89..622a17c0fb 100644 --- a/kivy/core/window/window_sdl2.py +++ b/kivy/core/window/window_sdl2.py @@ -345,7 +345,8 @@ def _mainloop(self): self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': - self._size = args + if platform != "ios": + self._size = args # don't use trigger here, we want to delay the resize event cb = self._do_resize Clock.unschedule(cb) @@ -456,7 +457,10 @@ def _mainloop(self): def _do_resize(self, dt): Logger.debug('Window: Resize window to %s' % str(self._size)) - self._win.resize_display_mode(*self._size) + if platform == "ios": + self._size = self._win.resize_display_mode(*self._size) + else: + self._win.resize_display_mode(*self._size) self.dispatch('on_resize', *self._size) def do_pause(self): diff --git a/kivy/graphics/context_instructions.pxd b/kivy/graphics/context_instructions.pxd index e00be285d2..f6562b168f 100644 --- a/kivy/graphics/context_instructions.pxd +++ b/kivy/graphics/context_instructions.pxd @@ -65,6 +65,7 @@ cdef class Rotate(Transform): cdef void compute(self) cdef class Scale(Transform): + cdef tuple _origin cdef float _x, _y, _z cdef void apply(self) cdef set_scale(self, double x, double y, double z) diff --git a/kivy/graphics/context_instructions.pyx b/kivy/graphics/context_instructions.pyx index 8aa4631335..2107a2c7a4 100644 --- a/kivy/graphics/context_instructions.pyx +++ b/kivy/graphics/context_instructions.pyx @@ -695,6 +695,17 @@ cdef class Scale(Transform): def __init__(self, *args, **kwargs): cdef double x, y, z Transform.__init__(self, **kwargs) + self._origin = (0, 0, 0) + + if 'origin' in kwargs: + origin = kwargs['origin'] + if len(origin) == 3: + self._origin = tuple(origin) + elif len(origin) == 2: + self._origin = (origin[0], origin[1], 0.) + else: + raise Exception('invalid number of components in origin') + if len(args) == 1: s = args[0] self.set_scale(s, s, s) @@ -705,10 +716,16 @@ cdef class Scale(Transform): self.set_scale(1.0, 1.0, 1.0) cdef set_scale(self, double x, double y, double z): + cdef float ox, oy, oz self._x = x self._y = y self._z = z - self.matrix = Matrix().scale(x, y, z) + ox, oy, oz = self._origin + cdef Matrix matrix + matrix = Matrix().translate(ox, oy, oz) + matrix = matrix.multiply(Matrix().scale(x, y, z)) + matrix = matrix.multiply(Matrix().translate(-ox, -oy, -oz)) + self.matrix = matrix property scale: '''Property for getting/setting the scale. @@ -770,6 +787,24 @@ cdef class Scale(Transform): def __set__(self, c): self.set_scale(c[0], c[1], c[2]) + property origin: + '''Origin of the scale. + + .. versionadded:: 1.9.0 + + The format of the origin can be either (x, y) or (x, y, z). + ''' + def __get__(self): + return self._origin + def __set__(self, origin): + if len(origin) == 3: + self._origin = tuple(origin) + elif len(origin) == 2: + self._origin = (origin[0], origin[1], 0.) + else: + raise Exception('invalid number of components in origin') + self.set_scale(self._x, self._y, self._z) + cdef class Translate(Transform): '''Instruction to create a translation of the model view coordinate space. diff --git a/kivy/graphics/vertex_instructions.pyx b/kivy/graphics/vertex_instructions.pyx index c014f2b844..3b1a24624e 100644 --- a/kivy/graphics/vertex_instructions.pyx +++ b/kivy/graphics/vertex_instructions.pyx @@ -876,13 +876,17 @@ cdef class BorderImage(Rectangle): tb[2] = b2 / th * tch tb[3] = b3 / tw * tcw - + cdef float sb0, sb1, sb2, sb3 + sb0 = min((b0/th) * h, b0) + sb1 = min((b1/tw) * w, b1) + sb2 = min((b2/th) * h, b2) + sb3 = min((b3/tw) * w, b3) # horizontal and vertical sections cdef float hs[4] cdef float vs[4] hs[0] = x; vs[0] = y - hs[1] = x + b3; vs[1] = y + b0 - hs[2] = x + w - b1; vs[2] = y + h - b2 + hs[1] = x + sb3; vs[1] = y + sb0 + hs[2] = x + w - sb1; vs[2] = y + h - sb2 hs[3] = x + w; vs[3] = y + h cdef float ths[4] diff --git a/kivy/input/providers/hidinput.py b/kivy/input/providers/hidinput.py index ccff3544d6..021797a325 100644 --- a/kivy/input/providers/hidinput.py +++ b/kivy/input/providers/hidinput.py @@ -239,9 +239,9 @@ def __str__(self): 0x58: ('f12', ), 0x54: ('Alt+SysRq', ), 0x46: ('Screenlock', ), - 0x67: ('up', ), + 0x67: ('up', ), 0x6c: ('down', ), - 0x69: ('left', ), + 0x69: ('left', ), 0x6a: ('right', ), 0x6e: ('insert', ), 0x6f: ('delete', ), diff --git a/kivy/lang.py b/kivy/lang.py index fcf01619da..65c3b15f23 100755 --- a/kivy/lang.py +++ b/kivy/lang.py @@ -290,7 +290,7 @@ class and template definitions to the :class:`~kivy.factory.Factory` for later More precisely, the kivy language parser detects all substrings of the form `X.a.b` where `X` is `self` or `root` or `app` or a known id, and `a` and `b` are properties: it then adds the appropriate dependencies to cause the -the constraint to be reevaluated whenever something changes. For example, +the constraint to be reevaluated whenever something changes. For example, this works exactly as expected:: : @@ -309,7 +309,7 @@ class and template definitions to the :class:`~kivy.factory.Factory` for later : alpha: self.a.b[self.c.d] - beta: self.alpha.e.f + beta: self.alpha.e.f Graphical Instructions diff --git a/kivy/loader.py b/kivy/loader.py index 4a412bc79d..907f22b333 100644 --- a/kivy/loader.py +++ b/kivy/loader.py @@ -40,7 +40,7 @@ from kivy.clock import Clock from kivy.cache import Cache from kivy.core.image import ImageLoader, Image -from kivy.compat import PY2 +from kivy.compat import PY2, string_types from collections import deque from time import sleep @@ -164,7 +164,7 @@ def _get_loading_image(self): return self._loading_image def _set_loading_image(self, image): - if isinstance(image, basestring): + if isinstance(image, string_types): self._loading_image = ImageLoader.load(filename=image) else: self._loading_image = image @@ -187,7 +187,7 @@ def _get_error_image(self): return self._error_image def _set_error_image(self, image): - if isinstance(image, basestring): + if isinstance(image, string_types): self._error_image = ImageLoader.load(filename=image) else: self._error_image = image diff --git a/kivy/storage/dictstore.py b/kivy/storage/dictstore.py index c617eac84b..c0d9d4ec5c 100644 --- a/kivy/storage/dictstore.py +++ b/kivy/storage/dictstore.py @@ -37,7 +37,7 @@ def store_load(self): return if not exists(self.filename): return - with open(self.filename, 'r') as fd: + with open(self.filename, 'rb') as fd: data = fd.read() if data: self._data = pickle.loads(data) @@ -48,7 +48,7 @@ def store_sync(self): if not self._is_changed: return - with open(self.filename, 'w') as fd: + with open(self.filename, 'wb') as fd: pickle.dump(self._data, fd) self._is_changed = False diff --git a/kivy/tests/test_fonts.py b/kivy/tests/test_fonts.py index 26939f1ce1..ddb2379a5b 100644 --- a/kivy/tests/test_fonts.py +++ b/kivy/tests/test_fonts.py @@ -23,5 +23,8 @@ def test_unicode_name(self): def tearDown(self): import os if os.path.exists(self.font_name): - os.unlink(self.font_name) + try: + os.unlink(self.font_name) + except: + pass diff --git a/kivy/tests/test_graphics.py b/kivy/tests/test_graphics.py index 4882298d10..335d8b01a3 100644 --- a/kivy/tests/test_graphics.py +++ b/kivy/tests/test_graphics.py @@ -5,7 +5,6 @@ Testing the simple vertex instructions ''' -import unittest from kivy.tests.common import GraphicUnitTest @@ -89,7 +88,7 @@ def test_point_add(self): r(wid) -class FBOInstructionTestCase(unittest.TestCase): +class FBOInstructionTestCase(GraphicUnitTest): def test_fbo_pixels(self): from kivy.graphics import Fbo, ClearColor, ClearBuffers, Ellipse @@ -105,8 +104,3 @@ def test_fbo_pixels(self): import pygame surface = pygame.image.fromstring(data, (512, 512), 'RGBA', True) pygame.image.save(surface, "results.png") - - def tearDown(self): - import os - if os.path.exists('results.png'): - os.unlink('results.png') diff --git a/kivy/tests/test_utils.py b/kivy/tests/test_utils.py index f474ea24e6..d6cacdf41d 100644 --- a/kivy/tests/test_utils.py +++ b/kivy/tests/test_utils.py @@ -58,17 +58,17 @@ def test_SafeList_iterate(self): # deprecated sl = SafeList(['1', 2, 3.]) self.assertTrue(isinstance(sl, list)) it = sl.iterate() - self.assertEqual(it.next(), '1') - self.assertEqual(it.next(), 2) - self.assertEqual(it.next(), 3.) + self.assertEqual(next(it), '1') + self.assertEqual(next(it), 2) + self.assertEqual(next(it), 3.) def test_SafeList_iterate_reverse(self): # deprecated sl = SafeList(['1', 2, 3.]) self.assertTrue(isinstance(sl, list)) it = sl.iterate(reverse=True) - self.assertEqual(it.next(), 3.) - self.assertEqual(it.next(), 2) - self.assertEqual(it.next(), '1') + self.assertEqual(next(it), 3.) + self.assertEqual(next(it), 2) + self.assertEqual(next(it), '1') def test_SafeList_clear(self): sl = SafeList(['1', 2, 3.]) diff --git a/kivy/tools/report.py b/kivy/tools/report.py index a7392505a7..6d5f6779c1 100644 --- a/kivy/tools/report.py +++ b/kivy/tools/report.py @@ -186,9 +186,10 @@ def testimport(libname): # Prints the entire Output print('\n'.join(report_dict['Global'] + report_dict['OpenGL'] + - report_dict['Core'] + report_dict['Libraries'] + - report_dict['Configuration'] + report_dict['InputAvailablity'] + - report_dict['Environ'] + report_dict['Options'])) + report_dict['Core'] + report_dict['Libraries'] + + report_dict['Configuration'] + + report_dict['InputAvailablity'] + + report_dict['Environ'] + report_dict['Options'])) print() print() @@ -213,4 +214,4 @@ def testimport(libname): # On windows system, the console leave directly after the end # of the dump. That's not cool if we want get report url -input('Enter any key to leave.') \ No newline at end of file +input('Enter any key to leave.') diff --git a/kivy/uix/behaviors.py b/kivy/uix/behaviors.py index b429472718..8c0345acae 100644 --- a/kivy/uix/behaviors.py +++ b/kivy/uix/behaviors.py @@ -93,7 +93,7 @@ class ButtonBehavior(object): '''This determines if the widget fires a `on_release` event if the touch_up is outside the widget. - ..versionadded:: 1.9.0 + ..versionadded:: 1.9.0 :attr:`always_release` is a :class:`~kivy.properties.BooleanProperty`, defaults to `True`. @@ -148,9 +148,9 @@ def on_touch_up(self, touch): assert(self in touch.ud) touch.ungrab(self) self.last_touch = touch - + if (not self.always_release - and not self.collide_point(*touch.pos)): + and not self.collide_point(*touch.pos)): self.state = 'normal' return diff --git a/kivy/uix/colorpicker.py b/kivy/uix/colorpicker.py index 1703e1cef8..5e2d66ccac 100644 --- a/kivy/uix/colorpicker.py +++ b/kivy/uix/colorpicker.py @@ -11,8 +11,9 @@ The ColorPicker widget allows a user to select a color from a chromatic -wheel where pinch and zoom can be used to change the selected color. Sliders -and TextInputs are also provided for entering the RGBA/HSV/HEX values directly. +wheel where pinch and zoom can be used to change the wheel's saturation. +Sliders and TextInputs are also provided for entering the RGBA/HSV/HEX values +directly. Usage:: @@ -428,7 +429,7 @@ def _trigger_update_clr(self, mode, clr_idx, text): def _update_clr(self, dt): mode, clr_idx, text = self._upd_clr_list try: - text = max(0, min(254, float(text))) + text = min(255, max(0, float(text))) if mode == 'rgb': self.color[clr_idx] = float(text) / 255. else: diff --git a/kivy/uix/slider.py b/kivy/uix/slider.py index 13817490c7..c29b80c7a2 100644 --- a/kivy/uix/slider.py +++ b/kivy/uix/slider.py @@ -23,7 +23,7 @@ from kivy.uix.widget import Widget from kivy.properties import (NumericProperty, AliasProperty, OptionProperty, ReferenceListProperty, BoundedNumericProperty) -from kivy.metrics import sp +from kivy.metrics import sp class Slider(Widget): @@ -55,9 +55,9 @@ class Slider(Widget): and interaction. It prevents the cursor from going out of the bounds of the slider bounding box. - By default, padding is sp(16). The range of the slider is reduced from padding - \*2 on the screen. It allows drawing the default cursor of sp(32) width without - having the cursor go out of the widget. + By default, padding is sp(16). The range of the slider is reduced from + padding \*2 on the screen. It allows drawing the default cursor of sp(32) + width without having the cursor go out of the widget. :attr:`padding` is a :class:`~kivy.properties.NumericProperty` and defaults to sp(16).''' diff --git a/setup.py b/setup.py index 0a9a0b3168..80d0cbebbd 100644 --- a/setup.py +++ b/setup.py @@ -119,7 +119,7 @@ def pkgconfig(*packages, **kw): # on python-for-android and kivy-ios, cython usage is external cython_unsupported_append = ''' - + Please note that the following versions of Cython are not supported at all: {} '''.format(', '.join(map(str, CYTHON_UNSUPPORTED))) @@ -127,11 +127,11 @@ def pkgconfig(*packages, **kw): cython_min = '''\ This version of Cython is not compatible with Kivy. Please upgrade to at least version {0}, preferably the newest supported version {1}. - + If your platform provides a Cython package, make sure you have upgraded to the newest version. If the newest version available is still too low, please remove it and install the newest supported Cython via pip: - + pip install -I Cython=={1}{2}\ '''.format(MIN_CYTHON_STRING, MAX_CYTHON_STRING, cython_unsupported_append if CYTHON_UNSUPPORTED else '') @@ -142,11 +142,11 @@ def pkgconfig(*packages, **kw): you do have issues, please downgrade to a supported version. It is best to use the newest supported version, {1}, but the minimum supported version is {0}. - + If your platform provides a Cython package, check if you can downgrade to a supported version. Otherwise, uninstall the platform package and install Cython via pip: - + pip install -I Cython=={1}{2}\ '''.format(MIN_CYTHON_STRING, MAX_CYTHON_STRING, cython_unsupported_append if CYTHON_UNSUPPORTED else '') @@ -155,11 +155,11 @@ def pkgconfig(*packages, **kw): This version of Cython suffers from known bugs and is unsupported. Please install the newest supported version, {1}, if possible, but the minimum supported version is {0}. - + If your platform provides a Cython package, check if you can install a supported version. Otherwise, uninstall the platform package and install Cython via pip: - + pip install -I Cython=={1}{2}\ '''.format(MIN_CYTHON_STRING, MAX_CYTHON_STRING, cython_unsupported_append) @@ -238,6 +238,8 @@ def build_extensions(self): config_py += '{0} = {1}\n'.format(opt, value) debug = bool(self.debug) print(' * debug = {0}'.format(debug)) + config_h += \ + '#if __USE_GLEW && defined(_WIN32)\n# define GLEW_BUILD\n#endif' config_pxi += 'DEF DEBUG = {0}\n'.format(debug) config_py += 'DEBUG = {0}\n'.format(debug) @@ -532,13 +534,18 @@ def determine_sdl2(): # no pkgconfig info, or we want to use a specific sdl2 path, so perform # manual configuration flags['libraries'] = ['SDL2', 'SDL2_ttf', 'SDL2_image', 'SDL2_mixer'] - flags['include_dirs'] = (sdl2_path.split(':') if sdl2_path else - ['/usr/local/include/SDL2', '/usr/include/SDL2']) + split_chr = ';' if platform == 'win32' else ':' + sdl2_paths = sdl2_path.split(split_chr) if sdl2_path else [] + + flags['include_dirs'] = ( + sdl2_paths if sdl2_paths else + ['/usr/local/include/SDL2', '/usr/include/SDL2']) flags['extra_link_args'] = [] flags['extra_compile_args'] = [] - flags['extra_link_args'] += (['-L' + sdl2_path] if sdl2_path else - ['-L/usr/local/lib/']) + flags['extra_link_args'] += ( + ['-L' + p for p in sdl2_paths] if sdl2_paths else + ['-L/usr/local/lib/']) # ensure headers for all the SDL2 and sub libraries are available libs_to_check = ['SDL', 'SDL_mixer', 'SDL_ttf', 'SDL_image']