Kivy-examples 2.3.1.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/main.py +77 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/monkey.obj +7966 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/objloader.py +147 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/simple.glsl +47 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/RST_Editor/editor.kv +72 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/RST_Editor/main.py +64 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/compass.kv +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/main.py +77 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/needle.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/rose.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/main.py +80 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/shadow32.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/takepicture.kv +40 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/animation/animate.py +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_suite.py +152 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_suite_data/testkvdir.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_build.py +24 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_config.py +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_kv.py +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_kv_in_template1.py +27 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/template1/test.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/test.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/testkvfile.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/asyncio_advanced.py +90 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/asyncio_basic.py +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/trio_advanced.py +93 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/trio_basic.py +58 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12908_sweet_trip_mm_clap_hi.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12909_sweet_trip_mm_clap_lo.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12910_sweet_trip_mm_clap_mid.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12911_sweet_trip_mm_hat_cl.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12913_sweet_trip_mm_kick_hi.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12914_sweet_trip_mm_kick_lo.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12915_sweet_trip_mm_kick_mid.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12916_sweet_trip_mm_kwik_mod_01.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12917_sweet_trip_mm_kwik_mod_02.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12918_sweet_trip_mm_kwik_mod_03.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12919_sweet_trip_mm_kwik_mod_04.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12920_sweet_trip_mm_kwik_mod_05.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12921_sweet_trip_mm_kwik_mod_06.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12922_sweet_trip_mm_kwik_mod_07.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12923_sweet_trip_mm_metal_clave.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12925_sweet_trip_mm_sweep_x.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12926_sweet_trip_mm_sweep_y.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12927_sweet_trip_mm_sweep_z.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/audio.kv +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/main.py +81 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/pitch.py +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/camera/main.py +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/bezier.py +105 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/canvas_stress.py +72 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/circle.py +84 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/fbo_canvas.py +91 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/kiwi.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/lines.py +296 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/lines_extended.py +183 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mesh.py +57 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mesh_manipulation.py +101 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mtexture1.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mtexture2.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/multitexture.py +110 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/repeat_texture.py +65 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/rotation.py +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/rounded_rectangle.py +153 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/scale.py +37 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/stencil_canvas.py +85 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/tesselate.py +146 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/texture.py +143 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/texture_example_image.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/1.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/2.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/3.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/root.kv +32 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/main.py +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/cover/cover_image.py +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/cover/cover_video.py +31 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/camera_puzzle.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/AnchorLayoutContainer.kv +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/BoxLayoutContainer.kv +14 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/ButtonContainer.kv +27 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/CheckBoxContainer.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/FileChooserContainer.kv +19 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/FloatLayoutContainer.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/GridLayoutContainer.kv +20 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/LabelContainer.kv +62 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/MediaContainer.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/PlaygroundContainer.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/PopupContainer.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/ProgressBarContainer.kv +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/RestContainer.kv +5 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/ScatterContainer.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/SelectorsContainer.kv +10 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/StackLayoutContainer.kv +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/TextContainer.kv +20 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/kivycatalog.kv +144 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/main.py +192 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/gesturedatabase.kv +117 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/gesturedatabase.py +180 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/helpers.py +30 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/historymanager.kv +164 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/historymanager.py +276 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/main.py +144 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/multistroke.kv +101 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/settings.kv +110 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/settings.py +97 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/Bubbles.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/Ill1.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/Wall.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/faust_github.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/main.py +73 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/pictures.kv +57 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/shadow32.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/shadereditor/main.py +147 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/shadereditor/shadereditor.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/README.txt +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/background.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/faust_github.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/README +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/bug.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/chevron-left.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/chevron-right.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/accordions.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/bubbles.kv +33 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/buttons.kv +26 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/carousel.kv +51 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/checkboxes.kv +33 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/codeinput.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/dropdown.kv +40 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/filechoosers.kv +24 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/popups.kv +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/progressbar.kv +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/rstdocument.kv +24 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/scatter.kv +14 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/screenmanager.kv +46 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/sliders.kv +55 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/spinner.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/splitter.kv +13 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/switches.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/tabbedpanel + layouts.kv +69 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/textinputs.kv +48 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/togglebutton.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/main.py +243 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/showcase.kv +100 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/README.txt +12 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/icon.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/main.py +170 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/particle.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/touchtracer.kv +29 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/frameworks/twisted/echo_client_app.py +82 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/frameworks/twisted/echo_server_app.py +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/frameworks/twisted/twistd_app.py +66 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/gestures/gesture_board.py +95 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/gestures/my_gestures.py +90 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/designwithkv/controller.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/designwithkv/main.py +29 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/1_skeleton.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/2_print_touch.py +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/3_draw_ellipse.py +22 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/4_draw_line.py +26 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/5_random_colors.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/6_button.py +38 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/quickstart/main.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/button.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/layout.kv +6 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/main.py +19 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/test.kv +5 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/keyboard/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/keyboard/main.py +226 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/keyboard/numeric.json +38 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kinect/README.txt +13 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kinect/kinectviewer.py +283 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_button.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_camera.kv +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_fbo.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_layout.kv +23 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_logo.kv +36 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_scatter.kv +6 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_stencil.kv +27 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_video.kv +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/builder_template.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/id_in_kv/id_in_kv.py +20 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/id_in_kv/test.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/kv_and_py/kv_and_py.py +34 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/kv_and_py/test.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/kivy.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/kvrun.py +38 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/clipboard.py +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/custom_titlebar.py +56 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/imagesave.py +14 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/joystick.py +83 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/multiple_dropfile.py +51 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/on_textedit_event.py +104 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/opacitywindow.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/shapecollisions.py +397 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/shapedwindow.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/two_panes.py +47 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/urlrequest.py +128 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/settings/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/settings/main.py +122 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/plasma.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/plasma.py +86 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/rotated.kv +91 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/rotated.py +102 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/shadertree.kv +29 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/shadertree.py +193 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/tex3.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/benchmark.py +19 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/cloud.svg +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/main-smaa.py +155 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/main.py +50 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/music.svg +68 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/rotated.svg +23 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/ship.svg +181 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/sun.svg +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/tiger.svg +813 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/text/pango_demo.py +296 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/notes/final/data/icon.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/notes/final/main.py +163 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/notes/final/note.kv +154 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/main.py +82 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/pong.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step1/main.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step1/pong.kv +2 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step2/main.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step2/pong.kv +21 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step3/main.py +26 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step3/pong.kv +31 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step4/main.py +48 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step4/pong.kv +34 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step5/main.py +75 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step5/pong.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/accordion_1.py +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/actionbar.py +32 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/asyncimage.py +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/boxlayout_poshint.py +54 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/bubble_test.py +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/camera.py +33 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/carousel_buttons.py +50 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/cityCC0.mpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/cityCC0.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/codeinput.py +225 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/codeinputtest.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/colorpicker.py +234 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/colorusage.py +62 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/compound_selection.py +83 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/customcollide.py +82 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/effectwidget.py +193 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/effectwidget2.py +47 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/effectwidget3_advanced.py +62 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/fbowidget.py +111 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/focus_behavior.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/image_mipmap.py +31 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/keyboardlistener.py +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_mipmap.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_sizing.py +193 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_text_size.py +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_with_markup.py +21 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/lang_dynamic_classes.py +18 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/pagelayout.py +64 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/popup_with_kv.py +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/basic_data.py +124 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/infinite_scrolling.py +143 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/key_viewclass.py +149 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/messenger.py +196 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/pull_to_refresh.py +95 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/rv_animate_items.py +109 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/rstexample.py +128 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scatter.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scatter.py +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/screenmanager.py +106 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scrollview.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scrollview.py +40 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/bird.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/button_white.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/button_white_animated.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/cube.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/info.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/info.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/simple_cv_joint_animated.gif +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/main.kv +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/main.py +150 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/uix/__init__.py +7 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/uix/custom_button.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/settings.py +93 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/shorten_text.py +80 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/spinner.py +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/splitter.py +74 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/tabbed_panel_showcase.py +316 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/tabbedpanel.py +50 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/textalign.kv +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/textalign.py +48 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/textinput.py +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/unicode_textinput.py +244 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/videoplayer.py +26 -0
- Kivy_examples-2.3.1.dev0.dist-info/AUTHORS +66 -0
- Kivy_examples-2.3.1.dev0.dist-info/LICENSE +21 -0
- Kivy_examples-2.3.1.dev0.dist-info/METADATA +382 -0
- Kivy_examples-2.3.1.dev0.dist-info/RECORD +624 -0
- Kivy_examples-2.3.1.dev0.dist-info/WHEEL +5 -0
- Kivy_examples-2.3.1.dev0.dist-info/dependency_links.txt +1 -0
- Kivy_examples-2.3.1.dev0.dist-info/top_level.txt +1 -0
- kivy/__init__.py +519 -0
- kivy/_version.py +18 -0
- kivy/animation.py +831 -0
- kivy/app.py +1213 -0
- kivy/atlas.py +456 -0
- kivy/base.py +617 -0
- kivy/cache.py +262 -0
- kivy/clock.py +1172 -0
- kivy/compat.py +82 -0
- kivy/config.py +1004 -0
- kivy/context.py +102 -0
- kivy/core/__init__.py +247 -0
- kivy/core/audio/__init__.py +223 -0
- kivy/core/audio/audio_android.py +104 -0
- kivy/core/audio/audio_avplayer.py +82 -0
- kivy/core/audio/audio_ffpyplayer.py +185 -0
- kivy/core/audio/audio_gstplayer.py +101 -0
- kivy/core/audio/audio_pygame.py +127 -0
- kivy/core/camera/__init__.py +151 -0
- kivy/core/camera/camera_android.py +206 -0
- kivy/core/camera/camera_gi.py +170 -0
- kivy/core/camera/camera_opencv.py +163 -0
- kivy/core/camera/camera_picamera.py +96 -0
- kivy/core/clipboard/__init__.py +157 -0
- kivy/core/clipboard/_clipboard_ext.py +36 -0
- kivy/core/clipboard/clipboard_android.py +91 -0
- kivy/core/clipboard/clipboard_dbusklipper.py +41 -0
- kivy/core/clipboard/clipboard_dummy.py +26 -0
- kivy/core/clipboard/clipboard_gtk3.py +47 -0
- kivy/core/clipboard/clipboard_nspaste.py +44 -0
- kivy/core/clipboard/clipboard_pygame.py +67 -0
- kivy/core/clipboard/clipboard_sdl2.py +36 -0
- kivy/core/clipboard/clipboard_winctypes.py +107 -0
- kivy/core/clipboard/clipboard_xclip.py +29 -0
- kivy/core/clipboard/clipboard_xsel.py +26 -0
- kivy/core/gl/__init__.py +90 -0
- kivy/core/image/__init__.py +996 -0
- kivy/core/image/img_dds.py +40 -0
- kivy/core/image/img_ffpyplayer.py +87 -0
- kivy/core/image/img_pil.py +123 -0
- kivy/core/image/img_pygame.py +119 -0
- kivy/core/image/img_sdl2.py +66 -0
- kivy/core/image/img_tex.py +58 -0
- kivy/core/spelling/__init__.py +135 -0
- kivy/core/spelling/spelling_enchant.py +50 -0
- kivy/core/spelling/spelling_osxappkit.py +64 -0
- kivy/core/text/__init__.py +1090 -0
- kivy/core/text/markup.py +893 -0
- kivy/core/text/text_pango.py +145 -0
- kivy/core/text/text_pil.py +84 -0
- kivy/core/text/text_pygame.py +117 -0
- kivy/core/text/text_sdl2.py +50 -0
- kivy/core/video/__init__.py +219 -0
- kivy/core/video/video_ffmpeg.py +106 -0
- kivy/core/video/video_ffpyplayer.py +449 -0
- kivy/core/video/video_gstplayer.py +140 -0
- kivy/core/video/video_null.py +12 -0
- kivy/core/window/__init__.py +2515 -0
- kivy/core/window/window_egl_rpi.py +86 -0
- kivy/core/window/window_pygame.py +441 -0
- kivy/core/window/window_sdl2.py +999 -0
- kivy/deps/__init__.py +6 -0
- kivy/effects/__init__.py +23 -0
- kivy/effects/dampedscroll.py +114 -0
- kivy/effects/kinetic.py +193 -0
- kivy/effects/opacityscroll.py +27 -0
- kivy/effects/scroll.py +126 -0
- kivy/event.py +12 -0
- kivy/eventmanager/__init__.py +185 -0
- kivy/extras/__init__.py +0 -0
- kivy/extras/highlight.py +52 -0
- kivy/factory.py +190 -0
- kivy/factory_registers.py +201 -0
- kivy/garden/__init__.py +186 -0
- kivy/geometry.py +121 -0
- kivy/gesture.py +424 -0
- kivy/graphics/__init__.py +126 -0
- kivy/graphics/cgl_backend/__init__.py +0 -0
- kivy/input/__init__.py +39 -0
- kivy/input/factory.py +35 -0
- kivy/input/motionevent.py +587 -0
- kivy/input/postproc/__init__.py +27 -0
- kivy/input/postproc/calibration.py +200 -0
- kivy/input/postproc/dejitter.py +74 -0
- kivy/input/postproc/doubletap.py +101 -0
- kivy/input/postproc/ignorelist.py +47 -0
- kivy/input/postproc/retaintouch.py +93 -0
- kivy/input/postproc/tripletap.py +106 -0
- kivy/input/provider.py +40 -0
- kivy/input/providers/__init__.py +68 -0
- kivy/input/providers/androidjoystick.py +117 -0
- kivy/input/providers/hidinput.py +778 -0
- kivy/input/providers/leapfinger.py +113 -0
- kivy/input/providers/linuxwacom.py +396 -0
- kivy/input/providers/mactouch.py +220 -0
- kivy/input/providers/mouse.py +424 -0
- kivy/input/providers/mtdev.py +380 -0
- kivy/input/providers/probesysfs.py +254 -0
- kivy/input/providers/tuio.py +326 -0
- kivy/input/providers/wm_common.py +162 -0
- kivy/input/providers/wm_pen.py +121 -0
- kivy/input/providers/wm_touch.py +157 -0
- kivy/input/recorder.py +335 -0
- kivy/input/shape.py +27 -0
- kivy/interactive.py +335 -0
- kivy/lang/__init__.py +883 -0
- kivy/lang/builder.py +1004 -0
- kivy/lang/parser.py +822 -0
- kivy/lib/__init__.py +21 -0
- kivy/lib/ddsfile.py +419 -0
- kivy/lib/gstplayer/__init__.py +27 -0
- kivy/lib/mtdev.py +254 -0
- kivy/lib/vidcore_lite/__init__.py +0 -0
- kivy/loader.py +579 -0
- kivy/logger.py +646 -0
- kivy/metrics.py +421 -0
- kivy/modules/__init__.py +300 -0
- kivy/modules/_webdebugger.py +200 -0
- kivy/modules/console.py +1059 -0
- kivy/modules/cursor.py +75 -0
- kivy/modules/inspector.py +755 -0
- kivy/modules/joycursor.py +299 -0
- kivy/modules/keybinding.py +64 -0
- kivy/modules/monitor.py +90 -0
- kivy/modules/recorder.py +94 -0
- kivy/modules/screen.py +183 -0
- kivy/modules/showborder.py +33 -0
- kivy/modules/touchring.py +97 -0
- kivy/modules/webdebugger.py +30 -0
- kivy/multistroke.py +1477 -0
- kivy/network/__init__.py +7 -0
- kivy/network/urlrequest.py +794 -0
- kivy/parser.py +154 -0
- kivy/resources.py +102 -0
- kivy/storage/__init__.py +405 -0
- kivy/storage/dictstore.py +98 -0
- kivy/storage/jsonstore.py +92 -0
- kivy/storage/redisstore.py +103 -0
- kivy/support.py +267 -0
- kivy/tests/__init__.py +11 -0
- kivy/tests/async_common.py +568 -0
- kivy/tests/common.py +524 -0
- kivy/tests/conftest.py +33 -0
- kivy/tests/fixtures.py +169 -0
- kivy/tests/perf_test_textinput.py +195 -0
- kivy/tests/pyinstaller/simple_widget/main.py +12 -0
- kivy/tests/pyinstaller/simple_widget/project/__init__.py +0 -0
- kivy/tests/pyinstaller/simple_widget/project/widget.py +12 -0
- kivy/tests/pyinstaller/test_pyinstaller.py +115 -0
- kivy/tests/pyinstaller/video_widget/main.py +6 -0
- kivy/tests/pyinstaller/video_widget/project/__init__.py +38 -0
- kivy/tests/test_animations.py +415 -0
- kivy/tests/test_app.py +216 -0
- kivy/tests/test_audio.py +69 -0
- kivy/tests/test_benchmark.py +292 -0
- kivy/tests/test_clipboard.py +48 -0
- kivy/tests/test_clock.py +292 -0
- kivy/tests/test_compat.py +6 -0
- kivy/tests/test_config.py +35 -0
- kivy/tests/test_coverage.py +83 -0
- kivy/tests/test_doc_gallery.py +38 -0
- kivy/tests/test_environ_cli.py +50 -0
- kivy/tests/test_fbo_py2py3.py +74 -0
- kivy/tests/test_filechooser.py +11 -0
- kivy/tests/test_filechooser_unicode.py +82 -0
- kivy/tests/test_fonts.py +42 -0
- kivy/tests/test_garden.py +23 -0
- kivy/tests/test_graphics.py +1149 -0
- kivy/tests/test_graphics_svg.py +84 -0
- kivy/tests/test_image.py +74 -0
- kivy/tests/test_imageloader.py +485 -0
- kivy/tests/test_invalid_lang.py +42 -0
- kivy/tests/test_issues/test_6315.py +55 -0
- kivy/tests/test_issues/test_issue_1084.py +47 -0
- kivy/tests/test_issues/test_issue_1091.py +19 -0
- kivy/tests/test_issues/test_issue_599.py +21 -0
- kivy/tests/test_issues/test_issue_609.py +19 -0
- kivy/tests/test_issues/test_issue_6909.py +28 -0
- kivy/tests/test_issues/test_issue_883.py +12 -0
- kivy/tests/test_kivy_init.py +30 -0
- kivy/tests/test_knspace.py +247 -0
- kivy/tests/test_lang.py +431 -0
- kivy/tests/test_lang_complex.py +87 -0
- kivy/tests/test_lang_pre_process_and_post_process.py +394 -0
- kivy/tests/test_logger.py +516 -0
- kivy/tests/test_metrics.py +30 -0
- kivy/tests/test_module_inspector.py +382 -0
- kivy/tests/test_motion_event.py +44 -0
- kivy/tests/test_mouse_hover_event.py +249 -0
- kivy/tests/test_mouse_multitouchsim.py +554 -0
- kivy/tests/test_multistroke.py +389 -0
- kivy/tests/test_properties.py +1332 -0
- kivy/tests/test_resources.py +79 -0
- kivy/tests/test_rst_replace.py +63 -0
- kivy/tests/test_screen.py +38 -0
- kivy/tests/test_storage.py +135 -0
- kivy/tests/test_uix_actionbar.py +363 -0
- kivy/tests/test_uix_anchorlayout.py +79 -0
- kivy/tests/test_uix_asyncimage.py +133 -0
- kivy/tests/test_uix_boxlayout.py +94 -0
- kivy/tests/test_uix_bubble.py +425 -0
- kivy/tests/test_uix_carousel.py +93 -0
- kivy/tests/test_uix_colorpicker.py +77 -0
- kivy/tests/test_uix_dropdown.py +91 -0
- kivy/tests/test_uix_gridlayout.py +244 -0
- kivy/tests/test_uix_layout.py +16 -0
- kivy/tests/test_uix_modal.py +101 -0
- kivy/tests/test_uix_recyclegridlayout.py +383 -0
- kivy/tests/test_uix_relativelayout.py +30 -0
- kivy/tests/test_uix_scrollview.py +358 -0
- kivy/tests/test_uix_settings.py +33 -0
- kivy/tests/test_uix_slider.py +156 -0
- kivy/tests/test_uix_stacklayout.py +120 -0
- kivy/tests/test_uix_textinput.py +577 -0
- kivy/tests/test_uix_translate_coordinates.py +72 -0
- kivy/tests/test_uix_videoplayer.py +112 -0
- kivy/tests/test_uix_widget.py +137 -0
- kivy/tests/test_urlrequest/test_urlrequest_requests.py +378 -0
- kivy/tests/test_urlrequest/test_urlrequest_urllib.py +155 -0
- kivy/tests/test_utils.py +237 -0
- kivy/tests/test_vector.py +256 -0
- kivy/tests/test_video.py +25 -0
- kivy/tests/test_weakmethod.py +44 -0
- kivy/tests/test_widget.py +127 -0
- kivy/tests/test_widget_walk.py +70 -0
- kivy/tests/test_window_base.py +60 -0
- kivy/tests/test_window_info.py +29 -0
- kivy/tests/visual_test_label.py +291 -0
- kivy/tools/__init__.py +44 -0
- kivy/tools/benchmark.py +286 -0
- kivy/tools/changelog_parser.py +120 -0
- kivy/tools/coverage.py +135 -0
- kivy/tools/gallery.py +323 -0
- kivy/tools/generate-icons.py +117 -0
- kivy/tools/gles_compat/subset_gles.py +125 -0
- kivy/tools/highlight/__init__.py +9 -0
- kivy/tools/kviewer.py +80 -0
- kivy/tools/packaging/__init__.py +12 -0
- kivy/tools/packaging/cython_cfg.py +82 -0
- kivy/tools/packaging/factory.py +105 -0
- kivy/tools/packaging/pyinstaller_hooks/__init__.py +381 -0
- kivy/tools/packaging/pyinstaller_hooks/__main__.py +29 -0
- kivy/tools/packaging/pyinstaller_hooks/hook-kivy.py +9 -0
- kivy/tools/packaging/pyinstaller_hooks/pyi_rth_kivy.py +17 -0
- kivy/tools/pep8checker/pep8.py +2316 -0
- kivy/tools/pep8checker/pep8kivy.py +109 -0
- kivy/tools/report.py +223 -0
- kivy/tools/stub-gl-debug.py +201 -0
- kivy/tools/texturecompress.py +233 -0
- kivy/uix/__init__.py +56 -0
- kivy/uix/accordion.py +484 -0
- kivy/uix/actionbar.py +934 -0
- kivy/uix/anchorlayout.py +122 -0
- kivy/uix/behaviors/__init__.py +95 -0
- kivy/uix/behaviors/button.py +212 -0
- kivy/uix/behaviors/codenavigation.py +167 -0
- kivy/uix/behaviors/compoundselection.py +688 -0
- kivy/uix/behaviors/cover.py +160 -0
- kivy/uix/behaviors/drag.py +234 -0
- kivy/uix/behaviors/emacs.py +140 -0
- kivy/uix/behaviors/focus.py +595 -0
- kivy/uix/behaviors/knspace.py +590 -0
- kivy/uix/behaviors/togglebutton.py +156 -0
- kivy/uix/behaviors/touchripple.py +318 -0
- kivy/uix/boxlayout.py +331 -0
- kivy/uix/bubble.py +576 -0
- kivy/uix/button.py +137 -0
- kivy/uix/camera.py +118 -0
- kivy/uix/carousel.py +695 -0
- kivy/uix/checkbox.py +197 -0
- kivy/uix/codeinput.py +238 -0
- kivy/uix/colorpicker.py +486 -0
- kivy/uix/dropdown.py +391 -0
- kivy/uix/effectwidget.py +772 -0
- kivy/uix/filechooser.py +1134 -0
- kivy/uix/floatlayout.py +148 -0
- kivy/uix/gesturesurface.py +625 -0
- kivy/uix/gridlayout.py +629 -0
- kivy/uix/image.py +528 -0
- kivy/uix/label.py +1200 -0
- kivy/uix/layout.py +322 -0
- kivy/uix/modalview.py +339 -0
- kivy/uix/pagelayout.py +233 -0
- kivy/uix/popup.py +266 -0
- kivy/uix/progressbar.py +95 -0
- kivy/uix/recycleboxlayout.py +183 -0
- kivy/uix/recyclegridlayout.py +255 -0
- kivy/uix/recyclelayout.py +446 -0
- kivy/uix/recycleview/__init__.py +624 -0
- kivy/uix/recycleview/datamodel.py +194 -0
- kivy/uix/recycleview/layout.py +253 -0
- kivy/uix/recycleview/views.py +423 -0
- kivy/uix/relativelayout.py +324 -0
- kivy/uix/rst.py +1492 -0
- kivy/uix/sandbox.py +198 -0
- kivy/uix/scatter.py +645 -0
- kivy/uix/scatterlayout.py +93 -0
- kivy/uix/screenmanager.py +1275 -0
- kivy/uix/scrollview.py +1288 -0
- kivy/uix/settings.py +1343 -0
- kivy/uix/slider.py +421 -0
- kivy/uix/spinner.py +221 -0
- kivy/uix/splitter.py +430 -0
- kivy/uix/stacklayout.py +331 -0
- kivy/uix/stencilview.py +40 -0
- kivy/uix/switch.py +122 -0
- kivy/uix/tabbedpanel.py +880 -0
- kivy/uix/textinput.py +4049 -0
- kivy/uix/togglebutton.py +37 -0
- kivy/uix/treeview.py +665 -0
- kivy/uix/video.py +302 -0
- kivy/uix/videoplayer.py +697 -0
- kivy/uix/vkeyboard.py +879 -0
- kivy/uix/widget.py +1629 -0
- kivy/utils.py +550 -0
- kivy/vector.py +412 -0
- kivy/weakmethod.py +72 -0
kivy/clock.py
ADDED
|
@@ -0,0 +1,1172 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Clock object
|
|
3
|
+
============
|
|
4
|
+
|
|
5
|
+
The :class:`Clock` object allows you to schedule a function call in the
|
|
6
|
+
future; once or repeatedly at specified intervals. You can get the time
|
|
7
|
+
elapsed between the scheduling and the calling of the callback via the
|
|
8
|
+
`dt` argument::
|
|
9
|
+
|
|
10
|
+
# dt means delta-time
|
|
11
|
+
def my_callback(dt):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
# call my_callback every 0.5 seconds
|
|
15
|
+
Clock.schedule_interval(my_callback, 0.5)
|
|
16
|
+
|
|
17
|
+
# call my_callback in 5 seconds
|
|
18
|
+
Clock.schedule_once(my_callback, 5)
|
|
19
|
+
|
|
20
|
+
# call my_callback as soon as possible (usually next frame.)
|
|
21
|
+
Clock.schedule_once(my_callback)
|
|
22
|
+
|
|
23
|
+
.. note::
|
|
24
|
+
|
|
25
|
+
If the callback returns False, the schedule will be canceled and won't
|
|
26
|
+
repeat.
|
|
27
|
+
|
|
28
|
+
If you want to schedule a function to call with default arguments, you can use
|
|
29
|
+
the `functools.partial
|
|
30
|
+
<http://docs.python.org/library/functools.html#functools.partial>`_ python
|
|
31
|
+
module::
|
|
32
|
+
|
|
33
|
+
from functools import partial
|
|
34
|
+
|
|
35
|
+
def my_callback(value, key, *largs):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
Clock.schedule_interval(partial(my_callback, 'my value', 'my key'), 0.5)
|
|
39
|
+
|
|
40
|
+
Conversely, if you want to schedule a function that doesn't accept the dt
|
|
41
|
+
argument, you can use a `lambda
|
|
42
|
+
<http://docs.python.org/2/reference/expressions.html#lambda>`_ expression
|
|
43
|
+
to write a short function that does accept dt. For Example::
|
|
44
|
+
|
|
45
|
+
def no_args_func():
|
|
46
|
+
print("I accept no arguments, so don't schedule me in the clock")
|
|
47
|
+
|
|
48
|
+
Clock.schedule_once(lambda dt: no_args_func(), 0.5)
|
|
49
|
+
|
|
50
|
+
.. note::
|
|
51
|
+
|
|
52
|
+
You cannot unschedule an anonymous function unless you keep a
|
|
53
|
+
reference to it. It's better to add \\*args to your function
|
|
54
|
+
definition so that it can be called with an arbitrary number of
|
|
55
|
+
parameters.
|
|
56
|
+
|
|
57
|
+
.. important::
|
|
58
|
+
|
|
59
|
+
The class method callback is weak-referenced: you are responsible for
|
|
60
|
+
keeping a reference to your original object/callback. If you don't keep a
|
|
61
|
+
reference, the ClockBase will never execute your callback. For
|
|
62
|
+
example::
|
|
63
|
+
|
|
64
|
+
class Foo(object):
|
|
65
|
+
def start(self):
|
|
66
|
+
Clock.schedule_interval(self.callback, 0.5)
|
|
67
|
+
|
|
68
|
+
def callback(self, dt):
|
|
69
|
+
print('In callback')
|
|
70
|
+
|
|
71
|
+
# A Foo object is created and the method start is called.
|
|
72
|
+
# Because no reference is kept to the instance returned from Foo(),
|
|
73
|
+
# the object will be collected by the Python Garbage Collector and
|
|
74
|
+
# your callback will be never called.
|
|
75
|
+
Foo().start()
|
|
76
|
+
|
|
77
|
+
# So you should do the following and keep a reference to the instance
|
|
78
|
+
# of foo until you don't need it anymore!
|
|
79
|
+
foo = Foo()
|
|
80
|
+
foo.start()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
.. _schedule-before-frame:
|
|
84
|
+
|
|
85
|
+
Schedule before frame
|
|
86
|
+
---------------------
|
|
87
|
+
|
|
88
|
+
.. versionadded:: 1.0.5
|
|
89
|
+
|
|
90
|
+
Sometimes you need to schedule a callback BEFORE the next frame. Starting
|
|
91
|
+
from 1.0.5, you can use a timeout of -1::
|
|
92
|
+
|
|
93
|
+
Clock.schedule_once(my_callback, 0) # call after the next frame
|
|
94
|
+
Clock.schedule_once(my_callback, -1) # call before the next frame
|
|
95
|
+
|
|
96
|
+
The Clock will execute all the callbacks with a timeout of -1 before the
|
|
97
|
+
next frame even if you add a new callback with -1 from a running
|
|
98
|
+
callback. However, :class:`Clock` has an iteration limit for these
|
|
99
|
+
callbacks: it defaults to 10.
|
|
100
|
+
|
|
101
|
+
If you schedule a callback that schedules a callback that schedules a ... etc
|
|
102
|
+
more than 10 times, it will leave the loop and send a warning to the console,
|
|
103
|
+
then continue after the next frame. This is implemented to prevent bugs from
|
|
104
|
+
hanging or crashing the application.
|
|
105
|
+
|
|
106
|
+
If you need to increase the limit, set the :attr:`max_iteration` property::
|
|
107
|
+
|
|
108
|
+
from kivy.clock import Clock
|
|
109
|
+
Clock.max_iteration = 20
|
|
110
|
+
|
|
111
|
+
.. _triggered-events:
|
|
112
|
+
|
|
113
|
+
Triggered Events
|
|
114
|
+
----------------
|
|
115
|
+
|
|
116
|
+
.. versionadded:: 1.0.5
|
|
117
|
+
|
|
118
|
+
:meth:`CyClockBase.create_trigger` is an advanced method way to defer a
|
|
119
|
+
callback. It functions exactly like :meth:`CyClockBase.schedule_once` and
|
|
120
|
+
:meth:`CyClockBase.schedule_interval` except that it doesn't immediately
|
|
121
|
+
schedule the callback. Instead, one schedules the callback using the
|
|
122
|
+
:class:`ClockEvent` returned by it. This ensures that you can call the event
|
|
123
|
+
multiple times but it won't be scheduled more than once. This is not the case
|
|
124
|
+
with :meth:`CyClockBase.schedule_once`::
|
|
125
|
+
|
|
126
|
+
# will run the callback twice before the next frame
|
|
127
|
+
Clock.schedule_once(my_callback)
|
|
128
|
+
Clock.schedule_once(my_callback)
|
|
129
|
+
|
|
130
|
+
# will run the callback once before the next frame
|
|
131
|
+
event = Clock.create_trigger(my_callback)
|
|
132
|
+
event()
|
|
133
|
+
event()
|
|
134
|
+
|
|
135
|
+
# will also run the callback only once before the next frame
|
|
136
|
+
event = Clock.schedule_once(my_callback) # now it's already scheduled
|
|
137
|
+
event() # won't be scheduled again
|
|
138
|
+
event()
|
|
139
|
+
|
|
140
|
+
In addition, it is more convenient to create and bind to
|
|
141
|
+
the triggered event than using :meth:`CyClockBase.schedule_once` in a
|
|
142
|
+
function::
|
|
143
|
+
|
|
144
|
+
from kivy.clock import Clock
|
|
145
|
+
from kivy.uix.widget import Widget
|
|
146
|
+
|
|
147
|
+
class Sample(Widget):
|
|
148
|
+
def __init__(self, **kwargs):
|
|
149
|
+
self._trigger = Clock.create_trigger(self.cb)
|
|
150
|
+
super(Sample, self).__init__(**kwargs)
|
|
151
|
+
self.bind(x=self._trigger, y=self._trigger)
|
|
152
|
+
|
|
153
|
+
def cb(self, *largs):
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
Even if x and y changes within one frame, the callback is only run once.
|
|
157
|
+
|
|
158
|
+
Unscheduling
|
|
159
|
+
-------------
|
|
160
|
+
|
|
161
|
+
An event scheduled with :meth:`CyClockBase.schedule_once`,
|
|
162
|
+
:meth:`CyClockBase.schedule_interval`, or with
|
|
163
|
+
:meth:`CyClockBase.create_trigger` and then triggered can be unscheduled in
|
|
164
|
+
multiple ways. E.g::
|
|
165
|
+
|
|
166
|
+
def my_callback(dt):
|
|
167
|
+
pass
|
|
168
|
+
|
|
169
|
+
# call my_callback every 0.5 seconds
|
|
170
|
+
event = Clock.schedule_interval(my_callback, 0.5)
|
|
171
|
+
|
|
172
|
+
# call my_callback in 5 seconds
|
|
173
|
+
event2 = Clock.schedule_once(my_callback, 5)
|
|
174
|
+
|
|
175
|
+
event_trig = Clock.create_trigger(my_callback, 5)
|
|
176
|
+
event_trig()
|
|
177
|
+
|
|
178
|
+
# unschedule using cancel
|
|
179
|
+
event.cancel()
|
|
180
|
+
|
|
181
|
+
# unschedule using Clock.unschedule
|
|
182
|
+
Clock.unschedule(event2)
|
|
183
|
+
|
|
184
|
+
# unschedule using Clock.unschedule with the callback
|
|
185
|
+
# NOT RECOMMENDED
|
|
186
|
+
Clock.unschedule(my_callback)
|
|
187
|
+
|
|
188
|
+
The best way to unschedule a callback is with :meth:`ClockEvent.cancel`.
|
|
189
|
+
:meth:`CyClockBase.unschedule` is mainly an alias for that for that function.
|
|
190
|
+
However, if the original callback itself is passed to
|
|
191
|
+
:meth:`CyClockBase.unschedule`, it'll unschedule all instances of that
|
|
192
|
+
callback (provided ``all`` is True, the default, otherwise only the first match
|
|
193
|
+
is removed).
|
|
194
|
+
|
|
195
|
+
Calling :meth:`CyClockBase.unschedule` on the original callback is highly
|
|
196
|
+
discouraged because it's significantly slower than when using the event.
|
|
197
|
+
|
|
198
|
+
Clock Lifecycle
|
|
199
|
+
---------------
|
|
200
|
+
|
|
201
|
+
Kivy's clock has a lifecycle. By default, scheduling a callback after the Clock
|
|
202
|
+
has ended will not raise an error, even though the callback may never be
|
|
203
|
+
called. That's because most callbacks are like services, e.g. responding to a
|
|
204
|
+
user button press - if the app is running the callbacks need to service the app
|
|
205
|
+
and respond to the input, but once the app has stopped or is stopping, we can
|
|
206
|
+
safely not process these events.
|
|
207
|
+
|
|
208
|
+
Other events always need to be processed. E.g. another thread may request a
|
|
209
|
+
callback in kivy's thread and then process some result. If the event is not
|
|
210
|
+
processed in Kivy's thread because the app stopped, the second thread may
|
|
211
|
+
block forever hanging the application as it exits.
|
|
212
|
+
|
|
213
|
+
Consequently, we provide a API
|
|
214
|
+
(:meth:`CyClockBase.create_lifecycle_aware_trigger`) for scheduling callbacks
|
|
215
|
+
that raise a :class:`ClockNotRunningError` if the clock has stopped. If the
|
|
216
|
+
scheduling succeeded it guarantees that one of its callbacks will be called.
|
|
217
|
+
I.e. the new :meth:`CyClockBase.create_lifecycle_aware_trigger` accepts an
|
|
218
|
+
additional ``clock_ended_callback`` parameter. Normally, ``callback`` will be
|
|
219
|
+
called when the event is processed. But, if the clock is stopped before it can
|
|
220
|
+
be processed, if the application exited normally (and the app was started) and
|
|
221
|
+
the event wasn't canceled, and the callbacks are not garbage collected, then
|
|
222
|
+
``clock_ended_callback`` will be called instead when the clock is stopped.
|
|
223
|
+
|
|
224
|
+
That is, given these conditions, if :class:`ClockNotRunningError` was not
|
|
225
|
+
raised when the event was scheduled, then one of these callbacks will be
|
|
226
|
+
called - either ``callback`` if the event executed normally, or
|
|
227
|
+
``clock_ended_callback`` if the clock is stopped while the event is scheduled.
|
|
228
|
+
|
|
229
|
+
By default, events can be scheduled before the clock is started because it is
|
|
230
|
+
assumed the clock will eventually be started when the app starts. I.e.
|
|
231
|
+
calling :meth:`CyClockBase.create_lifecycle_aware_trigger` before the clock
|
|
232
|
+
and application starts will succeed. But if the app never actually starts, then
|
|
233
|
+
neither of the callbacks may be executed.
|
|
234
|
+
|
|
235
|
+
.. versionadded:: 2.0.0
|
|
236
|
+
The lifecycle was added in 2.0.0
|
|
237
|
+
|
|
238
|
+
Exception Handling
|
|
239
|
+
------------------
|
|
240
|
+
|
|
241
|
+
Kivy provides a exception handling manager,
|
|
242
|
+
:attr:`~kivy.base.ExceptionManager`, to handle its internal exceptions
|
|
243
|
+
including exceptions raised by clock callbacks, without crashing the
|
|
244
|
+
application. By default when an exception is raised, the app will crash.
|
|
245
|
+
But, if a handler is registered with the exception manager and the handler
|
|
246
|
+
handles the exception, the app will not crash and will continue as normal.::
|
|
247
|
+
|
|
248
|
+
from kivy.base import ExceptionHandler, ExceptionManager
|
|
249
|
+
class MyHandler(ExceptionHandler):
|
|
250
|
+
def handle_exception(self, inst):
|
|
251
|
+
if isinstance(inst, ValueError):
|
|
252
|
+
Logger.exception('ValueError caught by MyHandler')
|
|
253
|
+
return ExceptionManager.PASS
|
|
254
|
+
return ExceptionManager.RAISE
|
|
255
|
+
|
|
256
|
+
ExceptionManager.add_handler(MyHandler())
|
|
257
|
+
|
|
258
|
+
Then, all ValueError exceptions will be logged to the console and ignored.
|
|
259
|
+
Similarly, if a scheduled clock callback raises a ValueError, other clock
|
|
260
|
+
events will still be processed normally.
|
|
261
|
+
|
|
262
|
+
If an event's callback raises an exception, before the exception handler is
|
|
263
|
+
executed, the callback is immediately canceled.
|
|
264
|
+
|
|
265
|
+
It still is possible for the app to be corrupted if kivy itself is the source
|
|
266
|
+
of the exception. I.e. even with a handler that ignores exceptions and doesn't
|
|
267
|
+
crash, the app may be in a corrupted state if the error originates from within
|
|
268
|
+
Kivy itself. However, the exception handler can help protect the app from
|
|
269
|
+
crashing and can help protect against user callbacks crashing the app.
|
|
270
|
+
|
|
271
|
+
.. versionchanged:: 2.0.0
|
|
272
|
+
Prior to Kivy 2.0.0, an exception raised in a event's callback would
|
|
273
|
+
cause the clock to crash and subsequent events may or may not be executed.
|
|
274
|
+
Even if the exception was handled by an
|
|
275
|
+
:class:`~kivy.base.ExceptionHandler`, there was no guarantee that some
|
|
276
|
+
scheduled events would not be skipped.
|
|
277
|
+
|
|
278
|
+
From 2.0.0 onward, if a event's exception is handled by an
|
|
279
|
+
:class:`~kivy.base.ExceptionHandler`, other events will be shielded from
|
|
280
|
+
the exception and will execute normally.
|
|
281
|
+
|
|
282
|
+
Scheduling from ``__del__``
|
|
283
|
+
---------------------------
|
|
284
|
+
|
|
285
|
+
It is not safe to schedule Clock events from a object's ``__del__`` or
|
|
286
|
+
``__dealloc__`` method. If you must schedule a Clock call from this method, use
|
|
287
|
+
:meth:`CyClockBase.schedule_del_safe` or
|
|
288
|
+
:meth:`CyClockBase.schedule_lifecycle_aware_del_safe` instead.
|
|
289
|
+
|
|
290
|
+
Threading and Callback Order
|
|
291
|
+
-----------------------------
|
|
292
|
+
|
|
293
|
+
Beginning with 1.10.0, all the events scheduled for the same frame, e.g.
|
|
294
|
+
all the events scheduled in the same frame with a ``timeout`` of ``0``,
|
|
295
|
+
well be executed in the order they were scheduled.
|
|
296
|
+
|
|
297
|
+
Also, all the scheduling and canceling methods are fully thread safe and
|
|
298
|
+
can be safely used from external threads.
|
|
299
|
+
|
|
300
|
+
As a consequence, calling :meth:`CyClockBase.unschedule` with the original
|
|
301
|
+
callback is now significantly slower and highly discouraged. Instead, the
|
|
302
|
+
returned events should be used to cancel. As a tradeoff, all the other methods
|
|
303
|
+
are now significantly faster than before.
|
|
304
|
+
|
|
305
|
+
Advanced Clock Details
|
|
306
|
+
-----------------------
|
|
307
|
+
|
|
308
|
+
The following section goes into the internal kivy clock details as well
|
|
309
|
+
as the various clock options. It is meant only for advanced users.
|
|
310
|
+
|
|
311
|
+
Fundamentally, the Kivy clock attempts to execute any scheduled callback
|
|
312
|
+
rhythmically as determined by the specified fps (frame per second, see
|
|
313
|
+
``maxfps`` in :mod:`~kivy.config`). That is, ideally, given e.g. a desired fps
|
|
314
|
+
of 30, the clock will execute the callbacks at intervals of 1 / 30 seconds, or
|
|
315
|
+
every 33.33 ms. All the callbacks in a frame are given the same timestamp,
|
|
316
|
+
i.e. the ``dt`` passed to the callback are all the same and it's the difference
|
|
317
|
+
in time between the start of this and the previous frame.
|
|
318
|
+
|
|
319
|
+
Because of inherent indeterminism, the frames do not actually occur exactly
|
|
320
|
+
at intervals of the fps and ``dt`` may be under or over the desired fps.
|
|
321
|
+
Also, once the timeout is "close enough" to the desired timeout, as determined
|
|
322
|
+
internally, Kivy will execute the callback in the current frame even when the
|
|
323
|
+
"actual time" has not elapsed the ``timeout`` amount.
|
|
324
|
+
|
|
325
|
+
Kivy offers now, since ``1.10.0``, multiple clocks with different behaviors.
|
|
326
|
+
|
|
327
|
+
Default Clock
|
|
328
|
+
^^^^^^^^^^^^^^
|
|
329
|
+
|
|
330
|
+
The default clock (``default``) behaves as described above. When a callback
|
|
331
|
+
with a timeout of zero or non-zero is scheduled, they are executed at the frame
|
|
332
|
+
that is near the timeout, which is a function of the fps. So a timeout of zero
|
|
333
|
+
would still result in a delay of one frame or about 1 / fps, typically a bit
|
|
334
|
+
less but sometimes more depending on the CPU usage of the other events
|
|
335
|
+
scheduled for that frame.
|
|
336
|
+
|
|
337
|
+
In a test using a fps of 30, a callback with a timeout of 0, 0.001, and 0.05,
|
|
338
|
+
resulted in a mean callback delay of 0.02487, 0.02488, and 0.05011 seconds,
|
|
339
|
+
respectively. When tested with a fps of 600 the delay for 0.05 was similar,
|
|
340
|
+
except the standard deviation was reduced resulting in overall better accuracy.
|
|
341
|
+
|
|
342
|
+
Interruptible Clock
|
|
343
|
+
^^^^^^^^^^^^^^^^^^^^
|
|
344
|
+
|
|
345
|
+
The default clock suffers from the quantization problem, as frames occur only
|
|
346
|
+
on intervals and any scheduled timeouts will not be able to occur during an
|
|
347
|
+
interval. For example, with the timeout of 0.05, while the mean was 0.05011,
|
|
348
|
+
its values ranged between 0.02548 - 0.07348 and a standard deviation of 0.002.
|
|
349
|
+
Also, there's the minimum timeout of about 0.02487.
|
|
350
|
+
|
|
351
|
+
The interruptible clock (``interrupt``) will execute timeouts even during a
|
|
352
|
+
frame. So a timeout of zero will execute as quickly as possible and similarly
|
|
353
|
+
a non-zero timeout will be executed even during the interval.
|
|
354
|
+
|
|
355
|
+
This clock, and all the clocks described after this have an option,
|
|
356
|
+
:attr:`ClockBaseInterruptBehavior.interupt_next_only`. When True, any of the
|
|
357
|
+
behavior new behavior will only apply to the callbacks with a timeout of
|
|
358
|
+
zero. Non-zero timeouts will behave like in the default clock. E.g. for this
|
|
359
|
+
clock when True, only zero timeouts will execute during the interval.
|
|
360
|
+
|
|
361
|
+
In a test using a fps of 30, a callback with a timeout of 0, 0.001, and 0.05,
|
|
362
|
+
resulted in a mean callback delay of 0.00013, 0.00013, and 0.04120 seconds,
|
|
363
|
+
respectively when :attr:`ClockBaseInterruptBehavior.interupt_next_only` was
|
|
364
|
+
False. Also, compared to the default clock the standard deviation was reduced.
|
|
365
|
+
When :attr:`ClockBaseInterruptBehavior.interupt_next_only` was True, the values
|
|
366
|
+
were 0.00010, 0.02414, and 0.05034, respectively.
|
|
367
|
+
|
|
368
|
+
Free Clock
|
|
369
|
+
^^^^^^^^^^^
|
|
370
|
+
|
|
371
|
+
The interruptible clock may not be ideal for all cases because all the events
|
|
372
|
+
are executed during the intervals and events are not executed anymore
|
|
373
|
+
rhythmically as multiples of the fps. For example, there may not be any benefit
|
|
374
|
+
for the graphics to update in a sub-interval, so the additional accuracy
|
|
375
|
+
wastes CPU.
|
|
376
|
+
|
|
377
|
+
The Free clock (``free_all``) solves this by having ``Clock.xxx_free`` versions
|
|
378
|
+
of all the Clock scheduling methods. By free, we mean the event is free from
|
|
379
|
+
the fps because it's not fps limited. E.g.
|
|
380
|
+
:meth:`CyClockBaseFree.create_trigger_free` corresponds to
|
|
381
|
+
:meth:`CyClockBase.create_trigger`. Only when an event scheduled using the
|
|
382
|
+
``Clock.xxx_free`` methods is present will the clock interrupt and execute
|
|
383
|
+
the events during the interval. So, if no ``free`` event is present the clock
|
|
384
|
+
behaves like the ``default`` clock, otherwise it behaves like the ``interrupt``
|
|
385
|
+
clock.
|
|
386
|
+
|
|
387
|
+
In a test using a fps of 30, a callback with a timeout of 0s, 0.001s, and
|
|
388
|
+
0.05s, resulted in a mean callback delay of 0.00012s, 0.00017s, and 0.04121s
|
|
389
|
+
seconds, respectively when it was a free event and 0.02403s, 0.02405s, and
|
|
390
|
+
0.04829s, respectively when it wasn't.
|
|
391
|
+
|
|
392
|
+
Free Only Clock
|
|
393
|
+
^^^^^^^^^^^^^^^^^
|
|
394
|
+
|
|
395
|
+
The Free clock executes all events when a free event was scheduled. This
|
|
396
|
+
results in normal events also being execute in the middle of the interval
|
|
397
|
+
when a free event is scheduled. For example, above, when a free event was
|
|
398
|
+
absent, a normal event with a 0.001s timeout was delayed for 0.02405s. However,
|
|
399
|
+
if a free event happened to be also scheduled, the normal event was only
|
|
400
|
+
delayed 0.00014s, which may be undesirable.
|
|
401
|
+
|
|
402
|
+
The Free only clock (``free_only``) solves it by only executing free events
|
|
403
|
+
during the interval and normal events are always executed like with the
|
|
404
|
+
default clock. For example, in the presence of a free event, a normal event
|
|
405
|
+
with a timeout of 0.001s still had a delay of 0.02406. So this clock,
|
|
406
|
+
treats free and normal events independently, with normal events always being
|
|
407
|
+
fps limited, but never the free events.
|
|
408
|
+
|
|
409
|
+
Summary
|
|
410
|
+
^^^^^^^^
|
|
411
|
+
|
|
412
|
+
The kivy clock type to use can be set with the ``kivy_clock`` option the
|
|
413
|
+
:mod:`~kivy.config`. If ``KIVY_CLOCK`` is present in the environment it
|
|
414
|
+
overwrites the config selection. Its possible values are as follows:
|
|
415
|
+
|
|
416
|
+
* When ``kivy_clock`` is ``default``, the normal clock, :class:`ClockBase`,
|
|
417
|
+
which limits callbacks to the maxfps quantization - is used.
|
|
418
|
+
* When ``kivy_clock`` is ``interrupt``, a interruptible clock,
|
|
419
|
+
:class:`ClockBaseInterrupt`, which doesn't limit any callbacks to the
|
|
420
|
+
maxfps - is used. Callbacks will be executed at any time.
|
|
421
|
+
* When ``kivy_clock`` is ``free_all``, a interruptible clock,
|
|
422
|
+
:class:`ClockBaseFreeInterruptAll`, which doesn't limit any callbacks to the
|
|
423
|
+
maxfps in the presence of free events, but in their absence it limits events
|
|
424
|
+
to the fps quantization interval - is used.
|
|
425
|
+
* When ``kivy_clock`` is ``free_only``, a interruptible clock,
|
|
426
|
+
:class:`ClockBaseFreeInterruptAll`, which treats free and normal events
|
|
427
|
+
independently; normal events are fps limited while free events are not - is
|
|
428
|
+
used.
|
|
429
|
+
|
|
430
|
+
Async clock support
|
|
431
|
+
-------------------
|
|
432
|
+
|
|
433
|
+
.. versionadded:: 2.0.0
|
|
434
|
+
|
|
435
|
+
Experimental async support has been added in 2.0.0. The Clock now has a
|
|
436
|
+
:meth:`ClockBaseBehavior.async_tick` and :meth:`ClockBaseBehavior.async_idle`
|
|
437
|
+
coroutine method which is used by the kivy EventLoop when the kivy EventLoop is
|
|
438
|
+
executed in a asynchronous manner. When used, the kivy clock does not
|
|
439
|
+
block while idling.
|
|
440
|
+
|
|
441
|
+
The async library to use is selected with the `KIVY_EVENTLOOP` environmental
|
|
442
|
+
variable or by calling :meth:`~kivy.clock.ClockBaseBehavior.init_async_lib`
|
|
443
|
+
directly. The library can be one of `"asyncio"` when the standard library
|
|
444
|
+
`asyncio` should be used, or `"trio"` if the trio library
|
|
445
|
+
should be used. If not set it defaults to `"asyncio"`.
|
|
446
|
+
|
|
447
|
+
See :mod:`~kivy.app` for example usage.
|
|
448
|
+
'''
|
|
449
|
+
|
|
450
|
+
__all__ = (
|
|
451
|
+
'Clock', 'ClockNotRunningError', 'ClockEvent', 'FreeClockEvent',
|
|
452
|
+
'CyClockBase', 'CyClockBaseFree', 'triggered',
|
|
453
|
+
'ClockBaseBehavior', 'ClockBaseInterruptBehavior',
|
|
454
|
+
'ClockBaseInterruptFreeBehavior', 'ClockBase', 'ClockBaseInterrupt',
|
|
455
|
+
'ClockBaseFreeInterruptAll', 'ClockBaseFreeInterruptOnly', 'mainthread')
|
|
456
|
+
|
|
457
|
+
from sys import platform
|
|
458
|
+
from os import environ
|
|
459
|
+
from functools import wraps, partial
|
|
460
|
+
from kivy.context import register_context
|
|
461
|
+
from kivy.config import Config
|
|
462
|
+
from kivy.logger import Logger
|
|
463
|
+
from kivy.compat import clock as _default_time
|
|
464
|
+
import time
|
|
465
|
+
try:
|
|
466
|
+
from kivy._clock import CyClockBase, ClockEvent, FreeClockEvent, \
|
|
467
|
+
CyClockBaseFree, ClockNotRunningError
|
|
468
|
+
except ImportError:
|
|
469
|
+
Logger.error(
|
|
470
|
+
'Clock: Unable to import kivy._clock. Have you perhaps forgotten to '
|
|
471
|
+
'compile kivy? Kivy contains Cython code which needs to be compiled. '
|
|
472
|
+
'A missing kivy._clock often indicates the Cython code has not been '
|
|
473
|
+
'compiled. Please follow the installation instructions and make sure '
|
|
474
|
+
'to compile Kivy')
|
|
475
|
+
raise
|
|
476
|
+
|
|
477
|
+
from threading import Event as ThreadingEvent
|
|
478
|
+
|
|
479
|
+
# some reading: http://gameprogrammingpatterns.com/game-loop.html
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def _get_sleep_obj():
|
|
483
|
+
pass
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
try:
|
|
487
|
+
import ctypes
|
|
488
|
+
if platform in ('win32', 'cygwin'):
|
|
489
|
+
# Win32 Sleep function is only 10-millisecond resolution, so
|
|
490
|
+
# instead use a waitable timer object, which has up to
|
|
491
|
+
# 100-nanosecond resolution (hardware and implementation
|
|
492
|
+
# dependent, of course).
|
|
493
|
+
|
|
494
|
+
_kernel32 = ctypes.windll.kernel32
|
|
495
|
+
|
|
496
|
+
def _get_sleep_obj(): # noqa: F811
|
|
497
|
+
return _kernel32.CreateWaitableTimerA(None, True, None)
|
|
498
|
+
|
|
499
|
+
def _usleep(microseconds, obj=None):
|
|
500
|
+
delay = ctypes.c_longlong(int(-microseconds * 10))
|
|
501
|
+
_kernel32.SetWaitableTimer(
|
|
502
|
+
obj, ctypes.byref(delay), 0,
|
|
503
|
+
ctypes.c_void_p(), ctypes.c_void_p(), False)
|
|
504
|
+
_kernel32.WaitForSingleObject(obj, 0xffffffff)
|
|
505
|
+
else:
|
|
506
|
+
if platform == 'darwin':
|
|
507
|
+
_libc = ctypes.CDLL('libc.dylib')
|
|
508
|
+
else:
|
|
509
|
+
from ctypes.util import find_library
|
|
510
|
+
_libc = ctypes.CDLL(find_library('c'), use_errno=True)
|
|
511
|
+
|
|
512
|
+
def _libc_clock_gettime_wrapper():
|
|
513
|
+
from os import strerror
|
|
514
|
+
|
|
515
|
+
class struct_tv(ctypes.Structure):
|
|
516
|
+
_fields_ = [('tv_sec', ctypes.c_long),
|
|
517
|
+
('tv_usec', ctypes.c_long)]
|
|
518
|
+
|
|
519
|
+
_clock_gettime = _libc.clock_gettime
|
|
520
|
+
_clock_gettime.argtypes = [ctypes.c_long,
|
|
521
|
+
ctypes.POINTER(struct_tv)]
|
|
522
|
+
|
|
523
|
+
if 'linux' in platform:
|
|
524
|
+
_clockid = 4 # CLOCK_MONOTONIC_RAW (Linux specific)
|
|
525
|
+
elif 'freebsd' in platform:
|
|
526
|
+
# clockid constants from sys/time.h
|
|
527
|
+
# _clockid = 4 # CLOCK_MONOTONIC (FreeBSD specific)
|
|
528
|
+
# 11: CLOCK_MONOTONIC_PRECISE (FreeBSD known OK for 10.2)
|
|
529
|
+
_clockid = 11
|
|
530
|
+
# _clockid = 12
|
|
531
|
+
# 12: CLOCK_MONOTONIC_FAST (FreeBSD specific)
|
|
532
|
+
Logger.debug('clock.py: {{{:s}}} clock ID {:d}'.format(
|
|
533
|
+
platform, _clockid))
|
|
534
|
+
elif 'openbsd' in platform:
|
|
535
|
+
_clockid = 3 # CLOCK_MONOTONIC
|
|
536
|
+
else:
|
|
537
|
+
_clockid = 1 # CLOCK_MONOTONIC
|
|
538
|
+
|
|
539
|
+
tv = struct_tv()
|
|
540
|
+
|
|
541
|
+
def _time():
|
|
542
|
+
if _clock_gettime(ctypes.c_long(_clockid),
|
|
543
|
+
ctypes.pointer(tv)) != 0:
|
|
544
|
+
_ernno = ctypes.get_errno()
|
|
545
|
+
raise OSError(_ernno, strerror(_ernno))
|
|
546
|
+
return tv.tv_sec + (tv.tv_usec * 0.000000001)
|
|
547
|
+
|
|
548
|
+
return _time
|
|
549
|
+
|
|
550
|
+
_default_time = _libc_clock_gettime_wrapper() # noqa: F811
|
|
551
|
+
|
|
552
|
+
_libc.usleep.argtypes = [ctypes.c_ulong]
|
|
553
|
+
_libc_usleep = _libc.usleep
|
|
554
|
+
|
|
555
|
+
def _usleep(microseconds, obj=None):
|
|
556
|
+
_libc_usleep(int(microseconds))
|
|
557
|
+
|
|
558
|
+
except (OSError, ImportError, AttributeError):
|
|
559
|
+
# ImportError: ctypes is not available on python-for-android.
|
|
560
|
+
# AttributeError: ctypes is now available on python-for-android, but
|
|
561
|
+
# "undefined symbol: clock_gettime". CF #3797
|
|
562
|
+
# OSError: if the libc cannot be read (like with buildbot: invalid ELF
|
|
563
|
+
# header)
|
|
564
|
+
|
|
565
|
+
def _usleep(microseconds, obj=None):
|
|
566
|
+
time.sleep(microseconds / 1000000.)
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
class ClockBaseBehavior(object):
|
|
570
|
+
'''The base of the kivy clock.
|
|
571
|
+
|
|
572
|
+
:parameters:
|
|
573
|
+
|
|
574
|
+
`async_lib`: string
|
|
575
|
+
The async library to use when the clock is run asynchronously.
|
|
576
|
+
Can be one of, `"asyncio"` when the standard library asyncio
|
|
577
|
+
should be used, or `"trio"` if the trio library should be used.
|
|
578
|
+
|
|
579
|
+
It defaults to `'asyncio'` or the value in the environmental
|
|
580
|
+
variable `KIVY_EVENTLOOP` if set. :meth:`init_async_lib` can also
|
|
581
|
+
be called directly to set the library.
|
|
582
|
+
'''
|
|
583
|
+
|
|
584
|
+
_dt = 0.0001
|
|
585
|
+
_last_fps_tick = None
|
|
586
|
+
_start_tick = 0
|
|
587
|
+
_fps = 0
|
|
588
|
+
_rfps = 0
|
|
589
|
+
_fps_counter = 0
|
|
590
|
+
_rfps_counter = 0
|
|
591
|
+
_frames = 0
|
|
592
|
+
_frames_displayed = 0
|
|
593
|
+
_events_duration = 0
|
|
594
|
+
'''The measured time that it takes to process all the events etc, excepting
|
|
595
|
+
any sleep or waiting time. It is the average and is updated every 5
|
|
596
|
+
seconds.
|
|
597
|
+
'''
|
|
598
|
+
|
|
599
|
+
_duration_count = 0
|
|
600
|
+
_sleep_time = 0
|
|
601
|
+
_duration_ts0 = 0
|
|
602
|
+
|
|
603
|
+
MIN_SLEEP = 0.005
|
|
604
|
+
'''The minimum time to sleep. If the remaining time is less than this,
|
|
605
|
+
the event loop will continue.
|
|
606
|
+
'''
|
|
607
|
+
SLEEP_UNDERSHOOT = MIN_SLEEP - 0.001
|
|
608
|
+
|
|
609
|
+
_async_lib = None
|
|
610
|
+
|
|
611
|
+
_async_wait_for = None
|
|
612
|
+
|
|
613
|
+
def __init__(self, async_lib='asyncio', **kwargs):
|
|
614
|
+
self.init_async_lib(async_lib)
|
|
615
|
+
super(ClockBaseBehavior, self).__init__(**kwargs)
|
|
616
|
+
self._duration_ts0 = self._start_tick = self._last_tick = self.time()
|
|
617
|
+
self._max_fps = float(Config.getint('graphics', 'maxfps'))
|
|
618
|
+
|
|
619
|
+
def init_async_lib(self, lib):
|
|
620
|
+
"""Manually sets the async library to use internally, when running in
|
|
621
|
+
a asynchronous manner.
|
|
622
|
+
|
|
623
|
+
This can be called anytime before the kivy event loop has started,
|
|
624
|
+
but not once the kivy App is running.
|
|
625
|
+
|
|
626
|
+
:parameters:
|
|
627
|
+
|
|
628
|
+
`lib`: string
|
|
629
|
+
The async library to use when the clock is run asynchronously.
|
|
630
|
+
Can be one of, `"asyncio"` when the standard library asyncio
|
|
631
|
+
should be used, or `"trio"` if the trio library should be used.
|
|
632
|
+
"""
|
|
633
|
+
if lib == 'trio':
|
|
634
|
+
import trio
|
|
635
|
+
self._async_lib = trio
|
|
636
|
+
|
|
637
|
+
async def wait_for(coro, t):
|
|
638
|
+
with trio.move_on_after(t):
|
|
639
|
+
await coro
|
|
640
|
+
self._async_wait_for = wait_for
|
|
641
|
+
elif lib == 'asyncio':
|
|
642
|
+
import asyncio
|
|
643
|
+
self._async_lib = asyncio
|
|
644
|
+
self._async_wait_for = asyncio.wait_for
|
|
645
|
+
else:
|
|
646
|
+
raise ValueError('async library {} not recognized'.format(lib))
|
|
647
|
+
|
|
648
|
+
@property
|
|
649
|
+
def frametime(self):
|
|
650
|
+
'''Time spent between the last frame and the current frame
|
|
651
|
+
(in seconds).
|
|
652
|
+
|
|
653
|
+
.. versionadded:: 1.8.0
|
|
654
|
+
'''
|
|
655
|
+
return self._dt
|
|
656
|
+
|
|
657
|
+
@property
|
|
658
|
+
def frames(self):
|
|
659
|
+
'''Number of internal frames (not necessarily drawn) from the start of
|
|
660
|
+
the clock.
|
|
661
|
+
|
|
662
|
+
.. versionadded:: 1.8.0
|
|
663
|
+
'''
|
|
664
|
+
return self._frames
|
|
665
|
+
|
|
666
|
+
@property
|
|
667
|
+
def frames_displayed(self):
|
|
668
|
+
'''Number of displayed frames from the start of the clock.
|
|
669
|
+
'''
|
|
670
|
+
return self._frames_displayed
|
|
671
|
+
|
|
672
|
+
def usleep(self, microseconds):
|
|
673
|
+
'''Sleeps for the number of microseconds.
|
|
674
|
+
'''
|
|
675
|
+
pass
|
|
676
|
+
|
|
677
|
+
def idle(self):
|
|
678
|
+
'''(internal) waits here until the next frame.
|
|
679
|
+
'''
|
|
680
|
+
fps = self._max_fps
|
|
681
|
+
if fps > 0:
|
|
682
|
+
min_sleep = self.get_resolution()
|
|
683
|
+
undershoot = 4 / 5. * min_sleep
|
|
684
|
+
usleep = self.usleep
|
|
685
|
+
ready = self._check_ready
|
|
686
|
+
|
|
687
|
+
done, sleeptime = ready(fps, min_sleep, undershoot)
|
|
688
|
+
while not done:
|
|
689
|
+
usleep(1000000 * sleeptime)
|
|
690
|
+
done, sleeptime = ready(fps, min_sleep, undershoot)
|
|
691
|
+
|
|
692
|
+
current = self.time()
|
|
693
|
+
self._dt = current - self._last_tick
|
|
694
|
+
self._last_tick = current
|
|
695
|
+
return current
|
|
696
|
+
|
|
697
|
+
async def async_idle(self):
|
|
698
|
+
'''(internal) async version of :meth:`idle`.
|
|
699
|
+
'''
|
|
700
|
+
fps = self._max_fps
|
|
701
|
+
if fps > 0:
|
|
702
|
+
min_sleep = self.get_resolution()
|
|
703
|
+
undershoot = 4 / 5. * min_sleep
|
|
704
|
+
ready = self._check_ready
|
|
705
|
+
|
|
706
|
+
slept = False
|
|
707
|
+
done, sleeptime = ready(fps, min_sleep, undershoot)
|
|
708
|
+
while not done:
|
|
709
|
+
slept = True
|
|
710
|
+
await self._async_lib.sleep(sleeptime)
|
|
711
|
+
done, sleeptime = ready(fps, min_sleep, undershoot)
|
|
712
|
+
|
|
713
|
+
if not slept:
|
|
714
|
+
await self._async_lib.sleep(0)
|
|
715
|
+
else:
|
|
716
|
+
await self._async_lib.sleep(0)
|
|
717
|
+
|
|
718
|
+
current = self.time()
|
|
719
|
+
self._dt = current - self._last_tick
|
|
720
|
+
self._last_tick = current
|
|
721
|
+
return current
|
|
722
|
+
|
|
723
|
+
def _check_ready(self, fps, min_sleep, undershoot):
|
|
724
|
+
sleeptime = 1 / fps - (self.time() - self._last_tick)
|
|
725
|
+
return sleeptime - undershoot <= min_sleep, sleeptime - undershoot
|
|
726
|
+
|
|
727
|
+
def tick(self):
|
|
728
|
+
'''Advance the clock to the next step. Must be called every frame.
|
|
729
|
+
The default clock has a tick() function called by the core Kivy
|
|
730
|
+
framework.'''
|
|
731
|
+
self.pre_idle()
|
|
732
|
+
ts = self.time()
|
|
733
|
+
self.post_idle(ts, self.idle())
|
|
734
|
+
|
|
735
|
+
async def async_tick(self):
|
|
736
|
+
'''async version of :meth:`tick`. '''
|
|
737
|
+
self.pre_idle()
|
|
738
|
+
ts = self.time()
|
|
739
|
+
current = await self.async_idle()
|
|
740
|
+
self.post_idle(ts, current)
|
|
741
|
+
|
|
742
|
+
def pre_idle(self):
|
|
743
|
+
'''Called before :meth:`idle` by :meth:`tick`.
|
|
744
|
+
'''
|
|
745
|
+
self._release_references()
|
|
746
|
+
|
|
747
|
+
def post_idle(self, ts, current):
|
|
748
|
+
'''Called after :meth:`idle` by :meth:`tick`.
|
|
749
|
+
'''
|
|
750
|
+
# tick the current time
|
|
751
|
+
self._frames += 1
|
|
752
|
+
self._fps_counter += 1
|
|
753
|
+
|
|
754
|
+
# compute how long the event processing takes
|
|
755
|
+
self._duration_count += 1
|
|
756
|
+
self._sleep_time += current - ts
|
|
757
|
+
t_tot = current - self._duration_ts0
|
|
758
|
+
if t_tot >= 1.:
|
|
759
|
+
self._events_duration = \
|
|
760
|
+
(t_tot - self._sleep_time) / float(self._duration_count)
|
|
761
|
+
self._duration_ts0 = current
|
|
762
|
+
self._sleep_time = self._duration_count = 0
|
|
763
|
+
|
|
764
|
+
# calculate fps things
|
|
765
|
+
if self._last_fps_tick is None:
|
|
766
|
+
self._last_fps_tick = current
|
|
767
|
+
elif current - self._last_fps_tick > 1:
|
|
768
|
+
d = float(current - self._last_fps_tick)
|
|
769
|
+
self._fps = self._fps_counter / d
|
|
770
|
+
self._rfps = self._rfps_counter
|
|
771
|
+
self._last_fps_tick = current
|
|
772
|
+
self._fps_counter = 0
|
|
773
|
+
self._rfps_counter = 0
|
|
774
|
+
|
|
775
|
+
# process event
|
|
776
|
+
self._process_events()
|
|
777
|
+
|
|
778
|
+
return self._dt
|
|
779
|
+
|
|
780
|
+
def tick_draw(self):
|
|
781
|
+
'''Tick the drawing counter.
|
|
782
|
+
'''
|
|
783
|
+
self._process_events_before_frame()
|
|
784
|
+
self._rfps_counter += 1
|
|
785
|
+
self._frames_displayed += 1
|
|
786
|
+
|
|
787
|
+
def get_fps(self):
|
|
788
|
+
'''Get the current average FPS calculated by the clock.
|
|
789
|
+
'''
|
|
790
|
+
return self._fps
|
|
791
|
+
|
|
792
|
+
def get_rfps(self):
|
|
793
|
+
'''Get the current "real" FPS calculated by the clock.
|
|
794
|
+
This counter reflects the real framerate displayed on the screen.
|
|
795
|
+
|
|
796
|
+
In contrast to get_fps(), this function returns a counter of the
|
|
797
|
+
number of frames, not the average of frames per second.
|
|
798
|
+
'''
|
|
799
|
+
return self._rfps
|
|
800
|
+
|
|
801
|
+
def get_time(self):
|
|
802
|
+
'''Get the last tick made by the clock.'''
|
|
803
|
+
return self._last_tick
|
|
804
|
+
|
|
805
|
+
def get_boottime(self):
|
|
806
|
+
'''Get the time in seconds from the application start.'''
|
|
807
|
+
return self._last_tick - self._start_tick
|
|
808
|
+
|
|
809
|
+
time = staticmethod(partial(_default_time))
|
|
810
|
+
|
|
811
|
+
def handle_exception(self, e):
|
|
812
|
+
from kivy.base import ExceptionManager
|
|
813
|
+
|
|
814
|
+
if ExceptionManager.handle_exception(e) == ExceptionManager.RAISE:
|
|
815
|
+
raise
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
ClockBaseBehavior.time.__doc__ = \
|
|
819
|
+
'''Proxy method for :func:`~kivy.compat.clock`. '''
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
class ClockBaseInterruptBehavior(ClockBaseBehavior):
|
|
823
|
+
'''A kivy clock which can be interrupted during a frame to execute events.
|
|
824
|
+
'''
|
|
825
|
+
|
|
826
|
+
interupt_next_only = False
|
|
827
|
+
_event = None
|
|
828
|
+
_async_event = None
|
|
829
|
+
_get_min_timeout_func = None
|
|
830
|
+
|
|
831
|
+
def __init__(self, interupt_next_only=False, **kwargs):
|
|
832
|
+
super(ClockBaseInterruptBehavior, self).__init__(**kwargs)
|
|
833
|
+
self._event = ThreadingEvent()
|
|
834
|
+
self.interupt_next_only = interupt_next_only
|
|
835
|
+
self._get_min_timeout_func = self.get_min_timeout
|
|
836
|
+
|
|
837
|
+
def init_async_lib(self, lib):
|
|
838
|
+
super(ClockBaseInterruptBehavior, self).init_async_lib(lib)
|
|
839
|
+
if lib == 'trio':
|
|
840
|
+
import trio
|
|
841
|
+
self._async_event = trio.Event()
|
|
842
|
+
# we don't know if this is called after things have already been
|
|
843
|
+
# scheduled, so don't delay for a full frame before processing
|
|
844
|
+
# events
|
|
845
|
+
self._async_event.set()
|
|
846
|
+
elif lib == 'asyncio':
|
|
847
|
+
import asyncio
|
|
848
|
+
self._async_event = asyncio.Event()
|
|
849
|
+
self._async_event.set()
|
|
850
|
+
|
|
851
|
+
def usleep(self, microseconds):
|
|
852
|
+
self._event.clear()
|
|
853
|
+
self._event.wait(microseconds / 1000000.)
|
|
854
|
+
|
|
855
|
+
async def async_usleep(self, microseconds):
|
|
856
|
+
self._async_event.clear()
|
|
857
|
+
await self._async_wait_for(
|
|
858
|
+
self._async_event.wait(), microseconds / 1000000.)
|
|
859
|
+
|
|
860
|
+
def on_schedule(self, event):
|
|
861
|
+
fps = self._max_fps
|
|
862
|
+
if not fps:
|
|
863
|
+
return
|
|
864
|
+
|
|
865
|
+
if not event.timeout or (
|
|
866
|
+
not self.interupt_next_only and event.timeout <=
|
|
867
|
+
1 / fps - # remaining time
|
|
868
|
+
(self.time() - self._last_tick) + # elapsed time
|
|
869
|
+
4 / 5. * self.get_resolution()): # resolution fudge factor
|
|
870
|
+
self._event.set()
|
|
871
|
+
if self._async_event:
|
|
872
|
+
self._async_event.set()
|
|
873
|
+
|
|
874
|
+
def idle(self):
|
|
875
|
+
fps = self._max_fps
|
|
876
|
+
event = self._event
|
|
877
|
+
resolution = self.get_resolution()
|
|
878
|
+
if fps > 0:
|
|
879
|
+
done, sleeptime = self._check_ready(
|
|
880
|
+
fps, resolution, 4 / 5. * resolution, event)
|
|
881
|
+
if not done:
|
|
882
|
+
event.wait(sleeptime)
|
|
883
|
+
|
|
884
|
+
current = self.time()
|
|
885
|
+
self._dt = current - self._last_tick
|
|
886
|
+
self._last_tick = current
|
|
887
|
+
event.clear()
|
|
888
|
+
# anything scheduled from now on, if scheduled for the upcoming frame
|
|
889
|
+
# will cause a timeout of the event on the next idle due to on_schedule
|
|
890
|
+
# `self._last_tick = current` must happen before clear, otherwise the
|
|
891
|
+
# on_schedule computation is wrong when exec between the clear and
|
|
892
|
+
# the `self._last_tick = current` bytecode.
|
|
893
|
+
return current
|
|
894
|
+
|
|
895
|
+
async def async_idle(self):
|
|
896
|
+
fps = self._max_fps
|
|
897
|
+
event = self._async_event
|
|
898
|
+
resolution = self.get_resolution()
|
|
899
|
+
if fps > 0:
|
|
900
|
+
done, sleeptime = self._check_ready(
|
|
901
|
+
fps, resolution, 4 / 5. * resolution, event)
|
|
902
|
+
if not done:
|
|
903
|
+
await self._async_wait_for(event.wait(), sleeptime)
|
|
904
|
+
else:
|
|
905
|
+
await self._async_lib.sleep(0)
|
|
906
|
+
else:
|
|
907
|
+
await self._async_lib.sleep(0)
|
|
908
|
+
|
|
909
|
+
current = self.time()
|
|
910
|
+
self._dt = current - self._last_tick
|
|
911
|
+
self._last_tick = current
|
|
912
|
+
event.clear()
|
|
913
|
+
# anything scheduled from now on, if scheduled for the upcoming frame
|
|
914
|
+
# will cause a timeout of the event on the next idle due to on_schedule
|
|
915
|
+
# `self._last_tick = current` must happen before clear, otherwise the
|
|
916
|
+
# on_schedule computation is wrong when exec between the clear and
|
|
917
|
+
# the `self._last_tick = current` bytecode.
|
|
918
|
+
return current
|
|
919
|
+
|
|
920
|
+
def _check_ready(self, fps, min_sleep, undershoot, event):
|
|
921
|
+
if event.is_set():
|
|
922
|
+
return True, 0
|
|
923
|
+
|
|
924
|
+
t = self._get_min_timeout_func()
|
|
925
|
+
if not t:
|
|
926
|
+
return True, 0
|
|
927
|
+
|
|
928
|
+
if not self.interupt_next_only:
|
|
929
|
+
curr_t = self.time()
|
|
930
|
+
sleeptime = min(1 / fps - (curr_t - self._last_tick), t - curr_t)
|
|
931
|
+
else:
|
|
932
|
+
sleeptime = 1 / fps - (self.time() - self._last_tick)
|
|
933
|
+
return sleeptime - undershoot <= min_sleep, sleeptime - undershoot
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
class ClockBaseInterruptFreeBehavior(ClockBaseInterruptBehavior):
|
|
937
|
+
'''A base class for the clock that interrupts the sleep interval for
|
|
938
|
+
free events.
|
|
939
|
+
'''
|
|
940
|
+
|
|
941
|
+
def __init__(self, **kwargs):
|
|
942
|
+
super(ClockBaseInterruptFreeBehavior, self).__init__(**kwargs)
|
|
943
|
+
self._get_min_timeout_func = self.get_min_free_timeout
|
|
944
|
+
|
|
945
|
+
def on_schedule(self, event):
|
|
946
|
+
if not event.free: # only wake up for free events
|
|
947
|
+
return
|
|
948
|
+
# free events should use real time not frame time
|
|
949
|
+
event._last_dt = self.time()
|
|
950
|
+
return super(ClockBaseInterruptFreeBehavior,
|
|
951
|
+
self).on_schedule(event)
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
class ClockBase(ClockBaseBehavior, CyClockBase):
|
|
955
|
+
'''The ``default`` kivy clock. See module for details.
|
|
956
|
+
'''
|
|
957
|
+
|
|
958
|
+
_sleep_obj = None
|
|
959
|
+
|
|
960
|
+
def __init__(self, **kwargs):
|
|
961
|
+
super(ClockBase, self).__init__(**kwargs)
|
|
962
|
+
self._sleep_obj = _get_sleep_obj()
|
|
963
|
+
|
|
964
|
+
def usleep(self, microseconds):
|
|
965
|
+
_usleep(microseconds, self._sleep_obj)
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
class ClockBaseInterrupt(ClockBaseInterruptBehavior, CyClockBase):
|
|
969
|
+
'''The ``interrupt`` kivy clock. See module for details.
|
|
970
|
+
'''
|
|
971
|
+
|
|
972
|
+
pass
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
class ClockBaseFreeInterruptAll(
|
|
976
|
+
ClockBaseInterruptFreeBehavior, CyClockBaseFree):
|
|
977
|
+
'''The ``free_all`` kivy clock. See module for details.
|
|
978
|
+
'''
|
|
979
|
+
|
|
980
|
+
pass
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
class ClockBaseFreeInterruptOnly(
|
|
984
|
+
ClockBaseInterruptFreeBehavior, CyClockBaseFree):
|
|
985
|
+
'''The ``free_only`` kivy clock. See module for details.
|
|
986
|
+
'''
|
|
987
|
+
|
|
988
|
+
def idle(self):
|
|
989
|
+
fps = self._max_fps
|
|
990
|
+
current = self.time()
|
|
991
|
+
event = self._event
|
|
992
|
+
if fps > 0:
|
|
993
|
+
min_sleep = self.get_resolution()
|
|
994
|
+
usleep = self.usleep
|
|
995
|
+
undershoot = 4 / 5. * min_sleep
|
|
996
|
+
min_t = self.get_min_free_timeout
|
|
997
|
+
interupt_next_only = self.interupt_next_only
|
|
998
|
+
|
|
999
|
+
sleeptime = 1 / fps - (current - self._last_tick)
|
|
1000
|
+
while sleeptime - undershoot > min_sleep:
|
|
1001
|
+
if event.is_set():
|
|
1002
|
+
do_free = True
|
|
1003
|
+
else:
|
|
1004
|
+
t = min_t()
|
|
1005
|
+
if not t:
|
|
1006
|
+
do_free = True
|
|
1007
|
+
elif interupt_next_only:
|
|
1008
|
+
do_free = False
|
|
1009
|
+
else:
|
|
1010
|
+
sleeptime = min(sleeptime, t - current)
|
|
1011
|
+
do_free = sleeptime - undershoot <= min_sleep
|
|
1012
|
+
|
|
1013
|
+
if do_free:
|
|
1014
|
+
event.clear()
|
|
1015
|
+
self._process_free_events(current)
|
|
1016
|
+
else:
|
|
1017
|
+
event.wait(sleeptime - undershoot)
|
|
1018
|
+
current = self.time()
|
|
1019
|
+
sleeptime = 1 / fps - (current - self._last_tick)
|
|
1020
|
+
|
|
1021
|
+
self._dt = current - self._last_tick
|
|
1022
|
+
self._last_tick = current
|
|
1023
|
+
event.clear() # this needs to stay after _last_tick
|
|
1024
|
+
return current
|
|
1025
|
+
|
|
1026
|
+
async def async_idle(self):
|
|
1027
|
+
fps = self._max_fps
|
|
1028
|
+
current = self.time()
|
|
1029
|
+
event = self._async_event
|
|
1030
|
+
if fps > 0:
|
|
1031
|
+
min_sleep = self.get_resolution()
|
|
1032
|
+
usleep = self.usleep
|
|
1033
|
+
undershoot = 4 / 5. * min_sleep
|
|
1034
|
+
min_t = self.get_min_free_timeout
|
|
1035
|
+
interupt_next_only = self.interupt_next_only
|
|
1036
|
+
|
|
1037
|
+
sleeptime = 1 / fps - (current - self._last_tick)
|
|
1038
|
+
slept = False
|
|
1039
|
+
while sleeptime - undershoot > min_sleep:
|
|
1040
|
+
if event.is_set():
|
|
1041
|
+
do_free = True
|
|
1042
|
+
else:
|
|
1043
|
+
t = min_t()
|
|
1044
|
+
if not t:
|
|
1045
|
+
do_free = True
|
|
1046
|
+
elif interupt_next_only:
|
|
1047
|
+
do_free = False
|
|
1048
|
+
else:
|
|
1049
|
+
sleeptime = min(sleeptime, t - current)
|
|
1050
|
+
do_free = sleeptime - undershoot <= min_sleep
|
|
1051
|
+
|
|
1052
|
+
if do_free:
|
|
1053
|
+
event.clear()
|
|
1054
|
+
self._process_free_events(current)
|
|
1055
|
+
else:
|
|
1056
|
+
slept = True
|
|
1057
|
+
await self._async_wait_for(
|
|
1058
|
+
event.wait(), sleeptime - undershoot)
|
|
1059
|
+
current = self.time()
|
|
1060
|
+
sleeptime = 1 / fps - (current - self._last_tick)
|
|
1061
|
+
|
|
1062
|
+
if not slept:
|
|
1063
|
+
await self._async_lib.sleep(0)
|
|
1064
|
+
else:
|
|
1065
|
+
await self._async_lib.sleep(0)
|
|
1066
|
+
|
|
1067
|
+
self._dt = current - self._last_tick
|
|
1068
|
+
self._last_tick = current
|
|
1069
|
+
event.clear() # this needs to stay after _last_tick
|
|
1070
|
+
return current
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
def mainthread(func):
|
|
1074
|
+
'''Decorator that will schedule the call of the function for the next
|
|
1075
|
+
available frame in the mainthread. It can be useful when you use
|
|
1076
|
+
:class:`~kivy.network.urlrequest.UrlRequest` or when you do Thread
|
|
1077
|
+
programming: you cannot do any OpenGL-related work in a thread.
|
|
1078
|
+
|
|
1079
|
+
Please note that this method will return directly and no result can be
|
|
1080
|
+
returned::
|
|
1081
|
+
|
|
1082
|
+
@mainthread
|
|
1083
|
+
def callback(self, *args):
|
|
1084
|
+
print('The request succeeded!',
|
|
1085
|
+
'This callback is called in the main thread.')
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
self.req = UrlRequest(url='http://...', on_success=callback)
|
|
1089
|
+
|
|
1090
|
+
.. versionadded:: 1.8.0
|
|
1091
|
+
'''
|
|
1092
|
+
@wraps(func)
|
|
1093
|
+
def delayed_func(*args, **kwargs):
|
|
1094
|
+
def callback_func(dt):
|
|
1095
|
+
func(*args, **kwargs)
|
|
1096
|
+
Clock.schedule_once(callback_func, 0)
|
|
1097
|
+
return delayed_func
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
def triggered(timeout=0, interval=False):
|
|
1101
|
+
'''Decorator that will trigger the call of the function at the specified
|
|
1102
|
+
timeout, through the method :meth:`CyClockBase.create_trigger`. Subsequent
|
|
1103
|
+
calls to the decorated function (while the timeout is active) are ignored.
|
|
1104
|
+
|
|
1105
|
+
It can be helpful when an expensive function (i.e. call to a server) can be
|
|
1106
|
+
triggered by different methods. Setting a proper timeout will delay the
|
|
1107
|
+
calling and only one of them will be triggered.
|
|
1108
|
+
|
|
1109
|
+
@triggered(timeout, interval=False)
|
|
1110
|
+
def callback(id):
|
|
1111
|
+
print('The callback has been called with id=%d' % id)
|
|
1112
|
+
|
|
1113
|
+
>> callback(id=1)
|
|
1114
|
+
>> callback(id=2)
|
|
1115
|
+
The callback has been called with id=2
|
|
1116
|
+
|
|
1117
|
+
The decorated callback can also be unscheduled using:
|
|
1118
|
+
|
|
1119
|
+
>> callback.cancel()
|
|
1120
|
+
|
|
1121
|
+
.. versionadded:: 1.10.1
|
|
1122
|
+
'''
|
|
1123
|
+
|
|
1124
|
+
def wrapper_triggered(func):
|
|
1125
|
+
|
|
1126
|
+
_args = []
|
|
1127
|
+
_kwargs = {}
|
|
1128
|
+
|
|
1129
|
+
def cb_function(dt):
|
|
1130
|
+
func(*tuple(_args), **_kwargs)
|
|
1131
|
+
|
|
1132
|
+
cb_trigger = Clock.create_trigger(
|
|
1133
|
+
cb_function,
|
|
1134
|
+
timeout=timeout,
|
|
1135
|
+
interval=interval)
|
|
1136
|
+
|
|
1137
|
+
@wraps(func)
|
|
1138
|
+
def trigger_function(*args, **kwargs):
|
|
1139
|
+
_args[:] = []
|
|
1140
|
+
_args.extend(list(args))
|
|
1141
|
+
_kwargs.clear()
|
|
1142
|
+
_kwargs.update(kwargs)
|
|
1143
|
+
cb_trigger()
|
|
1144
|
+
|
|
1145
|
+
def trigger_cancel():
|
|
1146
|
+
cb_trigger.cancel()
|
|
1147
|
+
|
|
1148
|
+
setattr(trigger_function, 'cancel', trigger_cancel)
|
|
1149
|
+
|
|
1150
|
+
return trigger_function
|
|
1151
|
+
|
|
1152
|
+
return wrapper_triggered
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
if 'KIVY_DOC_INCLUDE' in environ:
|
|
1156
|
+
#: Instance of :class:`ClockBaseBehavior`.
|
|
1157
|
+
Clock: ClockBase = None
|
|
1158
|
+
else:
|
|
1159
|
+
_classes = {'default': ClockBase, 'interrupt': ClockBaseInterrupt,
|
|
1160
|
+
'free_all': ClockBaseFreeInterruptAll,
|
|
1161
|
+
'free_only': ClockBaseFreeInterruptOnly}
|
|
1162
|
+
_clk = environ.get('KIVY_CLOCK', Config.get('kivy', 'kivy_clock'))
|
|
1163
|
+
if _clk not in _classes:
|
|
1164
|
+
raise Exception(
|
|
1165
|
+
'{} is not a valid kivy clock. Valid clocks are {}'.format(
|
|
1166
|
+
_clk, sorted(_classes.keys())))
|
|
1167
|
+
|
|
1168
|
+
Clock: ClockBase = register_context(
|
|
1169
|
+
'Clock', _classes[_clk],
|
|
1170
|
+
async_lib=environ.get('KIVY_EVENTLOOP', 'asyncio'))
|
|
1171
|
+
'''The kivy Clock instance. See module documentation for details.
|
|
1172
|
+
'''
|