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
|
@@ -0,0 +1,1090 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Text
|
|
3
|
+
====
|
|
4
|
+
|
|
5
|
+
An abstraction of text creation. Depending of the selected backend, the
|
|
6
|
+
accuracy of text rendering may vary.
|
|
7
|
+
|
|
8
|
+
.. versionchanged:: 1.10.1
|
|
9
|
+
:meth:`LabelBase.find_base_direction` added.
|
|
10
|
+
|
|
11
|
+
.. versionchanged:: 1.5.0
|
|
12
|
+
:attr:`LabelBase.line_height` added.
|
|
13
|
+
|
|
14
|
+
.. versionchanged:: 1.0.7
|
|
15
|
+
The :class:`LabelBase` does not generate any texture if the text has a
|
|
16
|
+
width <= 1.
|
|
17
|
+
|
|
18
|
+
This is the backend layer for rendering text with different text providers,
|
|
19
|
+
you should only be using this directly if your needs aren't fulfilled by the
|
|
20
|
+
:class:`~kivy.uix.label.Label`.
|
|
21
|
+
|
|
22
|
+
Usage example::
|
|
23
|
+
|
|
24
|
+
from kivy.core.text import Label as CoreLabel
|
|
25
|
+
|
|
26
|
+
...
|
|
27
|
+
...
|
|
28
|
+
my_label = CoreLabel()
|
|
29
|
+
my_label.text = 'hello'
|
|
30
|
+
# the label is usually not drawn until needed, so force it to draw.
|
|
31
|
+
my_label.refresh()
|
|
32
|
+
# Now access the texture of the label and use it wherever and
|
|
33
|
+
# however you may please.
|
|
34
|
+
hello_texture = my_label.texture
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
Font Context Manager
|
|
38
|
+
====================
|
|
39
|
+
|
|
40
|
+
A font context is a namespace where multiple fonts are loaded; if a font is
|
|
41
|
+
missing a glyph needed to render text, it can fall back to a different font in
|
|
42
|
+
the same context. The font context manager can be used to query and manipulate
|
|
43
|
+
the state of font contexts when using the Pango text provider (no other
|
|
44
|
+
provider currently implements it).
|
|
45
|
+
|
|
46
|
+
.. versionadded:: 1.11.0
|
|
47
|
+
|
|
48
|
+
.. warning:: This feature requires the Pango text provider.
|
|
49
|
+
|
|
50
|
+
Font contexts can be created automatically by :class:`kivy.uix.label.Label` or
|
|
51
|
+
:class:`kivy.uix.textinput.TextInput`; if a non-existent context is used in
|
|
52
|
+
one of these classes, it will be created automatically, or if a font file is
|
|
53
|
+
specified without a context (this creates an isolated context, without
|
|
54
|
+
support for fallback).
|
|
55
|
+
|
|
56
|
+
Usage example::
|
|
57
|
+
|
|
58
|
+
from kivy.uix.label import Label
|
|
59
|
+
from kivy.core.text import FontContextManager as FCM
|
|
60
|
+
|
|
61
|
+
# Create a font context containing system fonts + one custom TTF
|
|
62
|
+
FCM.create('system://myapp')
|
|
63
|
+
family = FCM.add_font('/path/to/file.ttf')
|
|
64
|
+
|
|
65
|
+
# These are now interchangeable ways to refer to the custom font:
|
|
66
|
+
lbl1 = Label(font_context='system://myapp', family_name=family)
|
|
67
|
+
lbl2 = Label(font_context='system://myapp', font_name='/path/to/file.ttf')
|
|
68
|
+
|
|
69
|
+
# You could also refer to a system font by family, since this is a
|
|
70
|
+
# system:// font context
|
|
71
|
+
lbl3 = Label(font_context='system://myapp', family_name='Arial')
|
|
72
|
+
'''
|
|
73
|
+
|
|
74
|
+
__all__ = ('LabelBase', 'Label',
|
|
75
|
+
'FontContextManagerBase', 'FontContextManager')
|
|
76
|
+
|
|
77
|
+
import re
|
|
78
|
+
import os
|
|
79
|
+
from ast import literal_eval
|
|
80
|
+
from functools import partial
|
|
81
|
+
from copy import copy
|
|
82
|
+
from kivy import kivy_data_dir
|
|
83
|
+
from kivy.config import Config
|
|
84
|
+
from kivy.utils import platform
|
|
85
|
+
from kivy.graphics.texture import Texture
|
|
86
|
+
from kivy.core import core_select_lib
|
|
87
|
+
from kivy.core.text.text_layout import layout_text, LayoutWord
|
|
88
|
+
from kivy.resources import resource_find, resource_add_path
|
|
89
|
+
from kivy.compat import PY2
|
|
90
|
+
from kivy.setupconfig import USE_SDL2, USE_PANGOFT2
|
|
91
|
+
from kivy.logger import Logger
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if 'KIVY_DOC' not in os.environ:
|
|
95
|
+
_default_font_paths = literal_eval(Config.get('kivy', 'default_font'))
|
|
96
|
+
DEFAULT_FONT = _default_font_paths.pop(0)
|
|
97
|
+
else:
|
|
98
|
+
DEFAULT_FONT = None
|
|
99
|
+
|
|
100
|
+
FONT_REGULAR = 0
|
|
101
|
+
FONT_ITALIC = 1
|
|
102
|
+
FONT_BOLD = 2
|
|
103
|
+
FONT_BOLDITALIC = 3
|
|
104
|
+
|
|
105
|
+
whitespace_pat = re.compile('( +)')
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class LabelBase(object):
|
|
109
|
+
'''Core text label.
|
|
110
|
+
This is the abstract class used by different backends to render text.
|
|
111
|
+
|
|
112
|
+
.. warning::
|
|
113
|
+
The core text label can't be changed at runtime. You must recreate one.
|
|
114
|
+
|
|
115
|
+
:Parameters:
|
|
116
|
+
`font_size`: int, defaults to 12
|
|
117
|
+
Font size of the text
|
|
118
|
+
`font_context`: str, defaults to None
|
|
119
|
+
Context for the specified font (see :class:`kivy.uix.label.Label`
|
|
120
|
+
for details). `None` will autocreate an isolated context named
|
|
121
|
+
after the resolved font file.
|
|
122
|
+
`font_name`: str, defaults to DEFAULT_FONT
|
|
123
|
+
Font name of the text
|
|
124
|
+
`font_family`: str, defaults to None
|
|
125
|
+
Font family name to request for drawing, this can only be used
|
|
126
|
+
with `font_context`.
|
|
127
|
+
`bold`: bool, defaults to False
|
|
128
|
+
Activate "bold" text style
|
|
129
|
+
`italic`: bool, defaults to False
|
|
130
|
+
Activate "italic" text style
|
|
131
|
+
`text_size`: tuple, defaults to (None, None)
|
|
132
|
+
Add constraint to render the text (inside a bounding box).
|
|
133
|
+
If no size is given, the label size will be set to the text size.
|
|
134
|
+
`padding`: int|float or list|tuple, defaults to [0, 0, 0, 0].
|
|
135
|
+
Padding of the text in the format [padding_left, padding_top,
|
|
136
|
+
padding_right, padding_bottom].
|
|
137
|
+
``padding`` should be int|float or a list|tuple with 1, 2 or 4
|
|
138
|
+
elements.
|
|
139
|
+
`padding_x`: float, defaults to 0.0
|
|
140
|
+
Left/right padding
|
|
141
|
+
`padding_y`: float, defaults to 0.0
|
|
142
|
+
Top/bottom padding
|
|
143
|
+
`halign`: str, defaults to "left"
|
|
144
|
+
Horizontal text alignment inside the bounding box
|
|
145
|
+
`valign`: str, defaults to "bottom"
|
|
146
|
+
Vertical text alignment inside the bounding box
|
|
147
|
+
`shorten`: bool, defaults to False
|
|
148
|
+
Indicate whether the label should attempt to shorten its textual
|
|
149
|
+
contents as much as possible if a `size` is given.
|
|
150
|
+
Setting this to True without an appropriately set size will lead to
|
|
151
|
+
unexpected results.
|
|
152
|
+
`shorten_from`: str, defaults to `center`
|
|
153
|
+
The side from which we should shorten the text from, can be left,
|
|
154
|
+
right, or center. E.g. if left, the ellipsis will appear towards
|
|
155
|
+
the left side and it will display as much text starting from the
|
|
156
|
+
right as possible.
|
|
157
|
+
`split_str`: string, defaults to `' '` (space)
|
|
158
|
+
The string to use to split the words by when shortening. If empty,
|
|
159
|
+
we can split after every character filling up the line as much as
|
|
160
|
+
possible.
|
|
161
|
+
`max_lines`: int, defaults to 0 (unlimited)
|
|
162
|
+
If set, this indicate how maximum line are allowed to render the
|
|
163
|
+
text. Works only if a limitation on text_size is set.
|
|
164
|
+
`mipmap`: bool, defaults to False
|
|
165
|
+
Create a mipmap for the texture
|
|
166
|
+
`strip`: bool, defaults to False
|
|
167
|
+
Whether each row of text has its leading and trailing spaces
|
|
168
|
+
stripped. If `halign` is `justify` it is implicitly True.
|
|
169
|
+
`strip_reflow`: bool, defaults to True
|
|
170
|
+
Whether text that has been reflowed into a second line should
|
|
171
|
+
be stripped, even if `strip` is False. This is only in effect when
|
|
172
|
+
`size_hint_x` is not None, because otherwise lines are never
|
|
173
|
+
split.
|
|
174
|
+
`unicode_errors`: str, defaults to `'replace'`
|
|
175
|
+
How to handle unicode decode errors. Can be `'strict'`, `'replace'`
|
|
176
|
+
or `'ignore'`.
|
|
177
|
+
`outline_width`: int, defaults to None
|
|
178
|
+
Width in pixels for the outline.
|
|
179
|
+
`outline_color`: tuple, defaults to (0, 0, 0)
|
|
180
|
+
Color of the outline.
|
|
181
|
+
`font_features`: str, defaults to None
|
|
182
|
+
OpenType font features in CSS format (Pango only)
|
|
183
|
+
`base_direction`: str, defaults to None (auto)
|
|
184
|
+
Text direction, one of `None`, `'ltr'`, `'rtl'`, `'weak_ltr'`,
|
|
185
|
+
or `'weak_rtl'` (Pango only)
|
|
186
|
+
`text_language`: str, defaults to None (user locale)
|
|
187
|
+
RFC-3066 format language tag as a string (Pango only)
|
|
188
|
+
`limit_render_to_text_bbox`: bool, defaults to False. PIL only.
|
|
189
|
+
If set to ``True``, this parameter indicates that rendering should
|
|
190
|
+
be limited to the bounding box of the text, excluding any
|
|
191
|
+
additional white spaces designated for ascent and descent.
|
|
192
|
+
By limiting the rendering to the bounding box of the text, it
|
|
193
|
+
ensures a more precise alignment with surrounding elements when
|
|
194
|
+
utilizing properties such as `valign`, `y`, `pos`, `pos_hint`, etc.
|
|
195
|
+
|
|
196
|
+
.. versionadded:: 2.3.0
|
|
197
|
+
`limit_render_to_text_bbox` was added to allow to limit text rendering
|
|
198
|
+
to the text bounding box (PIL only).
|
|
199
|
+
|
|
200
|
+
.. deprecated:: 2.2.0
|
|
201
|
+
`padding_x` and `padding_y` have been deprecated. Please use `padding`
|
|
202
|
+
instead.
|
|
203
|
+
|
|
204
|
+
.. versionchanged:: 2.2.0
|
|
205
|
+
`padding` is now a list and defaults to [0, 0, 0, 0]. `padding` accepts
|
|
206
|
+
int|float or a list|tuple with 1, 2 or 4 elements.
|
|
207
|
+
|
|
208
|
+
.. versionchanged:: 1.10.1
|
|
209
|
+
`font_context`, `font_family`, `font_features`, `base_direction`
|
|
210
|
+
and `text_language` were added.
|
|
211
|
+
|
|
212
|
+
.. versionchanged:: 1.10.0
|
|
213
|
+
`outline_width` and `outline_color` were added.
|
|
214
|
+
|
|
215
|
+
.. versionchanged:: 1.9.0
|
|
216
|
+
`strip`, `strip_reflow`, `shorten_from`, `split_str`, and
|
|
217
|
+
`unicode_errors` were added.
|
|
218
|
+
|
|
219
|
+
.. versionchanged:: 1.9.0
|
|
220
|
+
`padding_x` and `padding_y` has been fixed to work as expected.
|
|
221
|
+
In the past, the text was padded by the negative of their values.
|
|
222
|
+
|
|
223
|
+
.. versionchanged:: 1.8.0
|
|
224
|
+
`max_lines` parameters has been added.
|
|
225
|
+
|
|
226
|
+
.. versionchanged:: 1.0.8
|
|
227
|
+
`size` have been deprecated and replaced with `text_size`.
|
|
228
|
+
|
|
229
|
+
.. versionchanged:: 1.0.7
|
|
230
|
+
The `valign` is now respected. This wasn't the case previously
|
|
231
|
+
so you might have an issue in your application if you have not
|
|
232
|
+
considered this.
|
|
233
|
+
|
|
234
|
+
'''
|
|
235
|
+
|
|
236
|
+
__slots__ = ('options', 'texture', '_label', '_text_size')
|
|
237
|
+
|
|
238
|
+
_cached_lines = []
|
|
239
|
+
|
|
240
|
+
_fonts = {}
|
|
241
|
+
|
|
242
|
+
_fonts_cache = {}
|
|
243
|
+
|
|
244
|
+
_fonts_dirs = []
|
|
245
|
+
|
|
246
|
+
_font_dirs_files = []
|
|
247
|
+
|
|
248
|
+
_texture_1px = None
|
|
249
|
+
|
|
250
|
+
_font_family_support = False
|
|
251
|
+
|
|
252
|
+
def __init__(
|
|
253
|
+
self, text='', font_size=12, font_name=DEFAULT_FONT, bold=False,
|
|
254
|
+
italic=False, underline=False, strikethrough=False, font_family=None,
|
|
255
|
+
halign='left', valign='bottom', shorten=False,
|
|
256
|
+
text_size=None, mipmap=False, color=None, line_height=1.0, strip=False,
|
|
257
|
+
strip_reflow=True, shorten_from='center', split_str=' ',
|
|
258
|
+
unicode_errors='replace',
|
|
259
|
+
font_hinting='normal', font_kerning=True, font_blended=True,
|
|
260
|
+
outline_width=None, outline_color=None, font_context=None,
|
|
261
|
+
font_features=None, base_direction=None, font_direction='ltr',
|
|
262
|
+
font_script_name='Latin', text_language=None,
|
|
263
|
+
limit_render_to_text_bbox=False,
|
|
264
|
+
**kwargs):
|
|
265
|
+
|
|
266
|
+
# Include system fonts_dir in resource paths.
|
|
267
|
+
# This allows us to specify a font from those dirs.
|
|
268
|
+
LabelBase.get_system_fonts_dir()
|
|
269
|
+
|
|
270
|
+
options = {'text': text, 'font_size': font_size,
|
|
271
|
+
'font_name': font_name, 'bold': bold, 'italic': italic,
|
|
272
|
+
'underline': underline, 'strikethrough': strikethrough,
|
|
273
|
+
'font_family': font_family,
|
|
274
|
+
'halign': halign, 'valign': valign, 'shorten': shorten,
|
|
275
|
+
'mipmap': mipmap, 'line_height': line_height,
|
|
276
|
+
'strip': strip, 'strip_reflow': strip_reflow,
|
|
277
|
+
'shorten_from': shorten_from, 'split_str': split_str,
|
|
278
|
+
'unicode_errors': unicode_errors,
|
|
279
|
+
'font_hinting': font_hinting,
|
|
280
|
+
'font_kerning': font_kerning,
|
|
281
|
+
'font_blended': font_blended,
|
|
282
|
+
'outline_width': outline_width,
|
|
283
|
+
'font_context': font_context,
|
|
284
|
+
'font_features': font_features,
|
|
285
|
+
'base_direction': base_direction,
|
|
286
|
+
'font_direction': font_direction,
|
|
287
|
+
'font_script_name': font_script_name,
|
|
288
|
+
'text_language': text_language,
|
|
289
|
+
'limit_render_to_text_bbox': limit_render_to_text_bbox}
|
|
290
|
+
|
|
291
|
+
kwargs_get = kwargs.get
|
|
292
|
+
options['color'] = color or (1, 1, 1, 1)
|
|
293
|
+
options['outline_color'] = outline_color or (0, 0, 0, 1)
|
|
294
|
+
|
|
295
|
+
options['padding'] = kwargs_get('padding', [0, 0, 0, 0])
|
|
296
|
+
if isinstance(options['padding'], (int, float)):
|
|
297
|
+
options['padding'] = [options['padding']] * 4
|
|
298
|
+
elif (
|
|
299
|
+
isinstance(options['padding'], (list, tuple))
|
|
300
|
+
and len(options['padding']) != 4
|
|
301
|
+
):
|
|
302
|
+
if len(options['padding']) == 1:
|
|
303
|
+
options['padding'] = options['padding'] * 4
|
|
304
|
+
elif len(options['padding']) == 2:
|
|
305
|
+
options['padding'] = options['padding'] * 2
|
|
306
|
+
else:
|
|
307
|
+
raise ValueError(
|
|
308
|
+
"padding should be int|float or a list|tuple with 1, 2 or "
|
|
309
|
+
f"4 elements, got {type(options['padding'])} with "
|
|
310
|
+
f"{len(options['padding'])} elements."
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
options['padding_x'] = kwargs_get('padding_x')
|
|
314
|
+
options['padding_y'] = kwargs_get('padding_y')
|
|
315
|
+
for padding_option in ('padding_x', 'padding_y'):
|
|
316
|
+
if kwargs_get(padding_option):
|
|
317
|
+
Logger.warning(
|
|
318
|
+
f"LabelBase: The use of the {padding_option} parameter is "
|
|
319
|
+
"deprecated, and will be removed in future versions. Use "
|
|
320
|
+
"padding instead."
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
if 'size' in kwargs:
|
|
324
|
+
options['text_size'] = kwargs['size']
|
|
325
|
+
else:
|
|
326
|
+
if text_size is None:
|
|
327
|
+
options['text_size'] = (None, None)
|
|
328
|
+
else:
|
|
329
|
+
options['text_size'] = text_size
|
|
330
|
+
|
|
331
|
+
self._text_size = options['text_size']
|
|
332
|
+
self._text = options['text']
|
|
333
|
+
self._internal_size = 0, 0 # the real computed text size (inclds pad)
|
|
334
|
+
self._cached_lines = []
|
|
335
|
+
|
|
336
|
+
self.options = options
|
|
337
|
+
self.texture = None
|
|
338
|
+
self.is_shortened = False
|
|
339
|
+
self.resolve_font_name()
|
|
340
|
+
self._migrate_deprecated_padding_xy()
|
|
341
|
+
|
|
342
|
+
def _migrate_deprecated_padding_xy(self):
|
|
343
|
+
options = self.options
|
|
344
|
+
self.options['padding'] = list(self.options['padding'])
|
|
345
|
+
if options['padding_x']:
|
|
346
|
+
self.options['padding'][::2] = [options['padding_x']] * 2
|
|
347
|
+
if options['padding_y']:
|
|
348
|
+
self.options['padding'][1::2] = [options['padding_y']] * 2
|
|
349
|
+
|
|
350
|
+
@staticmethod
|
|
351
|
+
def register(name, fn_regular, fn_italic=None, fn_bold=None,
|
|
352
|
+
fn_bolditalic=None):
|
|
353
|
+
'''Register an alias for a Font.
|
|
354
|
+
|
|
355
|
+
.. versionadded:: 1.1.0
|
|
356
|
+
|
|
357
|
+
If you're using a ttf directly, you might not be able to use the
|
|
358
|
+
bold/italic properties of
|
|
359
|
+
the ttf version. If the font is delivered in multiple files
|
|
360
|
+
(one regular, one italic and one bold), then you need to register these
|
|
361
|
+
files and use the alias instead.
|
|
362
|
+
|
|
363
|
+
All the fn_regular/fn_italic/fn_bold parameters are resolved with
|
|
364
|
+
:func:`kivy.resources.resource_find`. If fn_italic/fn_bold are None,
|
|
365
|
+
fn_regular will be used instead.
|
|
366
|
+
'''
|
|
367
|
+
|
|
368
|
+
if fn_regular is None:
|
|
369
|
+
raise ValueError("font_regular cannot be None")
|
|
370
|
+
|
|
371
|
+
fonts = []
|
|
372
|
+
|
|
373
|
+
for font_type in fn_regular, fn_italic, fn_bold, fn_bolditalic:
|
|
374
|
+
if font_type is not None:
|
|
375
|
+
font = resource_find(font_type)
|
|
376
|
+
|
|
377
|
+
if font is None:
|
|
378
|
+
raise IOError('File {0} not found'.format(font_type))
|
|
379
|
+
else:
|
|
380
|
+
fonts.append(font)
|
|
381
|
+
else:
|
|
382
|
+
fonts.append(fonts[0]) # add regular font to list again
|
|
383
|
+
|
|
384
|
+
LabelBase._fonts[name] = tuple(fonts)
|
|
385
|
+
|
|
386
|
+
def resolve_font_name(self):
|
|
387
|
+
options = self.options
|
|
388
|
+
fontname = options['font_name']
|
|
389
|
+
fonts = self._fonts
|
|
390
|
+
fontscache = self._fonts_cache
|
|
391
|
+
|
|
392
|
+
if self._font_family_support and options['font_family']:
|
|
393
|
+
options['font_name_r'] = None
|
|
394
|
+
return
|
|
395
|
+
|
|
396
|
+
# is the font registered?
|
|
397
|
+
if fontname in fonts:
|
|
398
|
+
# return the preferred font for the current bold/italic combination
|
|
399
|
+
italic = int(options['italic'])
|
|
400
|
+
if options['bold']:
|
|
401
|
+
bold = FONT_BOLD
|
|
402
|
+
else:
|
|
403
|
+
bold = FONT_REGULAR
|
|
404
|
+
|
|
405
|
+
options['font_name_r'] = fonts[fontname][italic | bold]
|
|
406
|
+
|
|
407
|
+
elif fontname in fontscache:
|
|
408
|
+
options['font_name_r'] = fontscache[fontname]
|
|
409
|
+
else:
|
|
410
|
+
filename = resource_find(fontname)
|
|
411
|
+
if not filename and not fontname.endswith('.ttf'):
|
|
412
|
+
fontname = '{}.ttf'.format(fontname)
|
|
413
|
+
filename = resource_find(fontname)
|
|
414
|
+
|
|
415
|
+
if filename is None:
|
|
416
|
+
# XXX for compatibility, check directly in the data dir
|
|
417
|
+
filename = pep8_fn = os.path.join(kivy_data_dir, fontname)
|
|
418
|
+
if not os.path.exists(pep8_fn) or not os.path.isfile(pep8_fn):
|
|
419
|
+
raise IOError('Label: File %r not found' % fontname)
|
|
420
|
+
fontscache[fontname] = filename
|
|
421
|
+
options['font_name_r'] = filename
|
|
422
|
+
|
|
423
|
+
@staticmethod
|
|
424
|
+
def get_system_fonts_dir():
|
|
425
|
+
'''Return the directories used by the system for fonts.
|
|
426
|
+
'''
|
|
427
|
+
if LabelBase._fonts_dirs:
|
|
428
|
+
return LabelBase._fonts_dirs
|
|
429
|
+
|
|
430
|
+
fdirs = []
|
|
431
|
+
if platform == 'linux':
|
|
432
|
+
fdirs = [
|
|
433
|
+
'/usr/share/fonts', '/usr/local/share/fonts',
|
|
434
|
+
os.path.expanduser('~/.fonts'),
|
|
435
|
+
os.path.expanduser('~/.local/share/fonts')]
|
|
436
|
+
elif platform == 'macosx':
|
|
437
|
+
fdirs = ['/Library/Fonts', '/System/Library/Fonts',
|
|
438
|
+
os.path.expanduser('~/Library/Fonts')]
|
|
439
|
+
elif platform == 'win':
|
|
440
|
+
fdirs = [os.path.join(os.environ['SYSTEMROOT'], 'Fonts')]
|
|
441
|
+
elif platform == 'ios':
|
|
442
|
+
fdirs = ['/System/Library/Fonts']
|
|
443
|
+
elif platform == 'android':
|
|
444
|
+
fdirs = ['/system/fonts']
|
|
445
|
+
else:
|
|
446
|
+
raise Exception("Unknown platform: {}".format(platform))
|
|
447
|
+
|
|
448
|
+
fdirs.append(os.path.join(kivy_data_dir, 'fonts'))
|
|
449
|
+
# register the font dirs
|
|
450
|
+
rdirs = []
|
|
451
|
+
_font_dir_files = []
|
|
452
|
+
for fdir in fdirs:
|
|
453
|
+
for _dir, dirs, files in os.walk(fdir):
|
|
454
|
+
_font_dir_files.extend(files)
|
|
455
|
+
resource_add_path(_dir)
|
|
456
|
+
rdirs.append(_dir)
|
|
457
|
+
LabelBase._fonts_dirs = rdirs
|
|
458
|
+
LabelBase._font_dirs_files = _font_dir_files
|
|
459
|
+
|
|
460
|
+
return rdirs
|
|
461
|
+
|
|
462
|
+
def get_extents(self, text):
|
|
463
|
+
'''Return a tuple (width, height) indicating the size of the specified
|
|
464
|
+
text'''
|
|
465
|
+
return (0, 0)
|
|
466
|
+
|
|
467
|
+
def get_cached_extents(self):
|
|
468
|
+
'''Returns a cached version of the :meth:`get_extents` function.
|
|
469
|
+
|
|
470
|
+
::
|
|
471
|
+
|
|
472
|
+
>>> func = self._get_cached_extents()
|
|
473
|
+
>>> func
|
|
474
|
+
<built-in method size of pygame.font.Font object at 0x01E45650>
|
|
475
|
+
>>> func('a line')
|
|
476
|
+
(36, 18)
|
|
477
|
+
|
|
478
|
+
.. warning::
|
|
479
|
+
|
|
480
|
+
This method returns a size measuring function that is valid
|
|
481
|
+
for the font settings used at the time :meth:`get_cached_extents`
|
|
482
|
+
was called. Any change in the font settings will render the
|
|
483
|
+
returned function incorrect. You should only use this if you know
|
|
484
|
+
what you're doing.
|
|
485
|
+
|
|
486
|
+
.. versionadded:: 1.9.0
|
|
487
|
+
'''
|
|
488
|
+
return self.get_extents
|
|
489
|
+
|
|
490
|
+
def _render_begin(self):
|
|
491
|
+
pass
|
|
492
|
+
|
|
493
|
+
def _render_text(self, text, x, y):
|
|
494
|
+
pass
|
|
495
|
+
|
|
496
|
+
def _render_end(self):
|
|
497
|
+
pass
|
|
498
|
+
|
|
499
|
+
def shorten(self, text, margin=2):
|
|
500
|
+
''' Shortens the text to fit into a single line by the width specified
|
|
501
|
+
by :attr:`text_size` [0]. If :attr:`text_size` [0] is None, it returns
|
|
502
|
+
text unchanged.
|
|
503
|
+
|
|
504
|
+
:attr:`split_str` and :attr:`shorten_from` determines how the text is
|
|
505
|
+
shortened.
|
|
506
|
+
|
|
507
|
+
:params:
|
|
508
|
+
|
|
509
|
+
`text` str, the text to be shortened.
|
|
510
|
+
`margin` int, the amount of space to leave between the margins
|
|
511
|
+
and the text. This is in addition to :attr:`padding_x`.
|
|
512
|
+
|
|
513
|
+
:returns:
|
|
514
|
+
the text shortened to fit into a single line.
|
|
515
|
+
'''
|
|
516
|
+
textwidth = self.get_cached_extents()
|
|
517
|
+
uw = self.text_size[0]
|
|
518
|
+
if uw is None or not text:
|
|
519
|
+
return text
|
|
520
|
+
|
|
521
|
+
opts = self.options
|
|
522
|
+
uw = max(0, int(uw - opts['padding'][0] - opts['padding'][2] - margin))
|
|
523
|
+
# if larger, it won't fit so don't even try extents
|
|
524
|
+
chr = type(text)
|
|
525
|
+
text = text.replace(chr('\n'), chr(' '))
|
|
526
|
+
if len(text) <= uw and textwidth(text)[0] <= uw:
|
|
527
|
+
return text
|
|
528
|
+
c = opts['split_str']
|
|
529
|
+
offset = 0 if len(c) else 1
|
|
530
|
+
dir = opts['shorten_from'][0]
|
|
531
|
+
elps = textwidth('...')[0]
|
|
532
|
+
if elps > uw:
|
|
533
|
+
self.is_shortened = True
|
|
534
|
+
if textwidth('..')[0] <= uw:
|
|
535
|
+
return '..'
|
|
536
|
+
else:
|
|
537
|
+
return '.'
|
|
538
|
+
uw -= elps
|
|
539
|
+
|
|
540
|
+
f = partial(text.find, c)
|
|
541
|
+
f_rev = partial(text.rfind, c)
|
|
542
|
+
# now find the first and last word
|
|
543
|
+
e1, s2 = f(), f_rev()
|
|
544
|
+
|
|
545
|
+
if dir != 'l': # center or right
|
|
546
|
+
# no split, or the first word doesn't even fit
|
|
547
|
+
if e1 != -1:
|
|
548
|
+
l1 = textwidth(text[:e1])[0]
|
|
549
|
+
l2 = textwidth(text[s2 + 1:])[0]
|
|
550
|
+
if e1 == -1 or l1 + l2 > uw:
|
|
551
|
+
self.is_shortened = True
|
|
552
|
+
if len(c):
|
|
553
|
+
opts['split_str'] = ''
|
|
554
|
+
res = self.shorten(text, margin)
|
|
555
|
+
opts['split_str'] = c
|
|
556
|
+
return res
|
|
557
|
+
# at this point we do char by char so e1 must be zero
|
|
558
|
+
if l1 <= uw:
|
|
559
|
+
return chr('{0}...').format(text[:e1])
|
|
560
|
+
return chr('...')
|
|
561
|
+
|
|
562
|
+
# both word fits, and there's at least on split_str
|
|
563
|
+
if s2 == e1: # there's only on split_str
|
|
564
|
+
self.is_shortened = True
|
|
565
|
+
return chr('{0}...{1}').format(text[:e1], text[s2 + 1:])
|
|
566
|
+
|
|
567
|
+
# both the first and last word fits, and they start/end at diff pos
|
|
568
|
+
if dir == 'r':
|
|
569
|
+
ee1 = f(e1 + 1)
|
|
570
|
+
while l2 + textwidth(text[:ee1])[0] <= uw:
|
|
571
|
+
e1 = ee1
|
|
572
|
+
if e1 == s2:
|
|
573
|
+
break
|
|
574
|
+
ee1 = f(e1 + 1)
|
|
575
|
+
else:
|
|
576
|
+
while True:
|
|
577
|
+
if l1 <= l2:
|
|
578
|
+
ee1 = f(e1 + 1)
|
|
579
|
+
l1 = textwidth(text[:ee1])[0]
|
|
580
|
+
if l2 + l1 > uw:
|
|
581
|
+
break
|
|
582
|
+
e1 = ee1
|
|
583
|
+
if e1 == s2:
|
|
584
|
+
break
|
|
585
|
+
else:
|
|
586
|
+
ss2 = f_rev(0, s2 - offset)
|
|
587
|
+
l2 = textwidth(text[ss2 + 1:])[0]
|
|
588
|
+
if l2 + l1 > uw:
|
|
589
|
+
break
|
|
590
|
+
s2 = ss2
|
|
591
|
+
if e1 == s2:
|
|
592
|
+
break
|
|
593
|
+
else: # left
|
|
594
|
+
# no split, or the last word doesn't even fit
|
|
595
|
+
if s2 != -1:
|
|
596
|
+
l2 = textwidth(text[s2 + (1 if len(c) else -1):])[0]
|
|
597
|
+
l1 = textwidth(text[:max(0, e1)])[0]
|
|
598
|
+
# if split_str
|
|
599
|
+
if s2 == -1 or l2 + l1 > uw:
|
|
600
|
+
self.is_shortened = True
|
|
601
|
+
if len(c):
|
|
602
|
+
opts['split_str'] = ''
|
|
603
|
+
res = self.shorten(text, margin)
|
|
604
|
+
opts['split_str'] = c
|
|
605
|
+
return res
|
|
606
|
+
|
|
607
|
+
return chr('...')
|
|
608
|
+
|
|
609
|
+
# both word fits, and there's at least on split_str
|
|
610
|
+
if s2 == e1: # there's only on split_str
|
|
611
|
+
self.is_shortened = True
|
|
612
|
+
return chr('{0}...{1}').format(text[:e1], text[s2 + 1:])
|
|
613
|
+
|
|
614
|
+
# both the first and last word fits, and they start/end at diff pos
|
|
615
|
+
ss2 = f_rev(0, s2 - offset)
|
|
616
|
+
while l1 + textwidth(text[ss2 + 1:])[0] <= uw:
|
|
617
|
+
s2 = ss2
|
|
618
|
+
if s2 == e1:
|
|
619
|
+
break
|
|
620
|
+
ss2 = f_rev(0, s2 - offset)
|
|
621
|
+
|
|
622
|
+
self.is_shortened = True
|
|
623
|
+
return chr('{0}...{1}').format(text[:e1], text[s2 + 1:])
|
|
624
|
+
|
|
625
|
+
def _default_line_options(self, lines):
|
|
626
|
+
for line in lines:
|
|
627
|
+
if len(line.words): # get opts from first line, first word
|
|
628
|
+
return line.words[0].options
|
|
629
|
+
return None
|
|
630
|
+
|
|
631
|
+
def clear_texture(self):
|
|
632
|
+
self._render_begin()
|
|
633
|
+
data = self._render_end()
|
|
634
|
+
assert data
|
|
635
|
+
if data is not None and data.width > 1:
|
|
636
|
+
self.texture.blit_data(data)
|
|
637
|
+
return
|
|
638
|
+
|
|
639
|
+
# FIXME: This should possibly use a Config value, and possibly we should
|
|
640
|
+
# expose pango_unichar_direction() / pango_bidi_type_for_unichar()
|
|
641
|
+
@staticmethod
|
|
642
|
+
def find_base_direction(text):
|
|
643
|
+
'''Searches a string the first character that has a strong direction,
|
|
644
|
+
according to the Unicode bidirectional algorithm. Returns `None` if
|
|
645
|
+
the base direction cannot be determined, or one of `'ltr'` or `'rtl'`.
|
|
646
|
+
|
|
647
|
+
.. versionadded: 1.10.1
|
|
648
|
+
|
|
649
|
+
.. note:: This feature requires the Pango text provider.
|
|
650
|
+
'''
|
|
651
|
+
return 'ltr'
|
|
652
|
+
|
|
653
|
+
def render_lines(self, lines, options, render_text, y, size):
|
|
654
|
+
get_extents = self.get_cached_extents()
|
|
655
|
+
uw, uh = options['text_size']
|
|
656
|
+
padding_left = options['padding'][0]
|
|
657
|
+
padding_right = options['padding'][2]
|
|
658
|
+
if uw is not None:
|
|
659
|
+
uww = uw - padding_left - padding_right # real width of just text
|
|
660
|
+
w = size[0]
|
|
661
|
+
sw = options['space_width']
|
|
662
|
+
halign = options['halign']
|
|
663
|
+
split = re.split
|
|
664
|
+
find_base_dir = self.find_base_direction
|
|
665
|
+
cur_base_dir = options['base_direction']
|
|
666
|
+
|
|
667
|
+
for layout_line in lines: # for plain label each line has only one str
|
|
668
|
+
lw, lh = layout_line.w, layout_line.h
|
|
669
|
+
line = ''
|
|
670
|
+
assert len(layout_line.words) < 2
|
|
671
|
+
if len(layout_line.words):
|
|
672
|
+
last_word = layout_line.words[0]
|
|
673
|
+
line = last_word.text
|
|
674
|
+
if not cur_base_dir:
|
|
675
|
+
cur_base_dir = find_base_dir(line)
|
|
676
|
+
x = padding_left
|
|
677
|
+
if halign == 'auto':
|
|
678
|
+
if cur_base_dir and 'rtl' in cur_base_dir:
|
|
679
|
+
# right-align RTL text
|
|
680
|
+
x = max(0, int(w - lw - padding_right))
|
|
681
|
+
elif halign == 'center':
|
|
682
|
+
x = min(
|
|
683
|
+
int(w - lw),
|
|
684
|
+
max(
|
|
685
|
+
int(padding_left),
|
|
686
|
+
int((w - lw + padding_left - padding_right) / 2.0)
|
|
687
|
+
)
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
elif halign == 'right':
|
|
691
|
+
x = max(0, int(w - lw - padding_right))
|
|
692
|
+
|
|
693
|
+
# right left justify
|
|
694
|
+
# divide left over space between `spaces`
|
|
695
|
+
# TODO implement a better method of stretching glyphs?
|
|
696
|
+
if (uw is not None and halign == 'justify' and line and not
|
|
697
|
+
layout_line.is_last_line):
|
|
698
|
+
# number spaces needed to fill, and remainder
|
|
699
|
+
n, rem = divmod(max(uww - lw, 0), sw)
|
|
700
|
+
n = int(n)
|
|
701
|
+
words = None
|
|
702
|
+
if n or rem:
|
|
703
|
+
# there's no trailing space when justify is selected
|
|
704
|
+
words = split(whitespace_pat, line)
|
|
705
|
+
if words is not None and len(words) > 1:
|
|
706
|
+
space = type(line)(' ')
|
|
707
|
+
# words: every even index is spaces, just add ltr n spaces
|
|
708
|
+
for i in range(n):
|
|
709
|
+
idx = (2 * i + 1) % (len(words) - 1)
|
|
710
|
+
words[idx] = words[idx] + space
|
|
711
|
+
if rem:
|
|
712
|
+
# render the last word at the edge, also add it to line
|
|
713
|
+
ext = get_extents(words[-1])
|
|
714
|
+
word = LayoutWord(last_word.options, ext[0], ext[1],
|
|
715
|
+
words[-1])
|
|
716
|
+
layout_line.words.append(word)
|
|
717
|
+
last_word.lw = uww - ext[0] # word was stretched
|
|
718
|
+
render_text(words[-1], x + last_word.lw, y)
|
|
719
|
+
last_word.text = line = ''.join(words[:-2])
|
|
720
|
+
else:
|
|
721
|
+
last_word.lw = uww # word was stretched
|
|
722
|
+
last_word.text = line = ''.join(words)
|
|
723
|
+
layout_line.w = uww # the line occupies full width
|
|
724
|
+
|
|
725
|
+
if len(line):
|
|
726
|
+
layout_line.x = x
|
|
727
|
+
layout_line.y = y
|
|
728
|
+
render_text(line, x, y)
|
|
729
|
+
y += lh
|
|
730
|
+
return y
|
|
731
|
+
|
|
732
|
+
def _render_real(self):
|
|
733
|
+
lines = self._cached_lines
|
|
734
|
+
options = self._default_line_options(lines)
|
|
735
|
+
if options is None: # there was no text to render
|
|
736
|
+
return self.clear_texture()
|
|
737
|
+
|
|
738
|
+
old_opts = self.options
|
|
739
|
+
ih = self._internal_size[1] # the real size of text, not texture
|
|
740
|
+
size = self.size
|
|
741
|
+
valign = options['valign']
|
|
742
|
+
|
|
743
|
+
padding_top = options['padding'][1]
|
|
744
|
+
if valign == 'bottom':
|
|
745
|
+
y = int(size[1] - ih + padding_top)
|
|
746
|
+
elif valign == 'top':
|
|
747
|
+
y = int(padding_top)
|
|
748
|
+
elif valign in ('middle', 'center'):
|
|
749
|
+
y = int((size[1] - ih + 2 * padding_top) / 2)
|
|
750
|
+
|
|
751
|
+
self._render_begin()
|
|
752
|
+
self.render_lines(lines, options, self._render_text, y, size)
|
|
753
|
+
|
|
754
|
+
# get data from provider
|
|
755
|
+
data = self._render_end()
|
|
756
|
+
assert data
|
|
757
|
+
self.options = old_opts
|
|
758
|
+
|
|
759
|
+
# If the text is 1px width, usually, the data is black.
|
|
760
|
+
# Don't blit that kind of data, otherwise, you have a little black bar.
|
|
761
|
+
if data is not None and data.width > 1:
|
|
762
|
+
self.texture.blit_data(data)
|
|
763
|
+
|
|
764
|
+
def render(self, real=False):
|
|
765
|
+
'''Return a tuple (width, height) to create the image
|
|
766
|
+
with the user constraints. (width, height) includes the padding.
|
|
767
|
+
'''
|
|
768
|
+
if real:
|
|
769
|
+
return self._render_real()
|
|
770
|
+
|
|
771
|
+
options = copy(self.options)
|
|
772
|
+
options['space_width'] = self.get_extents(' ')[0]
|
|
773
|
+
options['strip'] = strip = (options['strip'] or
|
|
774
|
+
options['halign'] == 'justify')
|
|
775
|
+
uw, uh = options['text_size'] = self._text_size
|
|
776
|
+
text = self.text
|
|
777
|
+
if strip:
|
|
778
|
+
text = text.strip()
|
|
779
|
+
|
|
780
|
+
self.is_shortened = False
|
|
781
|
+
if uw is not None and options['shorten']:
|
|
782
|
+
text = self.shorten(text)
|
|
783
|
+
|
|
784
|
+
self._cached_lines = lines = []
|
|
785
|
+
if not text:
|
|
786
|
+
return 0, 0
|
|
787
|
+
|
|
788
|
+
if uh is not None and (options['valign'] == 'middle' or
|
|
789
|
+
options['valign'] == 'center'):
|
|
790
|
+
center = -1 # pos of newline
|
|
791
|
+
if len(text) > 1:
|
|
792
|
+
middle = int(len(text) // 2)
|
|
793
|
+
l, r = text.rfind('\n', 0, middle), text.find('\n', middle)
|
|
794
|
+
if l != -1 and r != -1:
|
|
795
|
+
center = l if center - l <= r - center else r
|
|
796
|
+
elif l != -1:
|
|
797
|
+
center = l
|
|
798
|
+
elif r != -1:
|
|
799
|
+
center = r
|
|
800
|
+
# if a newline split text, render from center down and up til uh
|
|
801
|
+
if center != -1:
|
|
802
|
+
# layout from center down until half uh
|
|
803
|
+
w, h, clipped = layout_text(text[center + 1:], lines, (0, 0),
|
|
804
|
+
(uw, uh / 2), options, self.get_cached_extents(), True, True)
|
|
805
|
+
# now layout from center upwards until uh is reached
|
|
806
|
+
w, h, clipped = layout_text(text[:center + 1], lines, (w, h),
|
|
807
|
+
(uw, uh), options, self.get_cached_extents(), False, True)
|
|
808
|
+
else: # if there's no new line, layout everything
|
|
809
|
+
w, h, clipped = layout_text(text, lines, (0, 0), (uw, None),
|
|
810
|
+
options, self.get_cached_extents(), True, True)
|
|
811
|
+
else: # top or bottom
|
|
812
|
+
w, h, clipped = layout_text(text, lines, (0, 0), (uw, uh), options,
|
|
813
|
+
self.get_cached_extents(), options['valign'] == 'top', True)
|
|
814
|
+
self._internal_size = w, h
|
|
815
|
+
if uw:
|
|
816
|
+
w = uw
|
|
817
|
+
if uh:
|
|
818
|
+
h = uh
|
|
819
|
+
if h > 1 and w < 2:
|
|
820
|
+
w = 2
|
|
821
|
+
return int(w), int(h)
|
|
822
|
+
|
|
823
|
+
def _texture_refresh(self, *l):
|
|
824
|
+
self.refresh()
|
|
825
|
+
|
|
826
|
+
def _texture_fill(self, texture):
|
|
827
|
+
# second pass, render for real
|
|
828
|
+
self.render(real=True)
|
|
829
|
+
|
|
830
|
+
def refresh(self):
|
|
831
|
+
'''Force re-rendering of the text
|
|
832
|
+
'''
|
|
833
|
+
self.resolve_font_name()
|
|
834
|
+
|
|
835
|
+
# first pass, calculating width/height
|
|
836
|
+
sz = self.render()
|
|
837
|
+
self._size_texture = sz
|
|
838
|
+
self._size = (sz[0], sz[1])
|
|
839
|
+
|
|
840
|
+
# if no text are rendered, return nothing.
|
|
841
|
+
width, height = self._size
|
|
842
|
+
if width <= 1 or height <= 1:
|
|
843
|
+
self.texture = self.texture_1px
|
|
844
|
+
return
|
|
845
|
+
|
|
846
|
+
# create a delayed texture
|
|
847
|
+
texture = self.texture
|
|
848
|
+
if texture is None or \
|
|
849
|
+
width != texture.width or \
|
|
850
|
+
height != texture.height:
|
|
851
|
+
texture = Texture.create(size=(width, height),
|
|
852
|
+
mipmap=self.options['mipmap'],
|
|
853
|
+
callback=self._texture_fill)
|
|
854
|
+
texture.flip_vertical()
|
|
855
|
+
texture.add_reload_observer(self._texture_refresh)
|
|
856
|
+
self.texture = texture
|
|
857
|
+
else:
|
|
858
|
+
texture.ask_update(self._texture_fill)
|
|
859
|
+
|
|
860
|
+
def _get_text(self):
|
|
861
|
+
return self._text
|
|
862
|
+
|
|
863
|
+
def _set_text(self, text):
|
|
864
|
+
if text != self._text:
|
|
865
|
+
self._text = text
|
|
866
|
+
|
|
867
|
+
text = property(_get_text, _set_text, doc='Get/Set the text')
|
|
868
|
+
label = property(_get_text, _set_text, doc='Get/Set the text')
|
|
869
|
+
|
|
870
|
+
@property
|
|
871
|
+
def texture_1px(self):
|
|
872
|
+
if LabelBase._texture_1px is None:
|
|
873
|
+
tex = Texture.create(size=(1, 1), colorfmt='rgba')
|
|
874
|
+
tex.blit_buffer(b'\x00\x00\x00\x00', colorfmt='rgba')
|
|
875
|
+
LabelBase._texture_1px = tex
|
|
876
|
+
return LabelBase._texture_1px
|
|
877
|
+
|
|
878
|
+
@property
|
|
879
|
+
def size(self):
|
|
880
|
+
return self._size
|
|
881
|
+
|
|
882
|
+
@property
|
|
883
|
+
def width(self):
|
|
884
|
+
return self._size[0]
|
|
885
|
+
|
|
886
|
+
@property
|
|
887
|
+
def height(self):
|
|
888
|
+
return self._size[1]
|
|
889
|
+
|
|
890
|
+
@property
|
|
891
|
+
def content_width(self):
|
|
892
|
+
'''Return the content width; i.e. the width of the text without
|
|
893
|
+
any padding.'''
|
|
894
|
+
if self.texture is None:
|
|
895
|
+
return 0
|
|
896
|
+
return self.texture.width - (
|
|
897
|
+
self.options['padding'][0] + self.options['padding'][2]
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
@property
|
|
901
|
+
def content_height(self):
|
|
902
|
+
'''Return the content height; i.e. the height of the text without
|
|
903
|
+
any padding.'''
|
|
904
|
+
if self.texture is None:
|
|
905
|
+
return 0
|
|
906
|
+
return self.texture.height - (
|
|
907
|
+
self.options['padding'][1] + self.options['padding'][3]
|
|
908
|
+
)
|
|
909
|
+
|
|
910
|
+
@property
|
|
911
|
+
def content_size(self):
|
|
912
|
+
'''Return the content size (width, height)'''
|
|
913
|
+
if self.texture is None:
|
|
914
|
+
return (0, 0)
|
|
915
|
+
return (self.content_width, self.content_height)
|
|
916
|
+
|
|
917
|
+
@property
|
|
918
|
+
def fontid(self):
|
|
919
|
+
'''Return a unique id for all font parameters'''
|
|
920
|
+
return str([self.options[x] for x in (
|
|
921
|
+
'font_size', 'font_name_r', 'bold',
|
|
922
|
+
'italic', 'underline', 'strikethrough')])
|
|
923
|
+
|
|
924
|
+
def _get_text_size(self):
|
|
925
|
+
return self._text_size
|
|
926
|
+
|
|
927
|
+
def _set_text_size(self, x):
|
|
928
|
+
self._text_size = x
|
|
929
|
+
|
|
930
|
+
text_size = property(_get_text_size, _set_text_size,
|
|
931
|
+
doc='''Get/set the (width, height) of the '
|
|
932
|
+
'contrained rendering box''')
|
|
933
|
+
|
|
934
|
+
usersize = property(_get_text_size, _set_text_size,
|
|
935
|
+
doc='''(deprecated) Use text_size instead.''')
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
class FontContextManagerBase(object):
|
|
939
|
+
@staticmethod
|
|
940
|
+
def create(font_context):
|
|
941
|
+
'''Create a font context, you must specify a unique name (string).
|
|
942
|
+
Returns `True` on success and `False` on failure.
|
|
943
|
+
|
|
944
|
+
If `font_context` starts with one of the reserved words `'system://'`,
|
|
945
|
+
`'directory://'`, `'fontconfig://'` or `'systemconfig://'`, the context
|
|
946
|
+
is setup accordingly (exact results of this depends on your platform,
|
|
947
|
+
environment and configuration).
|
|
948
|
+
|
|
949
|
+
* `'system://'` loads the default system's FontConfig configuration
|
|
950
|
+
and all fonts (usually including user fonts).
|
|
951
|
+
* `directory://` contexts preload a directory of font files (specified
|
|
952
|
+
in the context name), `systemconfig://` loads the system's FontConfig
|
|
953
|
+
configuration (but no fonts), and `fontconfig://` loads FontConfig
|
|
954
|
+
configuration file (specified in the context name!). These are for
|
|
955
|
+
advanced users only, check the source code and FontConfig
|
|
956
|
+
documentation for details.
|
|
957
|
+
* Fonts automatically loaded to an isolated context (ie when no
|
|
958
|
+
font context was specified) start with `'isolated://'`. This has
|
|
959
|
+
no special effect, and only serves to help you identify them in
|
|
960
|
+
the results returned from :meth:`list`.
|
|
961
|
+
* Any other string is a context that will only draw with the font
|
|
962
|
+
file(s) you explicitly add to it.
|
|
963
|
+
|
|
964
|
+
.. versionadded:: 1.11.0
|
|
965
|
+
|
|
966
|
+
.. note::
|
|
967
|
+
Font contexts are created automatically by specifying a name in the
|
|
968
|
+
`font_context` property of :class:`kivy.uix.label.Label` or
|
|
969
|
+
:class:`kivy.uix.textinput.TextInput`. They are also auto-created
|
|
970
|
+
by :meth:`add_font` by default, so you normally don't need to
|
|
971
|
+
call this directly.
|
|
972
|
+
|
|
973
|
+
.. note:: This feature requires the Pango text provider.
|
|
974
|
+
'''
|
|
975
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
976
|
+
|
|
977
|
+
@staticmethod
|
|
978
|
+
def exists(font_context):
|
|
979
|
+
'''Returns True if a font context with the given name exists.
|
|
980
|
+
|
|
981
|
+
.. versionadded:: 1.11.0
|
|
982
|
+
|
|
983
|
+
.. note:: This feature requires the Pango text provider.
|
|
984
|
+
'''
|
|
985
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
986
|
+
|
|
987
|
+
@staticmethod
|
|
988
|
+
def destroy(font_context):
|
|
989
|
+
'''Destroy a named font context (if it exists)
|
|
990
|
+
|
|
991
|
+
.. versionadded:: 1.11.0
|
|
992
|
+
|
|
993
|
+
.. note:: This feature requires the Pango text provider.
|
|
994
|
+
'''
|
|
995
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
996
|
+
|
|
997
|
+
@staticmethod
|
|
998
|
+
def list():
|
|
999
|
+
'''Returns a list of `bytes` objects, each representing a cached font
|
|
1000
|
+
context name. Note that entries that start with `isolated://` were
|
|
1001
|
+
autocreated by loading a font file with no font_context specified.
|
|
1002
|
+
|
|
1003
|
+
.. versionadded:: 1.11.0
|
|
1004
|
+
|
|
1005
|
+
.. note:: This feature requires the Pango text provider.
|
|
1006
|
+
'''
|
|
1007
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
1008
|
+
|
|
1009
|
+
@staticmethod
|
|
1010
|
+
def list_families(font_context):
|
|
1011
|
+
'''Returns a list of `bytes` objects, each representing a font family
|
|
1012
|
+
name that is available in the given `font_context`.
|
|
1013
|
+
|
|
1014
|
+
.. versionadded:: 1.11.0
|
|
1015
|
+
|
|
1016
|
+
.. note::
|
|
1017
|
+
Pango adds static "Serif", "Sans" and "Monospace" to the list in
|
|
1018
|
+
current versions, even if only a single custom font file is added
|
|
1019
|
+
to the context.
|
|
1020
|
+
|
|
1021
|
+
.. note:: This feature requires the Pango text provider.
|
|
1022
|
+
'''
|
|
1023
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
1024
|
+
|
|
1025
|
+
@staticmethod
|
|
1026
|
+
def list_custom(font_context):
|
|
1027
|
+
'''Returns a dictionary representing all the custom-loaded fonts in
|
|
1028
|
+
the context. The key is a `bytes` object representing the full path
|
|
1029
|
+
to the font file, the value is a `bytes` object representing the font
|
|
1030
|
+
family name used to request drawing with the font.
|
|
1031
|
+
|
|
1032
|
+
.. versionadded:: 1.11.0
|
|
1033
|
+
|
|
1034
|
+
.. note:: This feature requires the Pango text provider.
|
|
1035
|
+
'''
|
|
1036
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
1037
|
+
|
|
1038
|
+
@staticmethod
|
|
1039
|
+
def add_font(font_context, filename, autocreate=True, family=None):
|
|
1040
|
+
'''Add a font file to a named font context. If `autocreate` is true,
|
|
1041
|
+
the context will be created if it does not exist (this is the
|
|
1042
|
+
default). You can specify the `family` argument (string) to skip
|
|
1043
|
+
auto-detecting the font family name.
|
|
1044
|
+
|
|
1045
|
+
.. warning::
|
|
1046
|
+
|
|
1047
|
+
The `family` argument is slated for removal if the underlying
|
|
1048
|
+
implementation can be fixed, It is offered as a way to optimize
|
|
1049
|
+
startup time for deployed applications (it avoids opening the
|
|
1050
|
+
file with FreeType2 to determine its family name). To use this,
|
|
1051
|
+
first load the font file without specifying `family`, and
|
|
1052
|
+
hardcode the returned (autodetected) `family` value in your font
|
|
1053
|
+
context initialization.
|
|
1054
|
+
|
|
1055
|
+
.. versionadded:: 1.11.0
|
|
1056
|
+
|
|
1057
|
+
.. note:: This feature requires the Pango text provider.
|
|
1058
|
+
'''
|
|
1059
|
+
raise NotImplementedError("No font_context support in text provider")
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
# Load the appropriate provider
|
|
1063
|
+
label_libs = []
|
|
1064
|
+
if USE_PANGOFT2:
|
|
1065
|
+
label_libs += [('pango', 'text_pango', 'LabelPango')]
|
|
1066
|
+
|
|
1067
|
+
if USE_SDL2:
|
|
1068
|
+
label_libs += [('sdl2', 'text_sdl2', 'LabelSDL2')]
|
|
1069
|
+
else:
|
|
1070
|
+
label_libs += [('pygame', 'text_pygame', 'LabelPygame')]
|
|
1071
|
+
label_libs += [
|
|
1072
|
+
('pil', 'text_pil', 'LabelPIL')]
|
|
1073
|
+
Text = Label = core_select_lib('text', label_libs)
|
|
1074
|
+
|
|
1075
|
+
if 'KIVY_DOC' not in os.environ:
|
|
1076
|
+
if not Label:
|
|
1077
|
+
import sys
|
|
1078
|
+
Logger.critical('App: Unable to get a Text provider, abort.')
|
|
1079
|
+
sys.exit(1)
|
|
1080
|
+
|
|
1081
|
+
# FIXME: Better way to do this
|
|
1082
|
+
if Label.__name__ == 'LabelPango':
|
|
1083
|
+
from kivy.core.text.text_pango import PangoFontContextManager
|
|
1084
|
+
FontContextManager = PangoFontContextManager()
|
|
1085
|
+
else:
|
|
1086
|
+
FontContextManager = FontContextManagerBase()
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
# For the first initialization, register the default font
|
|
1090
|
+
Label.register(DEFAULT_FONT, *_default_font_paths)
|