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/core/text/markup.py
ADDED
|
@@ -0,0 +1,893 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Text Markup
|
|
3
|
+
===========
|
|
4
|
+
|
|
5
|
+
.. versionadded:: 1.1.0
|
|
6
|
+
|
|
7
|
+
.. versionchanged:: 1.10.1
|
|
8
|
+
|
|
9
|
+
Added `font_context`, `font_features` and `text_language` (Pango only)
|
|
10
|
+
|
|
11
|
+
We provide a simple text-markup for inline text styling. The syntax look the
|
|
12
|
+
same as the `BBCode <http://en.wikipedia.org/wiki/BBCode>`_.
|
|
13
|
+
|
|
14
|
+
A tag is defined as ``[tag]``, and should have a corresponding
|
|
15
|
+
``[/tag]`` closing tag. For example::
|
|
16
|
+
|
|
17
|
+
[b]Hello [color=ff0000]world[/color][/b]
|
|
18
|
+
|
|
19
|
+
The following tags are available:
|
|
20
|
+
|
|
21
|
+
``[b][/b]``
|
|
22
|
+
Activate bold text
|
|
23
|
+
``[i][/i]``
|
|
24
|
+
Activate italic text
|
|
25
|
+
``[u][/u]``
|
|
26
|
+
Underlined text
|
|
27
|
+
``[s][/s]``
|
|
28
|
+
Strikethrough text
|
|
29
|
+
``[font=<str>][/font]``
|
|
30
|
+
Change the font (note: this refers to a TTF file or registered alias)
|
|
31
|
+
``[font_context=<str>][/font_context]``
|
|
32
|
+
Change context for the font, use string value "none" for isolated context.
|
|
33
|
+
``[font_family=<str>][/font_family]``
|
|
34
|
+
Font family to request for drawing. This is only valid when using a
|
|
35
|
+
font context, and takes precedence over `[font]`. See
|
|
36
|
+
:class:`kivy.uix.label.Label` for details.
|
|
37
|
+
``[font_features=<str>][/font_features]``
|
|
38
|
+
OpenType font features, in CSS format, this is passed straight
|
|
39
|
+
through to Pango. The effects of requesting a feature depends on loaded
|
|
40
|
+
fonts, library versions, etc. Pango only, requires v1.38 or later.
|
|
41
|
+
``[size=<size>][/size]``
|
|
42
|
+
Change the font size. <size> should be an integer, optionally with a
|
|
43
|
+
unit (i.e. ``16sp``)
|
|
44
|
+
``[color=#<color>][/color]``
|
|
45
|
+
Change the text color
|
|
46
|
+
``[ref=<str>][/ref]``
|
|
47
|
+
Add an interactive zone. The reference + all the word box inside the
|
|
48
|
+
reference will be available in :attr:`MarkupLabel.refs`
|
|
49
|
+
``[anchor=<str>]``
|
|
50
|
+
Put an anchor in the text. You can get the position of your anchor within
|
|
51
|
+
the text with :attr:`MarkupLabel.anchors`
|
|
52
|
+
``[sub][/sub]``
|
|
53
|
+
Display the text at a subscript position relative to the text before it.
|
|
54
|
+
``[sup][/sup]``
|
|
55
|
+
Display the text at a superscript position relative to the text before it.
|
|
56
|
+
``[text_language=<str>][/text_language]``
|
|
57
|
+
Language of the text, this is an RFC-3066 format language tag (as string),
|
|
58
|
+
for example "en_US", "zh_CN", "fr" or "ja". This can impact font selection,
|
|
59
|
+
metrics and rendering. For example, the same bytes of text can look
|
|
60
|
+
different for `ur` and `ar` languages, though both use Arabic script.
|
|
61
|
+
Use the string `'none'` to revert to locale detection. Pango only.
|
|
62
|
+
|
|
63
|
+
If you need to escape the markup from the current text, use
|
|
64
|
+
:func:`kivy.utils.escape_markup`.
|
|
65
|
+
'''
|
|
66
|
+
|
|
67
|
+
__all__ = ('MarkupLabel', )
|
|
68
|
+
|
|
69
|
+
import re
|
|
70
|
+
from kivy.properties import dpi2px
|
|
71
|
+
from kivy.parser import parse_color
|
|
72
|
+
from kivy.logger import Logger
|
|
73
|
+
from kivy.core.text import Label, LabelBase
|
|
74
|
+
from kivy.core.text.text_layout import layout_text, LayoutWord, LayoutLine
|
|
75
|
+
from copy import copy
|
|
76
|
+
from functools import partial
|
|
77
|
+
|
|
78
|
+
# We need to do this trick when documentation is generated
|
|
79
|
+
MarkupLabelBase = Label
|
|
80
|
+
if Label is None:
|
|
81
|
+
MarkupLabelBase = LabelBase
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class MarkupLabel(MarkupLabelBase):
|
|
85
|
+
'''Markup text label.
|
|
86
|
+
|
|
87
|
+
See module documentation for more information.
|
|
88
|
+
'''
|
|
89
|
+
|
|
90
|
+
def __init__(self, *largs, **kwargs):
|
|
91
|
+
self._style_stack = {}
|
|
92
|
+
self._refs = {}
|
|
93
|
+
self._anchors = {}
|
|
94
|
+
super(MarkupLabel, self).__init__(*largs, **kwargs)
|
|
95
|
+
self._internal_size = 0, 0
|
|
96
|
+
self._cached_lines = []
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def refs(self):
|
|
100
|
+
'''Get the bounding box of all the ``[ref=...]``::
|
|
101
|
+
|
|
102
|
+
{ 'refA': ((x1, y1, x2, y2), (x1, y1, x2, y2)), ... }
|
|
103
|
+
'''
|
|
104
|
+
return self._refs
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def anchors(self):
|
|
108
|
+
'''Get the position of all the ``[anchor=...]``::
|
|
109
|
+
|
|
110
|
+
{ 'anchorA': (x, y), 'anchorB': (x, y), ... }
|
|
111
|
+
'''
|
|
112
|
+
return self._anchors
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def markup(self):
|
|
116
|
+
'''Return the text with all the markup split::
|
|
117
|
+
|
|
118
|
+
>>> MarkupLabel('[b]Hello world[/b]').markup
|
|
119
|
+
>>> ('[b]', 'Hello world', '[/b]')
|
|
120
|
+
|
|
121
|
+
'''
|
|
122
|
+
s = re.split(r'(\[.*?\])', self.label)
|
|
123
|
+
s = [x for x in s if x != '']
|
|
124
|
+
return s
|
|
125
|
+
|
|
126
|
+
def _push_style(self, k):
|
|
127
|
+
if k not in self._style_stack:
|
|
128
|
+
self._style_stack[k] = []
|
|
129
|
+
self._style_stack[k].append(self.options[k])
|
|
130
|
+
|
|
131
|
+
def _pop_style(self, k):
|
|
132
|
+
if k not in self._style_stack or len(self._style_stack[k]) == 0:
|
|
133
|
+
Logger.warning('Label: pop style stack without push')
|
|
134
|
+
return
|
|
135
|
+
v = self._style_stack[k].pop()
|
|
136
|
+
self.options[k] = v
|
|
137
|
+
|
|
138
|
+
def render(self, real=False):
|
|
139
|
+
options = copy(self.options)
|
|
140
|
+
if not real:
|
|
141
|
+
ret = self._pre_render()
|
|
142
|
+
else:
|
|
143
|
+
ret = self._render_real()
|
|
144
|
+
self.options = options
|
|
145
|
+
return ret
|
|
146
|
+
|
|
147
|
+
def _pre_render(self):
|
|
148
|
+
# split markup, words, and lines
|
|
149
|
+
# result: list of word with position and width/height
|
|
150
|
+
# during the first pass, we don't care about h/valign
|
|
151
|
+
self._cached_lines = lines = []
|
|
152
|
+
self._refs = {}
|
|
153
|
+
self._anchors = {}
|
|
154
|
+
clipped = False
|
|
155
|
+
w = h = 0
|
|
156
|
+
uw, uh = self.text_size
|
|
157
|
+
spush = self._push_style
|
|
158
|
+
spop = self._pop_style
|
|
159
|
+
options = self.options
|
|
160
|
+
options['_ref'] = None
|
|
161
|
+
options['_anchor'] = None
|
|
162
|
+
options['script'] = 'normal'
|
|
163
|
+
shorten = options['shorten']
|
|
164
|
+
# if shorten, then don't split lines to fit uw, because it will be
|
|
165
|
+
# flattened later when shortening and broken up lines if broken
|
|
166
|
+
# mid-word will have space mid-word when lines are joined
|
|
167
|
+
uw_temp = None if shorten else uw
|
|
168
|
+
xpad = options['padding'][0] + options['padding'][2]
|
|
169
|
+
uhh = (None if uh is not None and options['valign'] != 'top' or
|
|
170
|
+
options['shorten'] else uh)
|
|
171
|
+
options['strip'] = options['strip'] or options['halign'] == 'justify'
|
|
172
|
+
find_base_dir = Label.find_base_direction
|
|
173
|
+
base_dir = options['base_direction']
|
|
174
|
+
self._resolved_base_dir = None
|
|
175
|
+
for item in self.markup:
|
|
176
|
+
if item == '[b]':
|
|
177
|
+
spush('bold')
|
|
178
|
+
options['bold'] = True
|
|
179
|
+
self.resolve_font_name()
|
|
180
|
+
elif item == '[/b]':
|
|
181
|
+
spop('bold')
|
|
182
|
+
self.resolve_font_name()
|
|
183
|
+
elif item == '[i]':
|
|
184
|
+
spush('italic')
|
|
185
|
+
options['italic'] = True
|
|
186
|
+
self.resolve_font_name()
|
|
187
|
+
elif item == '[/i]':
|
|
188
|
+
spop('italic')
|
|
189
|
+
self.resolve_font_name()
|
|
190
|
+
elif item == '[u]':
|
|
191
|
+
spush('underline')
|
|
192
|
+
options['underline'] = True
|
|
193
|
+
self.resolve_font_name()
|
|
194
|
+
elif item == '[/u]':
|
|
195
|
+
spop('underline')
|
|
196
|
+
self.resolve_font_name()
|
|
197
|
+
elif item == '[s]':
|
|
198
|
+
spush('strikethrough')
|
|
199
|
+
options['strikethrough'] = True
|
|
200
|
+
self.resolve_font_name()
|
|
201
|
+
elif item == '[/s]':
|
|
202
|
+
spop('strikethrough')
|
|
203
|
+
self.resolve_font_name()
|
|
204
|
+
elif item[:6] == '[size=':
|
|
205
|
+
item = item[6:-1]
|
|
206
|
+
try:
|
|
207
|
+
if item[-2:] in ('px', 'pt', 'in', 'cm', 'mm', 'dp', 'sp'):
|
|
208
|
+
size = dpi2px(item[:-2], item[-2:])
|
|
209
|
+
else:
|
|
210
|
+
size = int(item)
|
|
211
|
+
except ValueError:
|
|
212
|
+
raise
|
|
213
|
+
size = options['font_size']
|
|
214
|
+
spush('font_size')
|
|
215
|
+
options['font_size'] = size
|
|
216
|
+
elif item == '[/size]':
|
|
217
|
+
spop('font_size')
|
|
218
|
+
elif item[:7] == '[color=':
|
|
219
|
+
color = parse_color(item[7:-1])
|
|
220
|
+
spush('color')
|
|
221
|
+
options['color'] = color
|
|
222
|
+
elif item == '[/color]':
|
|
223
|
+
spop('color')
|
|
224
|
+
elif item[:6] == '[font=':
|
|
225
|
+
fontname = item[6:-1]
|
|
226
|
+
spush('font_name')
|
|
227
|
+
options['font_name'] = fontname
|
|
228
|
+
self.resolve_font_name()
|
|
229
|
+
elif item == '[/font]':
|
|
230
|
+
spop('font_name')
|
|
231
|
+
self.resolve_font_name()
|
|
232
|
+
elif item[:13] == '[font_family=':
|
|
233
|
+
spush('font_family')
|
|
234
|
+
options['font_family'] = item[13:-1]
|
|
235
|
+
elif item == '[/font_family]':
|
|
236
|
+
spop('font_family')
|
|
237
|
+
elif item[:14] == '[font_context=':
|
|
238
|
+
fctx = item[14:-1]
|
|
239
|
+
if not fctx or fctx.lower() == 'none':
|
|
240
|
+
fctx = None
|
|
241
|
+
spush('font_context')
|
|
242
|
+
options['font_context'] = fctx
|
|
243
|
+
elif item == '[/font_context]':
|
|
244
|
+
spop('font_context')
|
|
245
|
+
elif item[:15] == '[font_features=':
|
|
246
|
+
spush('font_features')
|
|
247
|
+
options['font_features'] = item[15:-1]
|
|
248
|
+
elif item == '[/font_features]':
|
|
249
|
+
spop('font_features')
|
|
250
|
+
elif item[:15] == '[text_language=':
|
|
251
|
+
lang = item[15:-1]
|
|
252
|
+
if not lang or lang.lower() == 'none':
|
|
253
|
+
lang = None
|
|
254
|
+
spush('text_language')
|
|
255
|
+
options['text_language'] = lang
|
|
256
|
+
elif item == '[/text_language]':
|
|
257
|
+
spop('text_language')
|
|
258
|
+
elif item[:5] == '[sub]':
|
|
259
|
+
spush('font_size')
|
|
260
|
+
spush('script')
|
|
261
|
+
options['font_size'] = options['font_size'] * .5
|
|
262
|
+
options['script'] = 'subscript'
|
|
263
|
+
elif item == '[/sub]':
|
|
264
|
+
spop('font_size')
|
|
265
|
+
spop('script')
|
|
266
|
+
elif item[:5] == '[sup]':
|
|
267
|
+
spush('font_size')
|
|
268
|
+
spush('script')
|
|
269
|
+
options['font_size'] = options['font_size'] * .5
|
|
270
|
+
options['script'] = 'superscript'
|
|
271
|
+
elif item == '[/sup]':
|
|
272
|
+
spop('font_size')
|
|
273
|
+
spop('script')
|
|
274
|
+
elif item[:5] == '[ref=':
|
|
275
|
+
ref = item[5:-1]
|
|
276
|
+
spush('_ref')
|
|
277
|
+
options['_ref'] = ref
|
|
278
|
+
elif item == '[/ref]':
|
|
279
|
+
spop('_ref')
|
|
280
|
+
elif not clipped and item[:8] == '[anchor=':
|
|
281
|
+
options['_anchor'] = item[8:-1]
|
|
282
|
+
elif not clipped:
|
|
283
|
+
item = item.replace('&bl;', '[').replace(
|
|
284
|
+
'&br;', ']').replace('&', '&')
|
|
285
|
+
if not base_dir:
|
|
286
|
+
base_dir = self._resolved_base_dir = find_base_dir(item)
|
|
287
|
+
opts = copy(options)
|
|
288
|
+
extents = self.get_cached_extents()
|
|
289
|
+
opts['space_width'] = extents(' ')[0]
|
|
290
|
+
w, h, clipped = layout_text(
|
|
291
|
+
item, lines, (w, h), (uw_temp, uhh),
|
|
292
|
+
opts, extents,
|
|
293
|
+
append_down=True,
|
|
294
|
+
complete=False
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
if len(lines): # remove any trailing spaces from the last line
|
|
298
|
+
old_opts = self.options
|
|
299
|
+
self.options = copy(opts)
|
|
300
|
+
w, h, clipped = layout_text(
|
|
301
|
+
'', lines, (w, h), (uw_temp, uhh),
|
|
302
|
+
self.options, self.get_cached_extents(),
|
|
303
|
+
append_down=True,
|
|
304
|
+
complete=True
|
|
305
|
+
)
|
|
306
|
+
self.options = old_opts
|
|
307
|
+
|
|
308
|
+
self.is_shortened = False
|
|
309
|
+
if shorten:
|
|
310
|
+
options['_ref'] = None # no refs for you!
|
|
311
|
+
options['_anchor'] = None
|
|
312
|
+
w, h, lines = self.shorten_post(lines, w, h)
|
|
313
|
+
self._cached_lines = lines
|
|
314
|
+
# when valign is not top, for markup we layout everything (text_size[1]
|
|
315
|
+
# is temporarily set to None) and after layout cut to size if too tall
|
|
316
|
+
elif uh != uhh and h > uh and len(lines) > 1:
|
|
317
|
+
if options['valign'] == 'bottom':
|
|
318
|
+
i = 0
|
|
319
|
+
while i < len(lines) - 1 and h > uh:
|
|
320
|
+
h -= lines[i].h
|
|
321
|
+
i += 1
|
|
322
|
+
del lines[:i]
|
|
323
|
+
else: # middle
|
|
324
|
+
i = 0
|
|
325
|
+
top = int(h / 2. + uh / 2.) # remove extra top portion
|
|
326
|
+
while i < len(lines) - 1 and h > top:
|
|
327
|
+
h -= lines[i].h
|
|
328
|
+
i += 1
|
|
329
|
+
del lines[:i]
|
|
330
|
+
i = len(lines) - 1 # remove remaining bottom portion
|
|
331
|
+
while i and h > uh:
|
|
332
|
+
h -= lines[i].h
|
|
333
|
+
i -= 1
|
|
334
|
+
del lines[i + 1:]
|
|
335
|
+
|
|
336
|
+
# now justify the text
|
|
337
|
+
if options['halign'] == 'justify' and uw is not None:
|
|
338
|
+
# XXX: update refs to justified pos
|
|
339
|
+
# when justify, each line should've been stripped already
|
|
340
|
+
split = partial(re.split, re.compile('( +)'))
|
|
341
|
+
uww = uw - xpad
|
|
342
|
+
chr = type(self.text)
|
|
343
|
+
space = chr(' ')
|
|
344
|
+
empty = chr('')
|
|
345
|
+
|
|
346
|
+
for i in range(len(lines)):
|
|
347
|
+
line = lines[i]
|
|
348
|
+
words = line.words
|
|
349
|
+
# if there's nothing to justify, we're done
|
|
350
|
+
if (not line.w or int(uww - line.w) <= 0 or not len(words) or
|
|
351
|
+
line.is_last_line):
|
|
352
|
+
continue
|
|
353
|
+
|
|
354
|
+
done = False
|
|
355
|
+
parts = [None, ] * len(words) # contains words split by space
|
|
356
|
+
idxs = [None, ] * len(words) # indices of the space in parts
|
|
357
|
+
# break each word into spaces and add spaces until it's full
|
|
358
|
+
# do first round of split in case we don't need to split all
|
|
359
|
+
for w in range(len(words)):
|
|
360
|
+
word = words[w]
|
|
361
|
+
sw = word.options['space_width']
|
|
362
|
+
p = parts[w] = split(word.text)
|
|
363
|
+
idxs[w] = [v for v in range(len(p)) if
|
|
364
|
+
p[v].startswith(' ')]
|
|
365
|
+
# now we have the indices of the spaces in split list
|
|
366
|
+
for k in idxs[w]:
|
|
367
|
+
# try to add single space at each space
|
|
368
|
+
if line.w + sw > uww:
|
|
369
|
+
done = True
|
|
370
|
+
break
|
|
371
|
+
line.w += sw
|
|
372
|
+
word.lw += sw
|
|
373
|
+
p[k] += space
|
|
374
|
+
if done:
|
|
375
|
+
break
|
|
376
|
+
|
|
377
|
+
# there's not a single space in the line?
|
|
378
|
+
if not any(idxs):
|
|
379
|
+
continue
|
|
380
|
+
|
|
381
|
+
# now keep adding spaces to already split words until done
|
|
382
|
+
while not done:
|
|
383
|
+
for w in range(len(words)):
|
|
384
|
+
if not idxs[w]:
|
|
385
|
+
continue
|
|
386
|
+
word = words[w]
|
|
387
|
+
sw = word.options['space_width']
|
|
388
|
+
p = parts[w]
|
|
389
|
+
for k in idxs[w]:
|
|
390
|
+
# try to add single space at each space
|
|
391
|
+
if line.w + sw > uww:
|
|
392
|
+
done = True
|
|
393
|
+
break
|
|
394
|
+
line.w += sw
|
|
395
|
+
word.lw += sw
|
|
396
|
+
p[k] += space
|
|
397
|
+
if done:
|
|
398
|
+
break
|
|
399
|
+
|
|
400
|
+
# if not completely full, push last words to right edge
|
|
401
|
+
diff = int(uww - line.w)
|
|
402
|
+
if diff > 0:
|
|
403
|
+
# find the last word that had a space
|
|
404
|
+
for w in range(len(words) - 1, -1, -1):
|
|
405
|
+
if not idxs[w]:
|
|
406
|
+
continue
|
|
407
|
+
break
|
|
408
|
+
old_opts = self.options
|
|
409
|
+
self.options = word.options
|
|
410
|
+
word = words[w]
|
|
411
|
+
# split that word into left/right and push right till uww
|
|
412
|
+
l_text = empty.join(parts[w][:idxs[w][-1]])
|
|
413
|
+
r_text = empty.join(parts[w][idxs[w][-1]:])
|
|
414
|
+
left = LayoutWord(
|
|
415
|
+
word.options,
|
|
416
|
+
self.get_extents(l_text)[0],
|
|
417
|
+
word.lh,
|
|
418
|
+
l_text
|
|
419
|
+
)
|
|
420
|
+
right = LayoutWord(
|
|
421
|
+
word.options,
|
|
422
|
+
self.get_extents(r_text)[0],
|
|
423
|
+
word.lh,
|
|
424
|
+
r_text
|
|
425
|
+
)
|
|
426
|
+
left.lw = max(left.lw, word.lw + diff - right.lw)
|
|
427
|
+
self.options = old_opts
|
|
428
|
+
|
|
429
|
+
# now put words back together with right/left inserted
|
|
430
|
+
for k in range(len(words)):
|
|
431
|
+
if idxs[k]:
|
|
432
|
+
words[k].text = empty.join(parts[k])
|
|
433
|
+
words[w] = right
|
|
434
|
+
words.insert(w, left)
|
|
435
|
+
else:
|
|
436
|
+
for k in range(len(words)):
|
|
437
|
+
if idxs[k]:
|
|
438
|
+
words[k].text = empty.join(parts[k])
|
|
439
|
+
line.w = uww
|
|
440
|
+
w = max(w, uww)
|
|
441
|
+
|
|
442
|
+
self._internal_size = w, h
|
|
443
|
+
if uw:
|
|
444
|
+
w = uw
|
|
445
|
+
if uh:
|
|
446
|
+
h = uh
|
|
447
|
+
if h > 1 and w < 2:
|
|
448
|
+
w = 2
|
|
449
|
+
if w < 1:
|
|
450
|
+
w = 1
|
|
451
|
+
if h < 1:
|
|
452
|
+
h = 1
|
|
453
|
+
return int(w), int(h)
|
|
454
|
+
|
|
455
|
+
def render_lines(self, lines, options, render_text, y, size):
|
|
456
|
+
padding_left = options['padding'][0]
|
|
457
|
+
padding_right = options['padding'][2]
|
|
458
|
+
w = size[0]
|
|
459
|
+
halign = options['halign']
|
|
460
|
+
refs = self._refs
|
|
461
|
+
anchors = self._anchors
|
|
462
|
+
base_dir = options['base_direction'] or self._resolved_base_dir
|
|
463
|
+
auto_halign_r = halign == 'auto' and base_dir and 'rtl' in base_dir
|
|
464
|
+
|
|
465
|
+
for layout_line in lines: # for plain label each line has only one str
|
|
466
|
+
lw, lh = layout_line.w, layout_line.h
|
|
467
|
+
x = padding_left
|
|
468
|
+
if halign == 'center':
|
|
469
|
+
x = min(
|
|
470
|
+
int(w - lw),
|
|
471
|
+
max(
|
|
472
|
+
int(padding_left),
|
|
473
|
+
int((w - lw + padding_left - padding_right) / 2.0)
|
|
474
|
+
)
|
|
475
|
+
)
|
|
476
|
+
elif halign == 'right' or auto_halign_r:
|
|
477
|
+
x = max(0, int(w - lw - padding_right))
|
|
478
|
+
layout_line.x = x
|
|
479
|
+
layout_line.y = y
|
|
480
|
+
psp = pph = 0
|
|
481
|
+
for word in layout_line.words:
|
|
482
|
+
options = self.options = word.options
|
|
483
|
+
# the word height is not scaled by line_height, only lh was
|
|
484
|
+
wh = options['line_height'] * word.lh
|
|
485
|
+
# calculate sub/super script pos
|
|
486
|
+
if options['script'] == 'superscript':
|
|
487
|
+
script_pos = max(0, psp if psp and (wh < pph)
|
|
488
|
+
else self.get_descent())
|
|
489
|
+
psp = script_pos
|
|
490
|
+
pph = wh
|
|
491
|
+
elif options['script'] == 'subscript':
|
|
492
|
+
script_pos = min(lh - wh, ((psp + pph) - wh)
|
|
493
|
+
if pph and (wh < pph) else (lh - wh))
|
|
494
|
+
pph = wh
|
|
495
|
+
psp = script_pos
|
|
496
|
+
else:
|
|
497
|
+
script_pos = (lh - wh) / 1.25
|
|
498
|
+
psp = pph = 0
|
|
499
|
+
if len(word.text):
|
|
500
|
+
render_text(word.text, x, y + script_pos)
|
|
501
|
+
|
|
502
|
+
# should we record refs ?
|
|
503
|
+
ref = options['_ref']
|
|
504
|
+
if ref is not None:
|
|
505
|
+
if ref not in refs:
|
|
506
|
+
refs[ref] = []
|
|
507
|
+
refs[ref].append((x, y, x + word.lw, y + wh))
|
|
508
|
+
|
|
509
|
+
# Should we record anchors?
|
|
510
|
+
anchor = options['_anchor']
|
|
511
|
+
if anchor is not None:
|
|
512
|
+
if anchor not in anchors:
|
|
513
|
+
anchors[anchor] = (x, y)
|
|
514
|
+
x += word.lw
|
|
515
|
+
y += lh
|
|
516
|
+
return y
|
|
517
|
+
|
|
518
|
+
def shorten_post(self, lines, w, h, margin=2):
|
|
519
|
+
''' Shortens the text to a single line according to the label options.
|
|
520
|
+
|
|
521
|
+
This function operates on a text that has already been laid out because
|
|
522
|
+
for markup, parts of text can have different size and options.
|
|
523
|
+
|
|
524
|
+
If :attr:`text_size` [0] is None, the lines are returned unchanged.
|
|
525
|
+
Otherwise, the lines are converted to a single line fitting within the
|
|
526
|
+
constrained width, :attr:`text_size` [0].
|
|
527
|
+
|
|
528
|
+
:params:
|
|
529
|
+
|
|
530
|
+
`lines`: list of `LayoutLine` instances describing the text.
|
|
531
|
+
`w`: int, the width of the text in lines, including padding.
|
|
532
|
+
`h`: int, the height of the text in lines, including padding.
|
|
533
|
+
`margin` int, the additional space left on the sides. This is in
|
|
534
|
+
addition to :attr:`padding_x`.
|
|
535
|
+
|
|
536
|
+
:returns:
|
|
537
|
+
3-tuple of (xw, h, lines), where w, and h is similar to the input
|
|
538
|
+
and contains the resulting width / height of the text, including
|
|
539
|
+
padding. lines, is a list containing a single `LayoutLine`, which
|
|
540
|
+
contains the words for the line.
|
|
541
|
+
'''
|
|
542
|
+
|
|
543
|
+
def n(line, c):
|
|
544
|
+
''' A function similar to text.find, except it's an iterator that
|
|
545
|
+
returns successive occurrences of string c in list line. line is
|
|
546
|
+
not a string, but a list of LayoutWord instances that we walk
|
|
547
|
+
from left to right returning the indices of c in the words as we
|
|
548
|
+
encounter them. Note that the options can be different among the
|
|
549
|
+
words.
|
|
550
|
+
|
|
551
|
+
:returns:
|
|
552
|
+
3-tuple: the index of the word in line, the index of the
|
|
553
|
+
occurrence in word, and the extents (width) of the combined
|
|
554
|
+
words until this occurrence, not including the occurrence char.
|
|
555
|
+
If no more are found it returns (-1, -1, total_w) where total_w
|
|
556
|
+
is the full width of all the words.
|
|
557
|
+
'''
|
|
558
|
+
total_w = 0
|
|
559
|
+
for w in range(len(line)):
|
|
560
|
+
word = line[w]
|
|
561
|
+
if not word.lw:
|
|
562
|
+
continue
|
|
563
|
+
f = partial(word.text.find, c)
|
|
564
|
+
i = f()
|
|
565
|
+
while i != -1:
|
|
566
|
+
self.options = word.options
|
|
567
|
+
yield w, i, total_w + self.get_extents(word.text[:i])[0]
|
|
568
|
+
i = f(i + 1)
|
|
569
|
+
self.options = word.options
|
|
570
|
+
total_w += self.get_extents(word.text)[0]
|
|
571
|
+
yield -1, -1, total_w # this should never be reached, really
|
|
572
|
+
|
|
573
|
+
def p(line, c):
|
|
574
|
+
''' Similar to the `n` function, except it returns occurrences of c
|
|
575
|
+
from right to left in the list, line, similar to rfind.
|
|
576
|
+
'''
|
|
577
|
+
total_w = 0
|
|
578
|
+
offset = 0 if len(c) else 1
|
|
579
|
+
for w in range(len(line) - 1, -1, -1):
|
|
580
|
+
word = line[w]
|
|
581
|
+
if not word.lw:
|
|
582
|
+
continue
|
|
583
|
+
f = partial(word.text.rfind, c)
|
|
584
|
+
i = f()
|
|
585
|
+
while i != -1:
|
|
586
|
+
self.options = word.options
|
|
587
|
+
yield (w, i, total_w +
|
|
588
|
+
self.get_extents(word.text[i + 1:])[0])
|
|
589
|
+
if i:
|
|
590
|
+
i = f(0, i - offset)
|
|
591
|
+
else:
|
|
592
|
+
if not c:
|
|
593
|
+
self.options = word.options
|
|
594
|
+
yield (w, -1, total_w +
|
|
595
|
+
self.get_extents(word.text)[0])
|
|
596
|
+
break
|
|
597
|
+
self.options = word.options
|
|
598
|
+
total_w += self.get_extents(word.text)[0]
|
|
599
|
+
yield -1, -1, total_w # this should never be reached, really
|
|
600
|
+
|
|
601
|
+
def n_restricted(line, uw, c):
|
|
602
|
+
''' Similar to the function `n`, except it only returns the first
|
|
603
|
+
occurrence and it's not an iterator. Furthermore, if the first
|
|
604
|
+
occurrence doesn't fit within width uw, it returns the index of
|
|
605
|
+
whatever amount of text will still fit in uw.
|
|
606
|
+
|
|
607
|
+
:returns:
|
|
608
|
+
similar to the function `n`, except it's a 4-tuple, with the
|
|
609
|
+
last element a boolean, indicating if we had to clip the text
|
|
610
|
+
to fit in uw (True) or if the whole text until the first
|
|
611
|
+
occurrence fitted in uw (False).
|
|
612
|
+
'''
|
|
613
|
+
total_w = 0
|
|
614
|
+
if not len(line):
|
|
615
|
+
return 0, 0, 0
|
|
616
|
+
for w in range(len(line)):
|
|
617
|
+
word = line[w]
|
|
618
|
+
f = partial(word.text.find, c)
|
|
619
|
+
self.options = word.options
|
|
620
|
+
extents = self.get_cached_extents()
|
|
621
|
+
i = f()
|
|
622
|
+
if i != -1:
|
|
623
|
+
ww = extents(word.text[:i])[0]
|
|
624
|
+
|
|
625
|
+
if i != -1 and total_w + ww <= uw: # found and it fits
|
|
626
|
+
return w, i, total_w + ww, False
|
|
627
|
+
elif i == -1:
|
|
628
|
+
ww = extents(word.text)[0]
|
|
629
|
+
if total_w + ww <= uw: # wasn't found and all fits
|
|
630
|
+
total_w += ww
|
|
631
|
+
continue
|
|
632
|
+
i = len(word.text)
|
|
633
|
+
|
|
634
|
+
# now just find whatever amount of the word does fit
|
|
635
|
+
e = 0
|
|
636
|
+
while e != i and total_w + extents(word.text[:e])[0] <= uw:
|
|
637
|
+
e += 1
|
|
638
|
+
e = max(0, e - 1)
|
|
639
|
+
return w, e, total_w + extents(word.text[:e])[0], True
|
|
640
|
+
|
|
641
|
+
return -1, -1, total_w, False
|
|
642
|
+
|
|
643
|
+
def p_restricted(line, uw, c):
|
|
644
|
+
''' Similar to `n_restricted`, except it returns the first
|
|
645
|
+
occurrence starting from the right, like `p`.
|
|
646
|
+
'''
|
|
647
|
+
total_w = 0
|
|
648
|
+
if not len(line):
|
|
649
|
+
return 0, 0, 0
|
|
650
|
+
for w in range(len(line) - 1, -1, -1):
|
|
651
|
+
word = line[w]
|
|
652
|
+
f = partial(word.text.rfind, c)
|
|
653
|
+
self.options = word.options
|
|
654
|
+
extents = self.get_cached_extents()
|
|
655
|
+
i = f()
|
|
656
|
+
if i != -1:
|
|
657
|
+
ww = extents(word.text[i + 1:])[0]
|
|
658
|
+
|
|
659
|
+
if i != -1 and total_w + ww <= uw: # found and it fits
|
|
660
|
+
return w, i, total_w + ww, False
|
|
661
|
+
elif i == -1:
|
|
662
|
+
ww = extents(word.text)[0]
|
|
663
|
+
if total_w + ww <= uw: # wasn't found and all fits
|
|
664
|
+
total_w += ww
|
|
665
|
+
continue
|
|
666
|
+
|
|
667
|
+
# now just find whatever amount of the word does fit
|
|
668
|
+
s = len(word.text) - 1
|
|
669
|
+
while s >= 0 and total_w + extents(word.text[s:])[0] <= uw:
|
|
670
|
+
s -= 1
|
|
671
|
+
return w, s, total_w + extents(word.text[s + 1:])[0], True
|
|
672
|
+
|
|
673
|
+
return -1, -1, total_w, False
|
|
674
|
+
|
|
675
|
+
textwidth = self.get_cached_extents()
|
|
676
|
+
uw = self.text_size[0]
|
|
677
|
+
if uw is None:
|
|
678
|
+
return w, h, lines
|
|
679
|
+
old_opts = copy(self.options)
|
|
680
|
+
uw = max(
|
|
681
|
+
0,
|
|
682
|
+
int(uw - old_opts["padding"][0] - old_opts["padding"][2] - margin),
|
|
683
|
+
)
|
|
684
|
+
chr = type(self.text)
|
|
685
|
+
ssize = textwidth(' ')
|
|
686
|
+
c = old_opts['split_str']
|
|
687
|
+
line_height = old_opts['line_height']
|
|
688
|
+
xpad, ypad = (
|
|
689
|
+
old_opts["padding"][0] + old_opts["padding"][2],
|
|
690
|
+
old_opts["padding"][1] + old_opts["padding"][3],
|
|
691
|
+
)
|
|
692
|
+
dir = old_opts['shorten_from'][0]
|
|
693
|
+
|
|
694
|
+
# flatten lines into single line
|
|
695
|
+
line = []
|
|
696
|
+
last_w = 0
|
|
697
|
+
for l in range(len(lines)):
|
|
698
|
+
# concatenate (non-empty) inside lines with a space
|
|
699
|
+
this_line = lines[l]
|
|
700
|
+
if last_w and this_line.w and not this_line.line_wrap:
|
|
701
|
+
line.append(LayoutWord(old_opts, ssize[0], ssize[1], chr(' ')))
|
|
702
|
+
last_w = this_line.w or last_w
|
|
703
|
+
for word in this_line.words:
|
|
704
|
+
if word.lw:
|
|
705
|
+
line.append(word)
|
|
706
|
+
|
|
707
|
+
# if that fits, just return the flattened line
|
|
708
|
+
lw = sum([word.lw for word in line])
|
|
709
|
+
if lw <= uw:
|
|
710
|
+
lh = max([word.lh for word in line] + [0]) * line_height
|
|
711
|
+
self.is_shortened = False
|
|
712
|
+
return (
|
|
713
|
+
lw + xpad,
|
|
714
|
+
lh + ypad,
|
|
715
|
+
[LayoutLine(0, 0, lw, lh, 1, 0, line)]
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
elps_opts = copy(old_opts)
|
|
719
|
+
if 'ellipsis_options' in old_opts:
|
|
720
|
+
elps_opts.update(old_opts['ellipsis_options'])
|
|
721
|
+
|
|
722
|
+
# Set new opts for ellipsis
|
|
723
|
+
self.options = elps_opts
|
|
724
|
+
# find the size of ellipsis that'll fit
|
|
725
|
+
elps_s = textwidth('...')
|
|
726
|
+
if elps_s[0] > uw: # even ellipsis didn't fit...
|
|
727
|
+
self.is_shortened = True
|
|
728
|
+
s = textwidth('..')
|
|
729
|
+
if s[0] <= uw:
|
|
730
|
+
return (
|
|
731
|
+
s[0] + xpad,
|
|
732
|
+
s[1] * line_height + ypad,
|
|
733
|
+
[LayoutLine(
|
|
734
|
+
0, 0, s[0], s[1], 1, 0,
|
|
735
|
+
[LayoutWord(old_opts, s[0], s[1], '..')])]
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
else:
|
|
739
|
+
s = textwidth('.')
|
|
740
|
+
return (
|
|
741
|
+
s[0] + xpad,
|
|
742
|
+
s[1] * line_height + ypad,
|
|
743
|
+
[LayoutLine(
|
|
744
|
+
0, 0, s[0], s[1], 1, 0,
|
|
745
|
+
[LayoutWord(old_opts, s[0], s[1], '.')])]
|
|
746
|
+
)
|
|
747
|
+
|
|
748
|
+
elps = LayoutWord(elps_opts, elps_s[0], elps_s[1], '...')
|
|
749
|
+
uw -= elps_s[0]
|
|
750
|
+
# Restore old opts
|
|
751
|
+
self.options = old_opts
|
|
752
|
+
|
|
753
|
+
# now find the first left and right words that fit
|
|
754
|
+
w1, e1, l1, clipped1 = n_restricted(line, uw, c)
|
|
755
|
+
w2, s2, l2, clipped2 = p_restricted(line, uw, c)
|
|
756
|
+
|
|
757
|
+
if dir != 'l': # center or right
|
|
758
|
+
line1 = None
|
|
759
|
+
if clipped1 or clipped2 or l1 + l2 > uw:
|
|
760
|
+
# if either was clipped or both don't fit, just take first
|
|
761
|
+
if len(c):
|
|
762
|
+
self.options = old_opts
|
|
763
|
+
old_opts['split_str'] = ''
|
|
764
|
+
res = self.shorten_post(lines, w, h, margin)
|
|
765
|
+
self.options['split_str'] = c
|
|
766
|
+
self.is_shortened = True
|
|
767
|
+
return res
|
|
768
|
+
line1 = line[:w1]
|
|
769
|
+
last_word = line[w1]
|
|
770
|
+
last_text = last_word.text[:e1]
|
|
771
|
+
self.options = last_word.options
|
|
772
|
+
s = self.get_extents(last_text)
|
|
773
|
+
line1.append(LayoutWord(last_word.options, s[0], s[1],
|
|
774
|
+
last_text))
|
|
775
|
+
elif (w1, e1) == (-1, -1): # this shouldn't occur
|
|
776
|
+
line1 = line
|
|
777
|
+
if line1:
|
|
778
|
+
line1.append(elps)
|
|
779
|
+
lw = sum([word.lw for word in line1])
|
|
780
|
+
lh = max([word.lh for word in line1]) * line_height
|
|
781
|
+
self.options = old_opts
|
|
782
|
+
self.is_shortened = True
|
|
783
|
+
return (
|
|
784
|
+
lw + xpad,
|
|
785
|
+
lh + ypad,
|
|
786
|
+
[LayoutLine(0, 0, lw, lh, 1, 0, line1)]
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
# now we know that both the first and last word fit, and that
|
|
790
|
+
# there's at least one instances of the split_str in the line
|
|
791
|
+
if (w1, e1) != (w2, s2): # more than one split_str
|
|
792
|
+
if dir == 'r':
|
|
793
|
+
f = n(line, c) # iterator
|
|
794
|
+
assert next(f)[:-1] == (w1, e1) # first word should match
|
|
795
|
+
ww1, ee1, l1 = next(f)
|
|
796
|
+
while l2 + l1 <= uw:
|
|
797
|
+
w1, e1 = ww1, ee1
|
|
798
|
+
ww1, ee1, l1 = next(f)
|
|
799
|
+
if (w1, e1) == (w2, s2):
|
|
800
|
+
break
|
|
801
|
+
else: # center
|
|
802
|
+
f = n(line, c) # iterator
|
|
803
|
+
f_inv = p(line, c) # iterator
|
|
804
|
+
assert next(f)[:-1] == (w1, e1)
|
|
805
|
+
assert next(f_inv)[:-1] == (w2, s2)
|
|
806
|
+
while True:
|
|
807
|
+
if l1 <= l2:
|
|
808
|
+
ww1, ee1, l1 = next(f) # hypothesize that next fit
|
|
809
|
+
if l2 + l1 > uw:
|
|
810
|
+
break
|
|
811
|
+
w1, e1 = ww1, ee1
|
|
812
|
+
if (w1, e1) == (w2, s2):
|
|
813
|
+
break
|
|
814
|
+
else:
|
|
815
|
+
ww2, ss2, l2 = next(f_inv)
|
|
816
|
+
if l2 + l1 > uw:
|
|
817
|
+
break
|
|
818
|
+
w2, s2 = ww2, ss2
|
|
819
|
+
if (w1, e1) == (w2, s2):
|
|
820
|
+
break
|
|
821
|
+
else: # left
|
|
822
|
+
line1 = [elps]
|
|
823
|
+
if clipped1 or clipped2 or l1 + l2 > uw:
|
|
824
|
+
# if either was clipped or both don't fit, just take last
|
|
825
|
+
if len(c):
|
|
826
|
+
self.options = old_opts
|
|
827
|
+
old_opts['split_str'] = ''
|
|
828
|
+
res = self.shorten_post(lines, w, h, margin)
|
|
829
|
+
self.options['split_str'] = c
|
|
830
|
+
self.is_shortened = True
|
|
831
|
+
return res
|
|
832
|
+
first_word = line[w2]
|
|
833
|
+
first_text = first_word.text[s2 + 1:]
|
|
834
|
+
self.options = first_word.options
|
|
835
|
+
s = self.get_extents(first_text)
|
|
836
|
+
line1.append(LayoutWord(first_word.options, s[0], s[1],
|
|
837
|
+
first_text))
|
|
838
|
+
line1.extend(line[w2 + 1:])
|
|
839
|
+
elif (w1, e1) == (-1, -1): # this shouldn't occur
|
|
840
|
+
line1 = line
|
|
841
|
+
if len(line1) != 1:
|
|
842
|
+
lw = sum([word.lw for word in line1])
|
|
843
|
+
lh = max([word.lh for word in line1]) * line_height
|
|
844
|
+
self.options = old_opts
|
|
845
|
+
self.is_shortened = True
|
|
846
|
+
return (
|
|
847
|
+
lw + xpad,
|
|
848
|
+
lh + ypad,
|
|
849
|
+
[LayoutLine(0, 0, lw, lh, 1, 0, line1)]
|
|
850
|
+
)
|
|
851
|
+
|
|
852
|
+
# now we know that both the first and last word fit, and that
|
|
853
|
+
# there's at least one instances of the split_str in the line
|
|
854
|
+
if (w1, e1) != (w2, s2): # more than one split_str
|
|
855
|
+
f_inv = p(line, c) # iterator
|
|
856
|
+
assert next(f_inv)[:-1] == (w2, s2) # last word should match
|
|
857
|
+
ww2, ss2, l2 = next(f_inv)
|
|
858
|
+
while l2 + l1 <= uw:
|
|
859
|
+
w2, s2 = ww2, ss2
|
|
860
|
+
ww2, ss2, l2 = next(f_inv)
|
|
861
|
+
if (w1, e1) == (w2, s2):
|
|
862
|
+
break
|
|
863
|
+
|
|
864
|
+
# now add back the left half
|
|
865
|
+
line1 = line[:w1]
|
|
866
|
+
last_word = line[w1]
|
|
867
|
+
last_text = last_word.text[:e1]
|
|
868
|
+
self.options = last_word.options
|
|
869
|
+
s = self.get_extents(last_text)
|
|
870
|
+
if len(last_text):
|
|
871
|
+
line1.append(LayoutWord(last_word.options, s[0], s[1], last_text))
|
|
872
|
+
line1.append(elps)
|
|
873
|
+
|
|
874
|
+
# now add back the right half
|
|
875
|
+
first_word = line[w2]
|
|
876
|
+
first_text = first_word.text[s2 + 1:]
|
|
877
|
+
self.options = first_word.options
|
|
878
|
+
s = self.get_extents(first_text)
|
|
879
|
+
if len(first_text):
|
|
880
|
+
line1.append(LayoutWord(first_word.options, s[0], s[1],
|
|
881
|
+
first_text))
|
|
882
|
+
line1.extend(line[w2 + 1:])
|
|
883
|
+
|
|
884
|
+
lw = sum([word.lw for word in line1])
|
|
885
|
+
lh = max([word.lh for word in line1]) * line_height
|
|
886
|
+
self.options = old_opts
|
|
887
|
+
if uw < lw:
|
|
888
|
+
self.is_shortened = True
|
|
889
|
+
return (
|
|
890
|
+
lw + xpad,
|
|
891
|
+
lh + ypad,
|
|
892
|
+
[LayoutLine(0, 0, lw, lh, 1, 0, line1)]
|
|
893
|
+
)
|