vispy 0.15.0__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
Potentially problematic release.
This version of vispy might be problematic. Click here for more details.
- vispy/__init__.py +33 -0
- vispy/app/__init__.py +15 -0
- vispy/app/_default_app.py +76 -0
- vispy/app/_detect_eventloop.py +148 -0
- vispy/app/application.py +263 -0
- vispy/app/backends/__init__.py +52 -0
- vispy/app/backends/_egl.py +264 -0
- vispy/app/backends/_glfw.py +513 -0
- vispy/app/backends/_jupyter_rfb.py +278 -0
- vispy/app/backends/_offscreen_util.py +121 -0
- vispy/app/backends/_osmesa.py +235 -0
- vispy/app/backends/_pyglet.py +451 -0
- vispy/app/backends/_pyqt4.py +36 -0
- vispy/app/backends/_pyqt5.py +36 -0
- vispy/app/backends/_pyqt6.py +40 -0
- vispy/app/backends/_pyside.py +37 -0
- vispy/app/backends/_pyside2.py +52 -0
- vispy/app/backends/_pyside6.py +53 -0
- vispy/app/backends/_qt.py +1003 -0
- vispy/app/backends/_sdl2.py +444 -0
- vispy/app/backends/_template.py +244 -0
- vispy/app/backends/_test.py +8 -0
- vispy/app/backends/_tk.py +800 -0
- vispy/app/backends/_wx.py +476 -0
- vispy/app/backends/tests/__init__.py +0 -0
- vispy/app/backends/tests/test_offscreen_util.py +52 -0
- vispy/app/backends/tests/test_rfb.py +77 -0
- vispy/app/base.py +294 -0
- vispy/app/canvas.py +828 -0
- vispy/app/qt.py +92 -0
- vispy/app/tests/__init__.py +0 -0
- vispy/app/tests/qt-designer.ui +58 -0
- vispy/app/tests/test_app.py +442 -0
- vispy/app/tests/test_backends.py +164 -0
- vispy/app/tests/test_canvas.py +122 -0
- vispy/app/tests/test_context.py +92 -0
- vispy/app/tests/test_qt.py +47 -0
- vispy/app/tests/test_simultaneous.py +134 -0
- vispy/app/timer.py +174 -0
- vispy/color/__init__.py +17 -0
- vispy/color/_color_dict.py +193 -0
- vispy/color/color_array.py +447 -0
- vispy/color/color_space.py +181 -0
- vispy/color/colormap.py +1213 -0
- vispy/color/tests/__init__.py +0 -0
- vispy/color/tests/test_color.py +378 -0
- vispy/conftest.py +12 -0
- vispy/ext/__init__.py +0 -0
- vispy/ext/cocoapy.py +1522 -0
- vispy/ext/cubehelix.py +138 -0
- vispy/ext/egl.py +375 -0
- vispy/ext/fontconfig.py +118 -0
- vispy/ext/gdi32plus.py +206 -0
- vispy/ext/osmesa.py +105 -0
- vispy/geometry/__init__.py +23 -0
- vispy/geometry/_triangulation_debugger.py +171 -0
- vispy/geometry/calculations.py +162 -0
- vispy/geometry/curves.py +399 -0
- vispy/geometry/generation.py +643 -0
- vispy/geometry/isocurve.py +175 -0
- vispy/geometry/isosurface.py +465 -0
- vispy/geometry/meshdata.py +700 -0
- vispy/geometry/normals.py +78 -0
- vispy/geometry/parametric.py +56 -0
- vispy/geometry/polygon.py +137 -0
- vispy/geometry/rect.py +210 -0
- vispy/geometry/tests/__init__.py +0 -0
- vispy/geometry/tests/test_calculations.py +23 -0
- vispy/geometry/tests/test_generation.py +56 -0
- vispy/geometry/tests/test_meshdata.py +106 -0
- vispy/geometry/tests/test_triangulation.py +594 -0
- vispy/geometry/torusknot.py +142 -0
- vispy/geometry/triangulation.py +876 -0
- vispy/gloo/__init__.py +56 -0
- vispy/gloo/buffer.py +505 -0
- vispy/gloo/context.py +272 -0
- vispy/gloo/framebuffer.py +257 -0
- vispy/gloo/gl/__init__.py +234 -0
- vispy/gloo/gl/_constants.py +332 -0
- vispy/gloo/gl/_es2.py +986 -0
- vispy/gloo/gl/_gl2.py +1365 -0
- vispy/gloo/gl/_proxy.py +499 -0
- vispy/gloo/gl/_pyopengl2.py +362 -0
- vispy/gloo/gl/dummy.py +24 -0
- vispy/gloo/gl/es2.py +62 -0
- vispy/gloo/gl/gl2.py +98 -0
- vispy/gloo/gl/glplus.py +168 -0
- vispy/gloo/gl/pyopengl2.py +97 -0
- vispy/gloo/gl/tests/__init__.py +0 -0
- vispy/gloo/gl/tests/test_basics.py +282 -0
- vispy/gloo/gl/tests/test_functionality.py +568 -0
- vispy/gloo/gl/tests/test_names.py +246 -0
- vispy/gloo/gl/tests/test_use.py +71 -0
- vispy/gloo/glir.py +1824 -0
- vispy/gloo/globject.py +101 -0
- vispy/gloo/preprocessor.py +67 -0
- vispy/gloo/program.py +543 -0
- vispy/gloo/tests/__init__.py +0 -0
- vispy/gloo/tests/test_buffer.py +558 -0
- vispy/gloo/tests/test_context.py +119 -0
- vispy/gloo/tests/test_framebuffer.py +195 -0
- vispy/gloo/tests/test_glir.py +307 -0
- vispy/gloo/tests/test_globject.py +35 -0
- vispy/gloo/tests/test_program.py +302 -0
- vispy/gloo/tests/test_texture.py +732 -0
- vispy/gloo/tests/test_use_gloo.py +187 -0
- vispy/gloo/tests/test_util.py +60 -0
- vispy/gloo/tests/test_wrappers.py +261 -0
- vispy/gloo/texture.py +1046 -0
- vispy/gloo/util.py +129 -0
- vispy/gloo/wrappers.py +762 -0
- vispy/glsl/__init__.py +42 -0
- vispy/glsl/antialias/antialias.glsl +7 -0
- vispy/glsl/antialias/cap-butt.glsl +31 -0
- vispy/glsl/antialias/cap-round.glsl +29 -0
- vispy/glsl/antialias/cap-square.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
- vispy/glsl/antialias/cap.glsl +67 -0
- vispy/glsl/antialias/caps.glsl +67 -0
- vispy/glsl/antialias/filled.glsl +50 -0
- vispy/glsl/antialias/outline.glsl +40 -0
- vispy/glsl/antialias/stroke.glsl +43 -0
- vispy/glsl/arrowheads/angle.glsl +99 -0
- vispy/glsl/arrowheads/arrowheads.frag +60 -0
- vispy/glsl/arrowheads/arrowheads.glsl +12 -0
- vispy/glsl/arrowheads/arrowheads.vert +83 -0
- vispy/glsl/arrowheads/curved.glsl +48 -0
- vispy/glsl/arrowheads/inhibitor.glsl +26 -0
- vispy/glsl/arrowheads/stealth.glsl +46 -0
- vispy/glsl/arrowheads/triangle.glsl +97 -0
- vispy/glsl/arrowheads/util.glsl +13 -0
- vispy/glsl/arrows/angle-30.glsl +12 -0
- vispy/glsl/arrows/angle-60.glsl +12 -0
- vispy/glsl/arrows/angle-90.glsl +12 -0
- vispy/glsl/arrows/arrow.frag +39 -0
- vispy/glsl/arrows/arrow.vert +49 -0
- vispy/glsl/arrows/arrows.glsl +17 -0
- vispy/glsl/arrows/common.glsl +187 -0
- vispy/glsl/arrows/curved.glsl +63 -0
- vispy/glsl/arrows/stealth.glsl +50 -0
- vispy/glsl/arrows/triangle-30.glsl +12 -0
- vispy/glsl/arrows/triangle-60.glsl +12 -0
- vispy/glsl/arrows/triangle-90.glsl +12 -0
- vispy/glsl/arrows/util.glsl +98 -0
- vispy/glsl/build_spatial_filters.py +660 -0
- vispy/glsl/collections/agg-fast-path.frag +20 -0
- vispy/glsl/collections/agg-fast-path.vert +78 -0
- vispy/glsl/collections/agg-glyph.frag +60 -0
- vispy/glsl/collections/agg-glyph.vert +33 -0
- vispy/glsl/collections/agg-marker.frag +35 -0
- vispy/glsl/collections/agg-marker.vert +48 -0
- vispy/glsl/collections/agg-path.frag +55 -0
- vispy/glsl/collections/agg-path.vert +166 -0
- vispy/glsl/collections/agg-point.frag +21 -0
- vispy/glsl/collections/agg-point.vert +35 -0
- vispy/glsl/collections/agg-segment.frag +32 -0
- vispy/glsl/collections/agg-segment.vert +75 -0
- vispy/glsl/collections/marker.frag +38 -0
- vispy/glsl/collections/marker.vert +48 -0
- vispy/glsl/collections/raw-path.frag +15 -0
- vispy/glsl/collections/raw-path.vert +24 -0
- vispy/glsl/collections/raw-point.frag +14 -0
- vispy/glsl/collections/raw-point.vert +31 -0
- vispy/glsl/collections/raw-segment.frag +18 -0
- vispy/glsl/collections/raw-segment.vert +26 -0
- vispy/glsl/collections/raw-triangle.frag +13 -0
- vispy/glsl/collections/raw-triangle.vert +26 -0
- vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
- vispy/glsl/collections/sdf-glyph.frag +80 -0
- vispy/glsl/collections/sdf-glyph.vert +59 -0
- vispy/glsl/collections/tick-labels.vert +71 -0
- vispy/glsl/colormaps/autumn.glsl +20 -0
- vispy/glsl/colormaps/blues.glsl +20 -0
- vispy/glsl/colormaps/color-space.glsl +17 -0
- vispy/glsl/colormaps/colormaps.glsl +24 -0
- vispy/glsl/colormaps/cool.glsl +20 -0
- vispy/glsl/colormaps/fire.glsl +21 -0
- vispy/glsl/colormaps/gray.glsl +20 -0
- vispy/glsl/colormaps/greens.glsl +20 -0
- vispy/glsl/colormaps/hot.glsl +22 -0
- vispy/glsl/colormaps/ice.glsl +20 -0
- vispy/glsl/colormaps/icefire.glsl +23 -0
- vispy/glsl/colormaps/parse.py +40 -0
- vispy/glsl/colormaps/reds.glsl +20 -0
- vispy/glsl/colormaps/spring.glsl +20 -0
- vispy/glsl/colormaps/summer.glsl +20 -0
- vispy/glsl/colormaps/user.glsl +22 -0
- vispy/glsl/colormaps/util.glsl +41 -0
- vispy/glsl/colormaps/wheel.glsl +21 -0
- vispy/glsl/colormaps/winter.glsl +20 -0
- vispy/glsl/lines/agg.frag +320 -0
- vispy/glsl/lines/agg.vert +241 -0
- vispy/glsl/markers/arrow.glsl +12 -0
- vispy/glsl/markers/asterisk.glsl +16 -0
- vispy/glsl/markers/chevron.glsl +14 -0
- vispy/glsl/markers/clover.glsl +20 -0
- vispy/glsl/markers/club.glsl +31 -0
- vispy/glsl/markers/cross.glsl +17 -0
- vispy/glsl/markers/diamond.glsl +12 -0
- vispy/glsl/markers/disc.glsl +9 -0
- vispy/glsl/markers/ellipse.glsl +67 -0
- vispy/glsl/markers/hbar.glsl +9 -0
- vispy/glsl/markers/heart.glsl +15 -0
- vispy/glsl/markers/infinity.glsl +15 -0
- vispy/glsl/markers/marker-sdf.frag +74 -0
- vispy/glsl/markers/marker-sdf.vert +41 -0
- vispy/glsl/markers/marker.frag +36 -0
- vispy/glsl/markers/marker.vert +46 -0
- vispy/glsl/markers/markers.glsl +24 -0
- vispy/glsl/markers/pin.glsl +18 -0
- vispy/glsl/markers/ring.glsl +11 -0
- vispy/glsl/markers/spade.glsl +28 -0
- vispy/glsl/markers/square.glsl +10 -0
- vispy/glsl/markers/tag.glsl +11 -0
- vispy/glsl/markers/triangle.glsl +14 -0
- vispy/glsl/markers/vbar.glsl +9 -0
- vispy/glsl/math/circle-through-2-points.glsl +30 -0
- vispy/glsl/math/constants.glsl +48 -0
- vispy/glsl/math/double.glsl +114 -0
- vispy/glsl/math/functions.glsl +20 -0
- vispy/glsl/math/point-to-line-distance.glsl +31 -0
- vispy/glsl/math/point-to-line-projection.glsl +29 -0
- vispy/glsl/math/signed-line-distance.glsl +27 -0
- vispy/glsl/math/signed-segment-distance.glsl +30 -0
- vispy/glsl/misc/regular-grid.frag +244 -0
- vispy/glsl/misc/spatial-filters.frag +1407 -0
- vispy/glsl/misc/viewport-NDC.glsl +20 -0
- vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
- vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
- vispy/glsl/transforms/hammer.glsl +44 -0
- vispy/glsl/transforms/identity.glsl +6 -0
- vispy/glsl/transforms/identity_forward.glsl +23 -0
- vispy/glsl/transforms/identity_inverse.glsl +23 -0
- vispy/glsl/transforms/linear-scale.glsl +127 -0
- vispy/glsl/transforms/log-scale.glsl +126 -0
- vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
- vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
- vispy/glsl/transforms/panzoom.glsl +10 -0
- vispy/glsl/transforms/polar.glsl +41 -0
- vispy/glsl/transforms/position.glsl +44 -0
- vispy/glsl/transforms/power-scale.glsl +139 -0
- vispy/glsl/transforms/projection.glsl +7 -0
- vispy/glsl/transforms/pvm.glsl +13 -0
- vispy/glsl/transforms/rotate.glsl +45 -0
- vispy/glsl/transforms/trackball.glsl +15 -0
- vispy/glsl/transforms/translate.glsl +35 -0
- vispy/glsl/transforms/transverse_mercator.glsl +38 -0
- vispy/glsl/transforms/viewport-clipping.glsl +14 -0
- vispy/glsl/transforms/viewport-transform.glsl +16 -0
- vispy/glsl/transforms/viewport.glsl +50 -0
- vispy/glsl/transforms/x.glsl +24 -0
- vispy/glsl/transforms/y.glsl +19 -0
- vispy/glsl/transforms/z.glsl +14 -0
- vispy/io/__init__.py +20 -0
- vispy/io/_data/spatial-filters.npy +0 -0
- vispy/io/datasets.py +94 -0
- vispy/io/image.py +231 -0
- vispy/io/mesh.py +122 -0
- vispy/io/stl.py +167 -0
- vispy/io/tests/__init__.py +0 -0
- vispy/io/tests/test_image.py +47 -0
- vispy/io/tests/test_io.py +121 -0
- vispy/io/wavefront.py +350 -0
- vispy/plot/__init__.py +36 -0
- vispy/plot/fig.py +58 -0
- vispy/plot/plotwidget.py +522 -0
- vispy/plot/tests/__init__.py +0 -0
- vispy/plot/tests/test_plot.py +46 -0
- vispy/scene/__init__.py +43 -0
- vispy/scene/cameras/__init__.py +27 -0
- vispy/scene/cameras/_base.py +38 -0
- vispy/scene/cameras/arcball.py +105 -0
- vispy/scene/cameras/base_camera.py +551 -0
- vispy/scene/cameras/fly.py +474 -0
- vispy/scene/cameras/magnify.py +163 -0
- vispy/scene/cameras/panzoom.py +311 -0
- vispy/scene/cameras/perspective.py +338 -0
- vispy/scene/cameras/tests/__init__.py +0 -0
- vispy/scene/cameras/tests/test_cameras.py +27 -0
- vispy/scene/cameras/tests/test_link.py +53 -0
- vispy/scene/cameras/tests/test_perspective.py +122 -0
- vispy/scene/cameras/turntable.py +183 -0
- vispy/scene/canvas.py +639 -0
- vispy/scene/events.py +85 -0
- vispy/scene/node.py +644 -0
- vispy/scene/subscene.py +20 -0
- vispy/scene/tests/__init__.py +0 -0
- vispy/scene/tests/test_canvas.py +119 -0
- vispy/scene/tests/test_node.py +142 -0
- vispy/scene/tests/test_visuals.py +141 -0
- vispy/scene/visuals.py +276 -0
- vispy/scene/widgets/__init__.py +18 -0
- vispy/scene/widgets/anchor.py +25 -0
- vispy/scene/widgets/axis.py +88 -0
- vispy/scene/widgets/colorbar.py +176 -0
- vispy/scene/widgets/console.py +351 -0
- vispy/scene/widgets/grid.py +509 -0
- vispy/scene/widgets/label.py +50 -0
- vispy/scene/widgets/tests/__init__.py +0 -0
- vispy/scene/widgets/tests/test_colorbar.py +47 -0
- vispy/scene/widgets/viewbox.py +199 -0
- vispy/scene/widgets/widget.py +478 -0
- vispy/testing/__init__.py +51 -0
- vispy/testing/_runners.py +448 -0
- vispy/testing/_testing.py +416 -0
- vispy/testing/image_tester.py +494 -0
- vispy/testing/rendered_array_tester.py +85 -0
- vispy/testing/tests/__init__.py +0 -0
- vispy/testing/tests/test_testing.py +20 -0
- vispy/util/__init__.py +32 -0
- vispy/util/bunch.py +15 -0
- vispy/util/check_environment.py +57 -0
- vispy/util/config.py +490 -0
- vispy/util/dpi/__init__.py +19 -0
- vispy/util/dpi/_linux.py +69 -0
- vispy/util/dpi/_quartz.py +26 -0
- vispy/util/dpi/_win32.py +34 -0
- vispy/util/dpi/tests/__init__.py +0 -0
- vispy/util/dpi/tests/test_dpi.py +16 -0
- vispy/util/eq.py +41 -0
- vispy/util/event.py +774 -0
- vispy/util/fetching.py +276 -0
- vispy/util/filter.py +44 -0
- vispy/util/fonts/__init__.py +14 -0
- vispy/util/fonts/_freetype.py +73 -0
- vispy/util/fonts/_quartz.py +192 -0
- vispy/util/fonts/_triage.py +36 -0
- vispy/util/fonts/_vispy_fonts.py +20 -0
- vispy/util/fonts/_win32.py +105 -0
- vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
- vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
- vispy/util/fonts/tests/__init__.py +0 -0
- vispy/util/fonts/tests/test_font.py +45 -0
- vispy/util/fourier.py +69 -0
- vispy/util/frozen.py +25 -0
- vispy/util/gallery_scraper.py +268 -0
- vispy/util/keys.py +91 -0
- vispy/util/logs.py +358 -0
- vispy/util/osmesa_gl.py +17 -0
- vispy/util/profiler.py +135 -0
- vispy/util/ptime.py +16 -0
- vispy/util/quaternion.py +229 -0
- vispy/util/svg/__init__.py +18 -0
- vispy/util/svg/base.py +20 -0
- vispy/util/svg/color.py +219 -0
- vispy/util/svg/element.py +51 -0
- vispy/util/svg/geometry.py +478 -0
- vispy/util/svg/group.py +66 -0
- vispy/util/svg/length.py +81 -0
- vispy/util/svg/number.py +25 -0
- vispy/util/svg/path.py +332 -0
- vispy/util/svg/shapes.py +57 -0
- vispy/util/svg/style.py +59 -0
- vispy/util/svg/svg.py +40 -0
- vispy/util/svg/transform.py +223 -0
- vispy/util/svg/transformable.py +28 -0
- vispy/util/svg/viewport.py +73 -0
- vispy/util/tests/__init__.py +0 -0
- vispy/util/tests/test_config.py +58 -0
- vispy/util/tests/test_docstring_parameters.py +123 -0
- vispy/util/tests/test_emitter_group.py +262 -0
- vispy/util/tests/test_event_emitter.py +743 -0
- vispy/util/tests/test_fourier.py +35 -0
- vispy/util/tests/test_gallery_scraper.py +112 -0
- vispy/util/tests/test_import.py +127 -0
- vispy/util/tests/test_key.py +22 -0
- vispy/util/tests/test_logging.py +45 -0
- vispy/util/tests/test_run.py +14 -0
- vispy/util/tests/test_transforms.py +42 -0
- vispy/util/tests/test_vispy.py +48 -0
- vispy/util/transforms.py +201 -0
- vispy/util/wrappers.py +155 -0
- vispy/version.py +21 -0
- vispy/visuals/__init__.py +50 -0
- vispy/visuals/_scalable_textures.py +487 -0
- vispy/visuals/axis.py +678 -0
- vispy/visuals/border.py +208 -0
- vispy/visuals/box.py +79 -0
- vispy/visuals/collections/__init__.py +30 -0
- vispy/visuals/collections/agg_fast_path_collection.py +219 -0
- vispy/visuals/collections/agg_path_collection.py +197 -0
- vispy/visuals/collections/agg_point_collection.py +52 -0
- vispy/visuals/collections/agg_segment_collection.py +142 -0
- vispy/visuals/collections/array_list.py +401 -0
- vispy/visuals/collections/base_collection.py +482 -0
- vispy/visuals/collections/collection.py +253 -0
- vispy/visuals/collections/path_collection.py +23 -0
- vispy/visuals/collections/point_collection.py +19 -0
- vispy/visuals/collections/polygon_collection.py +25 -0
- vispy/visuals/collections/raw_path_collection.py +119 -0
- vispy/visuals/collections/raw_point_collection.py +113 -0
- vispy/visuals/collections/raw_polygon_collection.py +77 -0
- vispy/visuals/collections/raw_segment_collection.py +112 -0
- vispy/visuals/collections/raw_triangle_collection.py +78 -0
- vispy/visuals/collections/segment_collection.py +19 -0
- vispy/visuals/collections/triangle_collection.py +16 -0
- vispy/visuals/collections/util.py +168 -0
- vispy/visuals/colorbar.py +699 -0
- vispy/visuals/cube.py +41 -0
- vispy/visuals/ellipse.py +162 -0
- vispy/visuals/filters/__init__.py +10 -0
- vispy/visuals/filters/base_filter.py +242 -0
- vispy/visuals/filters/clipper.py +60 -0
- vispy/visuals/filters/clipping_planes.py +122 -0
- vispy/visuals/filters/color.py +181 -0
- vispy/visuals/filters/markers.py +28 -0
- vispy/visuals/filters/mesh.py +801 -0
- vispy/visuals/filters/picking.py +60 -0
- vispy/visuals/filters/tests/__init__.py +3 -0
- vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
- vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
- vispy/visuals/glsl/__init__.py +1 -0
- vispy/visuals/glsl/antialiasing.py +133 -0
- vispy/visuals/glsl/color.py +63 -0
- vispy/visuals/graphs/__init__.py +1 -0
- vispy/visuals/graphs/graph.py +240 -0
- vispy/visuals/graphs/layouts/__init__.py +55 -0
- vispy/visuals/graphs/layouts/circular.py +49 -0
- vispy/visuals/graphs/layouts/force_directed.py +211 -0
- vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
- vispy/visuals/graphs/layouts/random.py +52 -0
- vispy/visuals/graphs/tests/__init__.py +1 -0
- vispy/visuals/graphs/tests/test_layouts.py +139 -0
- vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
- vispy/visuals/graphs/util.py +120 -0
- vispy/visuals/gridlines.py +161 -0
- vispy/visuals/gridmesh.py +98 -0
- vispy/visuals/histogram.py +58 -0
- vispy/visuals/image.py +701 -0
- vispy/visuals/image_complex.py +130 -0
- vispy/visuals/infinite_line.py +199 -0
- vispy/visuals/instanced_mesh.py +152 -0
- vispy/visuals/isocurve.py +213 -0
- vispy/visuals/isoline.py +241 -0
- vispy/visuals/isosurface.py +113 -0
- vispy/visuals/line/__init__.py +6 -0
- vispy/visuals/line/arrow.py +289 -0
- vispy/visuals/line/dash_atlas.py +90 -0
- vispy/visuals/line/line.py +545 -0
- vispy/visuals/line_plot.py +135 -0
- vispy/visuals/linear_region.py +199 -0
- vispy/visuals/markers.py +819 -0
- vispy/visuals/mesh.py +373 -0
- vispy/visuals/mesh_normals.py +159 -0
- vispy/visuals/plane.py +54 -0
- vispy/visuals/polygon.py +145 -0
- vispy/visuals/rectangle.py +196 -0
- vispy/visuals/regular_polygon.py +56 -0
- vispy/visuals/scrolling_lines.py +197 -0
- vispy/visuals/shaders/__init__.py +17 -0
- vispy/visuals/shaders/compiler.py +206 -0
- vispy/visuals/shaders/expression.py +99 -0
- vispy/visuals/shaders/function.py +788 -0
- vispy/visuals/shaders/multiprogram.py +145 -0
- vispy/visuals/shaders/parsing.py +140 -0
- vispy/visuals/shaders/program.py +161 -0
- vispy/visuals/shaders/shader_object.py +162 -0
- vispy/visuals/shaders/tests/__init__.py +0 -0
- vispy/visuals/shaders/tests/test_function.py +486 -0
- vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
- vispy/visuals/shaders/tests/test_parsing.py +57 -0
- vispy/visuals/shaders/variable.py +272 -0
- vispy/visuals/spectrogram.py +169 -0
- vispy/visuals/sphere.py +80 -0
- vispy/visuals/surface_plot.py +192 -0
- vispy/visuals/tests/__init__.py +0 -0
- vispy/visuals/tests/test_arrows.py +109 -0
- vispy/visuals/tests/test_axis.py +120 -0
- vispy/visuals/tests/test_collections.py +15 -0
- vispy/visuals/tests/test_colorbar.py +179 -0
- vispy/visuals/tests/test_colormap.py +97 -0
- vispy/visuals/tests/test_ellipse.py +122 -0
- vispy/visuals/tests/test_gridlines.py +30 -0
- vispy/visuals/tests/test_histogram.py +24 -0
- vispy/visuals/tests/test_image.py +392 -0
- vispy/visuals/tests/test_image_complex.py +36 -0
- vispy/visuals/tests/test_infinite_line.py +53 -0
- vispy/visuals/tests/test_instanced_mesh.py +50 -0
- vispy/visuals/tests/test_isosurface.py +22 -0
- vispy/visuals/tests/test_linear_region.py +152 -0
- vispy/visuals/tests/test_markers.py +54 -0
- vispy/visuals/tests/test_mesh.py +261 -0
- vispy/visuals/tests/test_mesh_normals.py +218 -0
- vispy/visuals/tests/test_polygon.py +112 -0
- vispy/visuals/tests/test_rectangle.py +163 -0
- vispy/visuals/tests/test_regular_polygon.py +111 -0
- vispy/visuals/tests/test_scalable_textures.py +196 -0
- vispy/visuals/tests/test_sdf.py +73 -0
- vispy/visuals/tests/test_spectrogram.py +42 -0
- vispy/visuals/tests/test_surface_plot.py +57 -0
- vispy/visuals/tests/test_text.py +95 -0
- vispy/visuals/tests/test_volume.py +542 -0
- vispy/visuals/tests/test_windbarb.py +33 -0
- vispy/visuals/text/__init__.py +7 -0
- vispy/visuals/text/_sdf_cpu.cpython-313-x86_64-linux-gnu.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +112 -0
- vispy/visuals/text/_sdf_gpu.py +316 -0
- vispy/visuals/text/text.py +675 -0
- vispy/visuals/transforms/__init__.py +34 -0
- vispy/visuals/transforms/_util.py +191 -0
- vispy/visuals/transforms/base_transform.py +233 -0
- vispy/visuals/transforms/chain.py +300 -0
- vispy/visuals/transforms/interactive.py +98 -0
- vispy/visuals/transforms/linear.py +564 -0
- vispy/visuals/transforms/nonlinear.py +398 -0
- vispy/visuals/transforms/tests/__init__.py +0 -0
- vispy/visuals/transforms/tests/test_transforms.py +243 -0
- vispy/visuals/transforms/transform_system.py +339 -0
- vispy/visuals/tube.py +173 -0
- vispy/visuals/visual.py +923 -0
- vispy/visuals/volume.py +1366 -0
- vispy/visuals/windbarb.py +291 -0
- vispy/visuals/xyz_axis.py +34 -0
- vispy-0.15.0.dist-info/METADATA +243 -0
- vispy-0.15.0.dist-info/RECORD +521 -0
- vispy-0.15.0.dist-info/WHEEL +6 -0
- vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
- vispy-0.15.0.dist-info/top_level.txt +1 -0
vispy/app/qt.py
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
3
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
4
|
+
|
|
5
|
+
# Force the selection of an application backend. If the user has already
|
|
6
|
+
# imported PyQt or PySide, this should result in selection of the corresponding
|
|
7
|
+
# backend.
|
|
8
|
+
from .backends import qt_lib
|
|
9
|
+
|
|
10
|
+
if qt_lib is None:
|
|
11
|
+
raise RuntimeError("Module backends._qt should not be imported directly.")
|
|
12
|
+
elif qt_lib in 'pyqt4':
|
|
13
|
+
from PyQt4 import QtGui
|
|
14
|
+
QWidget, QGridLayout = QtGui.QWidget, QtGui.QGridLayout # Compat
|
|
15
|
+
elif qt_lib == 'pyside':
|
|
16
|
+
from PySide import QtGui
|
|
17
|
+
QWidget, QGridLayout = QtGui.QWidget, QtGui.QGridLayout # Compat
|
|
18
|
+
elif qt_lib == 'pyqt5':
|
|
19
|
+
from PyQt5 import QtWidgets
|
|
20
|
+
QWidget, QGridLayout = QtWidgets.QWidget, QtWidgets.QGridLayout # Compat
|
|
21
|
+
elif qt_lib == 'pyqt6':
|
|
22
|
+
from PyQt6 import QtWidgets
|
|
23
|
+
QWidget, QGridLayout = QtWidgets.QWidget, QtWidgets.QGridLayout # Compat
|
|
24
|
+
elif qt_lib == 'pyside2':
|
|
25
|
+
from PySide2 import QtWidgets
|
|
26
|
+
QWidget, QGridLayout = QtWidgets.QWidget, QtWidgets.QGridLayout # Compat
|
|
27
|
+
elif qt_lib == 'pyside6':
|
|
28
|
+
from PySide6 import QtWidgets
|
|
29
|
+
QWidget, QGridLayout = QtWidgets.QWidget, QtWidgets.QGridLayout # Compat
|
|
30
|
+
elif qt_lib:
|
|
31
|
+
raise RuntimeError("Invalid value for qt_lib %r." % qt_lib)
|
|
32
|
+
else:
|
|
33
|
+
raise RuntimeError("Module backends._qt should not be imported directly.")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class QtCanvas(QWidget):
|
|
37
|
+
"""Qt widget containing a vispy Canvas.
|
|
38
|
+
|
|
39
|
+
This is a convenience class that allows a vispy canvas to be embedded
|
|
40
|
+
directly into a Qt application.
|
|
41
|
+
All methods and properties of the Canvas are wrapped by this class.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
parent : QWidget or None
|
|
46
|
+
The Qt parent to assign to this widget.
|
|
47
|
+
canvas : instance or subclass of Canvas
|
|
48
|
+
The vispy Canvas to display inside this widget, or a Canvas subclass
|
|
49
|
+
to instantiate using any remaining keyword arguments.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(self, parent=None, canvas=None, **kwargs):
|
|
53
|
+
from .canvas import Canvas
|
|
54
|
+
if canvas is None:
|
|
55
|
+
canvas = Canvas
|
|
56
|
+
if issubclass(canvas, Canvas):
|
|
57
|
+
canvas = canvas(**kwargs)
|
|
58
|
+
elif len(**kwargs) > 0:
|
|
59
|
+
raise TypeError('Invalid keyword arguments: %s' %
|
|
60
|
+
list(kwargs.keys()))
|
|
61
|
+
if not isinstance(canvas, Canvas):
|
|
62
|
+
raise TypeError('canvas argument must be an instance or subclass '
|
|
63
|
+
'of Canvas.')
|
|
64
|
+
|
|
65
|
+
QWidget.__init__(self, parent)
|
|
66
|
+
self.layout = QGridLayout()
|
|
67
|
+
self.setLayout(self.layout)
|
|
68
|
+
self.layout.setContentsMargins(0, 0, 0, 0)
|
|
69
|
+
self._canvas = canvas
|
|
70
|
+
self.layout.addWidget(canvas.native)
|
|
71
|
+
self.setSizePolicy(canvas.native.sizePolicy())
|
|
72
|
+
|
|
73
|
+
def __getattr__(self, attr):
|
|
74
|
+
if hasattr(self._canvas, attr):
|
|
75
|
+
return getattr(self._canvas, attr)
|
|
76
|
+
else:
|
|
77
|
+
raise AttributeError(attr)
|
|
78
|
+
|
|
79
|
+
def update(self):
|
|
80
|
+
"""Call update() on both this widget and the internal canvas."""
|
|
81
|
+
QWidget.update(self)
|
|
82
|
+
self._canvas.update()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class QtSceneCanvas(QtCanvas):
|
|
86
|
+
"""Convenience class embedding a vispy SceneCanvas inside a QWidget.
|
|
87
|
+
See QtCanvas.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __init__(self, parent=None, **kwargs):
|
|
91
|
+
from ..scene.canvas import SceneCanvas
|
|
92
|
+
QtCanvas.__init__(self, parent, canvas=SceneCanvas, **kwargs)
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ui version="4.0">
|
|
3
|
+
<class>Form</class>
|
|
4
|
+
<widget class="QWidget" name="Form">
|
|
5
|
+
<property name="geometry">
|
|
6
|
+
<rect>
|
|
7
|
+
<x>0</x>
|
|
8
|
+
<y>0</y>
|
|
9
|
+
<width>609</width>
|
|
10
|
+
<height>432</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Form</string>
|
|
15
|
+
</property>
|
|
16
|
+
<layout class="QGridLayout" name="gridLayout">
|
|
17
|
+
<item row="0" column="0">
|
|
18
|
+
<widget class="QLabel" name="label">
|
|
19
|
+
<property name="text">
|
|
20
|
+
<string>For testing that vispy Canvas can be embedded in Qt designer GUI</string>
|
|
21
|
+
</property>
|
|
22
|
+
</widget>
|
|
23
|
+
</item>
|
|
24
|
+
<item row="1" column="0">
|
|
25
|
+
<widget class="QFrame" name="frame">
|
|
26
|
+
<property name="frameShape">
|
|
27
|
+
<enum>QFrame::StyledPanel</enum>
|
|
28
|
+
</property>
|
|
29
|
+
<property name="frameShadow">
|
|
30
|
+
<enum>QFrame::Raised</enum>
|
|
31
|
+
</property>
|
|
32
|
+
<layout class="QGridLayout" name="gridLayout_2">
|
|
33
|
+
<item row="0" column="0">
|
|
34
|
+
<widget class="QtSceneCanvas" name="canvas" native="true">
|
|
35
|
+
<property name="sizePolicy">
|
|
36
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
37
|
+
<horstretch>0</horstretch>
|
|
38
|
+
<verstretch>0</verstretch>
|
|
39
|
+
</sizepolicy>
|
|
40
|
+
</property>
|
|
41
|
+
</widget>
|
|
42
|
+
</item>
|
|
43
|
+
</layout>
|
|
44
|
+
</widget>
|
|
45
|
+
</item>
|
|
46
|
+
</layout>
|
|
47
|
+
</widget>
|
|
48
|
+
<customwidgets>
|
|
49
|
+
<customwidget>
|
|
50
|
+
<class>QtSceneCanvas</class>
|
|
51
|
+
<extends>QWidget</extends>
|
|
52
|
+
<header>vispy.app.qt</header>
|
|
53
|
+
<container>1</container>
|
|
54
|
+
</customwidget>
|
|
55
|
+
</customwidgets>
|
|
56
|
+
<resources/>
|
|
57
|
+
<connections/>
|
|
58
|
+
</ui>
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from collections import namedtuple
|
|
3
|
+
from io import StringIO
|
|
4
|
+
from time import sleep
|
|
5
|
+
import gc
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from numpy.testing import assert_array_equal
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from vispy.app import use_app, Canvas, Timer, MouseEvent, KeyEvent
|
|
12
|
+
from vispy.app.base import BaseApplicationBackend
|
|
13
|
+
from vispy.testing import (requires_application, SkipTest, assert_is,
|
|
14
|
+
assert_in, run_tests_if_main,
|
|
15
|
+
assert_equal, assert_true, assert_raises, IS_TRAVIS_CI)
|
|
16
|
+
from vispy.util import keys, use_log_level
|
|
17
|
+
|
|
18
|
+
from vispy.gloo.program import (Program, VertexBuffer, IndexBuffer)
|
|
19
|
+
from vispy.gloo.util import _screenshot
|
|
20
|
+
from vispy.gloo import gl
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
gl.use_gl('gl2 debug')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def on_nonexist(self, *args):
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def on_mouse_move(self, *args):
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _on_mouse_move(self, *args):
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _test_callbacks(canvas):
|
|
39
|
+
"""Tests input capabilities, triaging based on backend"""
|
|
40
|
+
backend_name = canvas._app.backend_name
|
|
41
|
+
backend = canvas._backend
|
|
42
|
+
if backend_name.lower() == 'pyglet':
|
|
43
|
+
# Test Pyglet callbacks can take reasonable args
|
|
44
|
+
backend.on_resize(100, 100)
|
|
45
|
+
backend.our_draw_func()
|
|
46
|
+
backend.on_mouse_press(10, 10, 1)
|
|
47
|
+
backend.on_mouse_release(10, 11, 1)
|
|
48
|
+
backend.on_mouse_motion(10, 12, 0, 1)
|
|
49
|
+
backend.on_mouse_drag(10, 13, 0, 1, 1, 0)
|
|
50
|
+
backend.on_mouse_scroll(10, 13, 1, 1)
|
|
51
|
+
backend.on_key_press(10, 0)
|
|
52
|
+
backend.on_key_release(10, 0)
|
|
53
|
+
backend.on_text('foo')
|
|
54
|
+
elif backend_name.lower() == 'glfw':
|
|
55
|
+
# Test GLFW callbacks can take reasonable args
|
|
56
|
+
_id = backend._id
|
|
57
|
+
backend._on_draw(_id)
|
|
58
|
+
backend._on_resize(_id, 100, 100)
|
|
59
|
+
|
|
60
|
+
backend._on_key_press(_id, 340, 340, 1, 0) # Shift.
|
|
61
|
+
backend._on_key_press(_id, 50, 50, 1, 0) # 2
|
|
62
|
+
backend._on_key_char(_id, 50)
|
|
63
|
+
backend._on_key_press(_id, 50, 50, 0, 0)
|
|
64
|
+
backend._on_key_press(_id, 340, 340, 0, 0)
|
|
65
|
+
|
|
66
|
+
backend._on_key_press(_id, 65, 65, 1, 0) # Plain A
|
|
67
|
+
backend._on_key_char(_id, 197) # Unicode A.
|
|
68
|
+
backend._on_key_char(_id, 197) # Repeat A.
|
|
69
|
+
backend._on_key_press(_id, 65, 65, 0, 0)
|
|
70
|
+
|
|
71
|
+
backend._on_mouse_button(_id, 1, 1, 0)
|
|
72
|
+
backend._on_mouse_scroll(_id, 1, 0)
|
|
73
|
+
backend._on_mouse_motion(_id, 10, 10)
|
|
74
|
+
backend._on_close(_id)
|
|
75
|
+
elif any(x in backend_name.lower() for x in ('qt', 'pyside')):
|
|
76
|
+
# constructing fake Qt events is too hard :(
|
|
77
|
+
pass
|
|
78
|
+
elif 'sdl2' in backend_name.lower():
|
|
79
|
+
event = namedtuple('event', ['type', 'window', 'motion', 'button',
|
|
80
|
+
'wheel', 'key'])
|
|
81
|
+
event.type = 512 # WINDOWEVENT
|
|
82
|
+
event.window = namedtuple('window', ['event', 'data1', 'data2'])
|
|
83
|
+
event.motion = namedtuple('motion', ['x', 'y'])
|
|
84
|
+
event.button = namedtuple('button', ['x', 'y', 'button'])
|
|
85
|
+
event.wheel = namedtuple('wheel', ['x', 'y'])
|
|
86
|
+
event.key = namedtuple('key', ['keysym'])
|
|
87
|
+
event.key.keysym = namedtuple('keysym', ['mod', 'sym'])
|
|
88
|
+
|
|
89
|
+
event.window.event = 5 # WINDOWEVENT_RESIZED
|
|
90
|
+
event.window.data1 = 10
|
|
91
|
+
event.window.data2 = 20
|
|
92
|
+
backend._on_event(event)
|
|
93
|
+
|
|
94
|
+
event.type = 1024 # SDL_MOUSEMOTION
|
|
95
|
+
event.motion.x, event.motion.y = 1, 1
|
|
96
|
+
backend._on_event(event)
|
|
97
|
+
|
|
98
|
+
event.type = 1025 # MOUSEBUTTONDOWN
|
|
99
|
+
event.button.x, event.button.y, event.button.button = 1, 1, 1
|
|
100
|
+
backend._on_event(event)
|
|
101
|
+
event.type = 1026 # MOUSEBUTTONUP
|
|
102
|
+
backend._on_event(event)
|
|
103
|
+
|
|
104
|
+
event.type = 1027 # sdl2.SDL_MOUSEWHEEL
|
|
105
|
+
event.wheel.x, event.wheel.y = 0, 1
|
|
106
|
+
backend._on_event(event)
|
|
107
|
+
|
|
108
|
+
event.type = 768 # SDL_KEYDOWN
|
|
109
|
+
event.key.keysym.mod = 1073742049 # SLDK_LSHIFT
|
|
110
|
+
event.key.keysym.sym = 1073741906 # SDLK_UP
|
|
111
|
+
backend._on_event(event)
|
|
112
|
+
event.type = 769 # SDL_KEYUP
|
|
113
|
+
backend._on_event(event)
|
|
114
|
+
elif 'wx' in backend_name.lower():
|
|
115
|
+
# Constructing fake wx events is too hard
|
|
116
|
+
pass
|
|
117
|
+
elif 'osmesa' in backend_name.lower():
|
|
118
|
+
# No events for osmesa backend
|
|
119
|
+
pass
|
|
120
|
+
elif 'tk' in backend_name.lower():
|
|
121
|
+
event = namedtuple("event", [
|
|
122
|
+
"serial", "time", "type", "widget",
|
|
123
|
+
"width", "height",
|
|
124
|
+
"char", "keycode", "keysym", "keysym_num", "state",
|
|
125
|
+
"x", "y", "x_root", "y_root", "num", "delta"
|
|
126
|
+
])
|
|
127
|
+
|
|
128
|
+
event.width, event.height = 10, 20
|
|
129
|
+
backend._on_configure(event) # RESIZE
|
|
130
|
+
|
|
131
|
+
event.x, event.y, event.state = 1, 1, 0x0
|
|
132
|
+
backend._on_mouse_enter(event)
|
|
133
|
+
backend._on_mouse_move(event)
|
|
134
|
+
|
|
135
|
+
event.x, event.y, event.num = 1, 1, 1
|
|
136
|
+
backend._on_mouse_button_press(event)
|
|
137
|
+
backend._on_mouse_button_release(event)
|
|
138
|
+
backend._on_mouse_double_button_press(event)
|
|
139
|
+
|
|
140
|
+
event.delta = 120
|
|
141
|
+
backend._on_mouse_wheel(event)
|
|
142
|
+
|
|
143
|
+
event.keysym_num, event.keycode, event.state = 65362, 0, 0x0001 # SHIFT+UP
|
|
144
|
+
backend._on_key_down(event)
|
|
145
|
+
backend._on_key_up(event)
|
|
146
|
+
else:
|
|
147
|
+
raise ValueError
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@requires_application()
|
|
151
|
+
def test_run():
|
|
152
|
+
"""Test app running"""
|
|
153
|
+
for _ in range(2):
|
|
154
|
+
with Canvas(size=(100, 100), show=True, title='run') as c:
|
|
155
|
+
@c.events.draw.connect
|
|
156
|
+
def draw(event):
|
|
157
|
+
print(event) # test event __repr__
|
|
158
|
+
c.app.quit()
|
|
159
|
+
c.update()
|
|
160
|
+
c.app.run()
|
|
161
|
+
c.app.quit() # make sure it doesn't break if a user quits twice
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@requires_application()
|
|
165
|
+
def test_capability():
|
|
166
|
+
"""Test application capability enumeration"""
|
|
167
|
+
non_default_vals = dict(title='foo', size=[100, 100], position=[0, 0],
|
|
168
|
+
show=True, decorate=False, resizable=False,
|
|
169
|
+
vsync=True) # context is tested elsewhere
|
|
170
|
+
good_kwargs = dict()
|
|
171
|
+
bad_kwargs = dict()
|
|
172
|
+
with Canvas() as c:
|
|
173
|
+
for key, val in c.app.backend_module.capability.items():
|
|
174
|
+
if key in non_default_vals:
|
|
175
|
+
if val:
|
|
176
|
+
good_kwargs[key] = non_default_vals[key]
|
|
177
|
+
else:
|
|
178
|
+
bad_kwargs[key] = non_default_vals[key]
|
|
179
|
+
# bug on 3.3.1
|
|
180
|
+
# https://github.com/glfw/glfw/issues/1620
|
|
181
|
+
if c.app.backend_name == 'Glfw' and \
|
|
182
|
+
c.app.backend_module.glfw.__version__ == (3, 3, 1):
|
|
183
|
+
good_kwargs.pop('decorate')
|
|
184
|
+
# ensure all settable values can be set
|
|
185
|
+
with Canvas(**good_kwargs):
|
|
186
|
+
# some of these are hard to test, and the ones that are easy are
|
|
187
|
+
# tested elsewhere, so let's just make sure it runs here
|
|
188
|
+
pass
|
|
189
|
+
# ensure that *any* bad argument gets caught
|
|
190
|
+
for key, val in bad_kwargs.items():
|
|
191
|
+
assert_raises(RuntimeError, Canvas, **{key: val})
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@requires_application()
|
|
195
|
+
def test_application():
|
|
196
|
+
"""Test application running"""
|
|
197
|
+
app = use_app()
|
|
198
|
+
print(app) # __repr__ without app
|
|
199
|
+
app.create()
|
|
200
|
+
wrong = 'glfw' if app.backend_name.lower() != 'glfw' else 'pyqt5'
|
|
201
|
+
assert_raises(RuntimeError, use_app, wrong)
|
|
202
|
+
app.process_events()
|
|
203
|
+
print(app) # test __repr__
|
|
204
|
+
|
|
205
|
+
assert_raises(ValueError, Canvas, keys='foo')
|
|
206
|
+
assert_raises(TypeError, Canvas, keys=dict(escape=1))
|
|
207
|
+
assert_raises(ValueError, Canvas, keys=dict(escape='foo')) # not an attr
|
|
208
|
+
|
|
209
|
+
pos = [0, 0] if app.backend_module.capability['position'] else None
|
|
210
|
+
size = (100, 100)
|
|
211
|
+
# Use "with" statement so failures don't leave open window
|
|
212
|
+
# (and test context manager behavior)
|
|
213
|
+
title = 'default'
|
|
214
|
+
with Canvas(title=title, size=size, app=app, show=True,
|
|
215
|
+
position=pos) as canvas:
|
|
216
|
+
context = canvas.context
|
|
217
|
+
assert_true(canvas.create_native() is None) # should be done already
|
|
218
|
+
assert_is(canvas.app, app)
|
|
219
|
+
assert_true(canvas.native)
|
|
220
|
+
assert_equal('swap_buffers', canvas.events.draw.callback_refs[-1])
|
|
221
|
+
|
|
222
|
+
canvas.measure_fps(0.001)
|
|
223
|
+
sleep(0.002)
|
|
224
|
+
canvas.update()
|
|
225
|
+
app.process_events()
|
|
226
|
+
assert_true(canvas.fps > 0)
|
|
227
|
+
|
|
228
|
+
# Other methods
|
|
229
|
+
print(canvas) # __repr__
|
|
230
|
+
assert_equal(canvas.title, title)
|
|
231
|
+
canvas.title = 'you'
|
|
232
|
+
with use_log_level('warning', record=True, print_msg=False):
|
|
233
|
+
if app.backend_module.capability['position']:
|
|
234
|
+
# todo: disable more tests based on capability
|
|
235
|
+
canvas.position = pos
|
|
236
|
+
canvas.size = size
|
|
237
|
+
canvas.connect(on_mouse_move)
|
|
238
|
+
assert_raises(ValueError, canvas.connect, _on_mouse_move)
|
|
239
|
+
if sys.platform != 'darwin': # XXX knownfail, prob. needs warmup
|
|
240
|
+
canvas.show(False)
|
|
241
|
+
canvas.show()
|
|
242
|
+
app.process_events()
|
|
243
|
+
assert_raises(ValueError, canvas.connect, on_nonexist)
|
|
244
|
+
# deprecation of "paint"
|
|
245
|
+
with use_log_level('info', record=True, print_msg=False) as log:
|
|
246
|
+
olderr = sys.stderr
|
|
247
|
+
try:
|
|
248
|
+
fid = StringIO()
|
|
249
|
+
sys.stderr = fid
|
|
250
|
+
|
|
251
|
+
@canvas.events.paint.connect
|
|
252
|
+
def fake(event):
|
|
253
|
+
pass
|
|
254
|
+
finally:
|
|
255
|
+
sys.stderr = olderr
|
|
256
|
+
assert_equal(len(log), 1)
|
|
257
|
+
assert_in('deprecated', log[0])
|
|
258
|
+
|
|
259
|
+
# screenshots
|
|
260
|
+
gl.glViewport(0, 0, *size)
|
|
261
|
+
ss = _screenshot()
|
|
262
|
+
assert_array_equal(ss.shape, size + (4,))
|
|
263
|
+
assert_equal(len(canvas._backend._vispy_get_geometry()), 4)
|
|
264
|
+
if sys.platform != 'win32': # XXX knownfail for windows
|
|
265
|
+
assert_array_equal(canvas.size, size)
|
|
266
|
+
assert_equal(len(canvas.position), 2) # XXX knownfail, doesn't "take"
|
|
267
|
+
|
|
268
|
+
# GLOO: should have an OpenGL context already, so these should work
|
|
269
|
+
vert = "void main (void) {gl_Position = pos;}"
|
|
270
|
+
frag = "void main (void) {gl_FragColor = pos;}"
|
|
271
|
+
program = Program(vert, frag)
|
|
272
|
+
assert_raises(RuntimeError, program.glir.flush, context.shared.parser)
|
|
273
|
+
|
|
274
|
+
vert = "uniform vec4 pos;\nvoid main (void) {gl_Position = pos;}"
|
|
275
|
+
frag = "uniform vec4 pos;\nvoid main (void) {gl_FragColor = pos;}"
|
|
276
|
+
program = Program(vert, frag)
|
|
277
|
+
# uniform = program.uniforms[0]
|
|
278
|
+
program['pos'] = [1, 2, 3, 4]
|
|
279
|
+
|
|
280
|
+
vert = "attribute vec4 pos;\nvoid main (void) {gl_Position = pos;}"
|
|
281
|
+
frag = "void main (void) {}"
|
|
282
|
+
program = Program(vert, frag)
|
|
283
|
+
# attribute = program.attributes[0]
|
|
284
|
+
program["pos"] = [1, 2, 3, 4]
|
|
285
|
+
|
|
286
|
+
# use a real program
|
|
287
|
+
program._glir.clear()
|
|
288
|
+
vert = ("uniform mat4 u_model;"
|
|
289
|
+
"attribute vec2 a_position; attribute vec4 a_color;"
|
|
290
|
+
"varying vec4 v_color;"
|
|
291
|
+
"void main (void) {v_color = a_color;"
|
|
292
|
+
"gl_Position = u_model * vec4(a_position, 0.0, 1.0);"
|
|
293
|
+
"v_color = a_color;}")
|
|
294
|
+
frag = "void main() {gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);}"
|
|
295
|
+
n, p = 250, 50
|
|
296
|
+
T = np.random.uniform(0, 2 * np.pi, n)
|
|
297
|
+
position = np.zeros((n, 2), dtype=np.float32)
|
|
298
|
+
position[:, 0] = np.cos(T)
|
|
299
|
+
position[:, 1] = np.sin(T)
|
|
300
|
+
color = np.ones((n, 4), dtype=np.float32) * (1, 1, 1, 1)
|
|
301
|
+
data = np.zeros(n * p, [('a_position', np.float32, 2),
|
|
302
|
+
('a_color', np.float32, 4)])
|
|
303
|
+
data['a_position'] = np.repeat(position, p, axis=0)
|
|
304
|
+
data['a_color'] = np.repeat(color, p, axis=0)
|
|
305
|
+
|
|
306
|
+
program = Program(vert, frag)
|
|
307
|
+
program.bind(VertexBuffer(data))
|
|
308
|
+
program['u_model'] = np.eye(4, dtype=np.float32)
|
|
309
|
+
# different codepath if no call to activate()
|
|
310
|
+
program.draw(gl.GL_POINTS)
|
|
311
|
+
subset = IndexBuffer(np.arange(10, dtype=np.uint32))
|
|
312
|
+
program.draw(gl.GL_POINTS, subset)
|
|
313
|
+
|
|
314
|
+
# bad programs
|
|
315
|
+
frag_bad = ("varying vec4 v_colors") # no semicolon
|
|
316
|
+
program = Program(vert, frag_bad)
|
|
317
|
+
assert_raises(RuntimeError, program.glir.flush, context.shared.parser)
|
|
318
|
+
frag_bad = None # no fragment code. no main is not always enough
|
|
319
|
+
assert_raises(ValueError, Program, vert, frag_bad)
|
|
320
|
+
|
|
321
|
+
# Timer
|
|
322
|
+
timer = Timer(interval=0.001, connect=on_mouse_move, iterations=2,
|
|
323
|
+
start=True, app=app)
|
|
324
|
+
timer.start()
|
|
325
|
+
timer.interval = 0.002
|
|
326
|
+
assert_equal(timer.interval, 0.002)
|
|
327
|
+
assert_true(timer.running)
|
|
328
|
+
sleep(.003)
|
|
329
|
+
assert_true(timer.elapsed >= 0.002)
|
|
330
|
+
timer.stop()
|
|
331
|
+
assert_true(not timer.running)
|
|
332
|
+
assert_true(timer.native)
|
|
333
|
+
timer.disconnect()
|
|
334
|
+
|
|
335
|
+
# test that callbacks take reasonable inputs
|
|
336
|
+
_test_callbacks(canvas)
|
|
337
|
+
|
|
338
|
+
# cleanup
|
|
339
|
+
canvas.swap_buffers()
|
|
340
|
+
canvas.update()
|
|
341
|
+
app.process_events()
|
|
342
|
+
# put this in even though __exit__ will call it to make sure we don't
|
|
343
|
+
# have problems calling it multiple times
|
|
344
|
+
canvas.close() # done by context
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
@requires_application()
|
|
348
|
+
def test_fs():
|
|
349
|
+
"""Test fullscreen support"""
|
|
350
|
+
a = use_app()
|
|
351
|
+
if not a.backend_module.capability['fullscreen']:
|
|
352
|
+
return
|
|
353
|
+
assert_raises(TypeError, Canvas, fullscreen='foo')
|
|
354
|
+
if (a.backend_name.lower() == 'glfw' or
|
|
355
|
+
(a.backend_name.lower() == 'sdl2' and sys.platform == 'darwin')):
|
|
356
|
+
raise SkipTest('Backend takes over screen')
|
|
357
|
+
with use_log_level('warning', record=True, print_msg=False) as emit_list:
|
|
358
|
+
with Canvas(fullscreen=False) as c:
|
|
359
|
+
assert_equal(c.fullscreen, False)
|
|
360
|
+
c.fullscreen = True
|
|
361
|
+
assert_equal(c.fullscreen, True)
|
|
362
|
+
assert_equal(len(emit_list), 0)
|
|
363
|
+
with use_log_level('warning', record=True, print_msg=False):
|
|
364
|
+
# some backends print a warning b/c fullscreen can't be specified
|
|
365
|
+
with Canvas(fullscreen=True) as c:
|
|
366
|
+
assert_equal(c.fullscreen, True)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
@requires_application()
|
|
370
|
+
def test_close_keys():
|
|
371
|
+
"""Test close keys"""
|
|
372
|
+
c = Canvas(keys='interactive')
|
|
373
|
+
x = list()
|
|
374
|
+
|
|
375
|
+
@c.events.close.connect
|
|
376
|
+
def closer(event):
|
|
377
|
+
x.append('done')
|
|
378
|
+
c.events.key_press(key=keys.ESCAPE, text='', modifiers=[])
|
|
379
|
+
assert_equal(len(x), 1) # ensure the close event was sent
|
|
380
|
+
c.app.process_events()
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
@pytest.mark.skipif(IS_TRAVIS_CI and 'darwin' in sys.platform,
|
|
384
|
+
reason='Travis OSX causes segmentation fault on this test for an unknown reason.')
|
|
385
|
+
@requires_application()
|
|
386
|
+
def test_event_order():
|
|
387
|
+
"""Test event order"""
|
|
388
|
+
x = list()
|
|
389
|
+
|
|
390
|
+
class MyCanvas(Canvas):
|
|
391
|
+
def on_initialize(self, event):
|
|
392
|
+
x.append('init')
|
|
393
|
+
|
|
394
|
+
def on_draw(self, event):
|
|
395
|
+
sz = True if self.size is not None else False
|
|
396
|
+
x.append('draw size=%s show=%s' % (sz, show))
|
|
397
|
+
|
|
398
|
+
def on_close(self, event):
|
|
399
|
+
x.append('close')
|
|
400
|
+
|
|
401
|
+
for show in (False, True):
|
|
402
|
+
# clear our storage variable
|
|
403
|
+
while x:
|
|
404
|
+
x.pop()
|
|
405
|
+
with MyCanvas(show=show) as c:
|
|
406
|
+
c.update()
|
|
407
|
+
c.app.process_events()
|
|
408
|
+
|
|
409
|
+
print(x)
|
|
410
|
+
assert_true(len(x) >= 3)
|
|
411
|
+
assert_equal(x[0], 'init')
|
|
412
|
+
assert_in('draw size=True', x[1])
|
|
413
|
+
assert_in('draw size=True', x[-2])
|
|
414
|
+
assert_equal(x[-1], 'close')
|
|
415
|
+
del c
|
|
416
|
+
gc.collect()
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def test_abstract():
|
|
420
|
+
"""Test app abstract template"""
|
|
421
|
+
app = BaseApplicationBackend()
|
|
422
|
+
for fun in (app._vispy_get_backend_name, app._vispy_process_events,
|
|
423
|
+
app._vispy_run, app._vispy_quit):
|
|
424
|
+
assert_raises(NotImplementedError, fun)
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def test_mouse_key_events():
|
|
428
|
+
"""Test mouse and key events"""
|
|
429
|
+
me = MouseEvent('mouse_press')
|
|
430
|
+
for fun in (me.pos, me.button, me.buttons, me.modifiers, me.delta,
|
|
431
|
+
me.press_event, me.last_event, me.is_dragging):
|
|
432
|
+
fun
|
|
433
|
+
me.drag_events()
|
|
434
|
+
me._forget_last_event()
|
|
435
|
+
me.trail()
|
|
436
|
+
ke = KeyEvent('key_release')
|
|
437
|
+
ke.key
|
|
438
|
+
ke.text
|
|
439
|
+
ke.modifiers
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
run_tests_if_main()
|