vispy 0.14.0__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.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 +968 -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 +1134 -0
- vispy/color/tests/__init__.py +0 -0
- vispy/color/tests/test_color.py +352 -0
- vispy/conftest.py +12 -0
- vispy/ext/__init__.py +0 -0
- vispy/ext/cocoapy.py +1542 -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 +134 -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 +698 -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 +506 -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 +566 -0
- vispy/gloo/gl/tests/test_names.py +246 -0
- vispy/gloo/gl/tests/test_use.py +71 -0
- vispy/gloo/glir.py +1816 -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 +1045 -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 +106 -0
- vispy/scene/cameras/base_camera.py +538 -0
- vispy/scene/cameras/fly.py +474 -0
- vispy/scene/cameras/magnify.py +163 -0
- vispy/scene/cameras/panzoom.py +308 -0
- vispy/scene/cameras/perspective.py +333 -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 +173 -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 +446 -0
- vispy/testing/_testing.py +416 -0
- vispy/testing/image_tester.py +473 -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 +17 -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 +4 -0
- vispy/visuals/__init__.py +50 -0
- vispy/visuals/_scalable_textures.py +485 -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 +163 -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 +796 -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 +105 -0
- vispy/visuals/gridmesh.py +98 -0
- vispy/visuals/histogram.py +58 -0
- vispy/visuals/image.py +688 -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 +810 -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_histogram.py +24 -0
- vispy/visuals/tests/test_image.py +390 -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 +180 -0
- vispy/visuals/tests/test_sdf.py +73 -0
- vispy/visuals/tests/test_spectrogram.py +42 -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-312-aarch64-linux-gnu.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +110 -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 +1335 -0
- vispy/visuals/windbarb.py +291 -0
- vispy/visuals/xyz_axis.py +34 -0
- vispy-0.14.0.dist-info/LICENSE.txt +36 -0
- vispy-0.14.0.dist-info/METADATA +218 -0
- vispy-0.14.0.dist-info/RECORD +519 -0
- vispy-0.14.0.dist-info/WHEEL +6 -0
- vispy-0.14.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,476 @@
|
|
|
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
|
+
"""vispy backend for wxPython."""
|
|
6
|
+
|
|
7
|
+
from __future__ import division
|
|
8
|
+
|
|
9
|
+
from time import sleep
|
|
10
|
+
import gc
|
|
11
|
+
import warnings
|
|
12
|
+
|
|
13
|
+
from ..base import (BaseApplicationBackend, BaseCanvasBackend,
|
|
14
|
+
BaseTimerBackend)
|
|
15
|
+
from ...util import keys, logger
|
|
16
|
+
from ...util.ptime import time
|
|
17
|
+
from ... import config
|
|
18
|
+
|
|
19
|
+
USE_EGL = config['gl_backend'].lower().startswith('es')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# -------------------------------------------------------------------- init ---
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
# avoid silly locale warning on OSX
|
|
26
|
+
with warnings.catch_warnings(record=True):
|
|
27
|
+
import wx
|
|
28
|
+
from wx import glcanvas
|
|
29
|
+
from wx.glcanvas import GLCanvas
|
|
30
|
+
|
|
31
|
+
# Map native keys to vispy keys
|
|
32
|
+
KEYMAP = {
|
|
33
|
+
wx.WXK_SHIFT: keys.SHIFT,
|
|
34
|
+
wx.WXK_CONTROL: keys.CONTROL,
|
|
35
|
+
wx.WXK_ALT: keys.ALT,
|
|
36
|
+
wx.WXK_WINDOWS_MENU: keys.META,
|
|
37
|
+
|
|
38
|
+
wx.WXK_LEFT: keys.LEFT,
|
|
39
|
+
wx.WXK_UP: keys.UP,
|
|
40
|
+
wx.WXK_RIGHT: keys.RIGHT,
|
|
41
|
+
wx.WXK_DOWN: keys.DOWN,
|
|
42
|
+
wx.WXK_PAGEUP: keys.PAGEUP,
|
|
43
|
+
wx.WXK_PAGEDOWN: keys.PAGEDOWN,
|
|
44
|
+
|
|
45
|
+
wx.WXK_INSERT: keys.INSERT,
|
|
46
|
+
wx.WXK_DELETE: keys.DELETE,
|
|
47
|
+
wx.WXK_HOME: keys.HOME,
|
|
48
|
+
wx.WXK_END: keys.END,
|
|
49
|
+
|
|
50
|
+
wx.WXK_ESCAPE: keys.ESCAPE,
|
|
51
|
+
wx.WXK_BACK: keys.BACKSPACE,
|
|
52
|
+
|
|
53
|
+
wx.WXK_F1: keys.F1,
|
|
54
|
+
wx.WXK_F2: keys.F2,
|
|
55
|
+
wx.WXK_F3: keys.F3,
|
|
56
|
+
wx.WXK_F4: keys.F4,
|
|
57
|
+
wx.WXK_F5: keys.F5,
|
|
58
|
+
wx.WXK_F6: keys.F6,
|
|
59
|
+
wx.WXK_F7: keys.F7,
|
|
60
|
+
wx.WXK_F8: keys.F8,
|
|
61
|
+
wx.WXK_F9: keys.F9,
|
|
62
|
+
wx.WXK_F10: keys.F10,
|
|
63
|
+
wx.WXK_F11: keys.F11,
|
|
64
|
+
wx.WXK_F12: keys.F12,
|
|
65
|
+
|
|
66
|
+
wx.WXK_SPACE: keys.SPACE,
|
|
67
|
+
wx.WXK_RETURN: keys.ENTER, # == pyglet.window.key.RETURN
|
|
68
|
+
wx.WXK_NUMPAD_ENTER: keys.ENTER,
|
|
69
|
+
wx.WXK_TAB: keys.TAB,
|
|
70
|
+
}
|
|
71
|
+
except Exception as exp:
|
|
72
|
+
available, testable, why_not, which = False, False, str(exp), None
|
|
73
|
+
|
|
74
|
+
class GLCanvas(object):
|
|
75
|
+
pass
|
|
76
|
+
else:
|
|
77
|
+
if USE_EGL:
|
|
78
|
+
available, testable, why_not = False, False, 'EGL not supported'
|
|
79
|
+
else:
|
|
80
|
+
available, testable, why_not = True, True, None
|
|
81
|
+
which = 'wxPython ' + str(wx.__version__)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# -------------------------------------------------------------- capability ---
|
|
85
|
+
|
|
86
|
+
capability = dict( # things that can be set by the backend
|
|
87
|
+
title=True,
|
|
88
|
+
size=True,
|
|
89
|
+
position=True,
|
|
90
|
+
show=True,
|
|
91
|
+
vsync=True,
|
|
92
|
+
resizable=True,
|
|
93
|
+
decorate=True,
|
|
94
|
+
fullscreen=True,
|
|
95
|
+
context=True,
|
|
96
|
+
multi_window=True,
|
|
97
|
+
scroll=True,
|
|
98
|
+
parent=True,
|
|
99
|
+
always_on_top=True,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# ------------------------------------------------------- set_configuration ---
|
|
104
|
+
|
|
105
|
+
def _set_config(c):
|
|
106
|
+
"""Set gl configuration"""
|
|
107
|
+
gl_attribs = [glcanvas.WX_GL_RGBA,
|
|
108
|
+
glcanvas.WX_GL_DEPTH_SIZE, c['depth_size'],
|
|
109
|
+
glcanvas.WX_GL_STENCIL_SIZE, c['stencil_size'],
|
|
110
|
+
glcanvas.WX_GL_MIN_RED, c['red_size'],
|
|
111
|
+
glcanvas.WX_GL_MIN_GREEN, c['green_size'],
|
|
112
|
+
glcanvas.WX_GL_MIN_BLUE, c['blue_size'],
|
|
113
|
+
glcanvas.WX_GL_MIN_ALPHA, c['alpha_size']]
|
|
114
|
+
gl_attribs += [glcanvas.WX_GL_DOUBLEBUFFER] if c['double_buffer'] else []
|
|
115
|
+
gl_attribs += [glcanvas.WX_GL_STEREO] if c['stereo'] else []
|
|
116
|
+
return gl_attribs
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# ------------------------------------------------------------- application ---
|
|
120
|
+
|
|
121
|
+
_wx_app = None
|
|
122
|
+
_timers = []
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class ApplicationBackend(BaseApplicationBackend):
|
|
126
|
+
|
|
127
|
+
def __init__(self):
|
|
128
|
+
BaseApplicationBackend.__init__(self)
|
|
129
|
+
self._event_loop = wx.GUIEventLoop()
|
|
130
|
+
wx.EventLoop.SetActive(self._event_loop)
|
|
131
|
+
|
|
132
|
+
def _vispy_get_backend_name(self):
|
|
133
|
+
return 'wx'
|
|
134
|
+
|
|
135
|
+
def _vispy_process_events(self):
|
|
136
|
+
# inpsired by https://github.com/wxWidgets/wxPython/blob/master/
|
|
137
|
+
# samples/mainloop/mainloop.py
|
|
138
|
+
for _ in range(3): # trial-and-error found this to work (!)
|
|
139
|
+
while self._event_loop.Pending():
|
|
140
|
+
self._event_loop.Dispatch()
|
|
141
|
+
if hasattr(_wx_app, 'ProcessIdle'):
|
|
142
|
+
_wx_app.ProcessIdle()
|
|
143
|
+
else:
|
|
144
|
+
self._event_loop.ProcessIdle()
|
|
145
|
+
sleep(0.01)
|
|
146
|
+
|
|
147
|
+
def _vispy_run(self):
|
|
148
|
+
return _wx_app.MainLoop()
|
|
149
|
+
|
|
150
|
+
def _vispy_quit(self):
|
|
151
|
+
global _wx_app
|
|
152
|
+
_wx_app.ExitMainLoop()
|
|
153
|
+
|
|
154
|
+
def _vispy_get_native_app(self):
|
|
155
|
+
# Get native app in save way. Taken from guisupport.py
|
|
156
|
+
global _wx_app
|
|
157
|
+
_wx_app = wx.GetApp() # in case the user already has one
|
|
158
|
+
if _wx_app is None:
|
|
159
|
+
if hasattr(wx, 'App'):
|
|
160
|
+
_wx_app = wx.App()
|
|
161
|
+
else:
|
|
162
|
+
# legacy wx
|
|
163
|
+
_wx_app = wx.PySimpleApp()
|
|
164
|
+
_wx_app.SetExitOnFrameDelete(True)
|
|
165
|
+
return _wx_app
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# ------------------------------------------------------------------ canvas ---
|
|
169
|
+
|
|
170
|
+
def _get_mods(evt):
|
|
171
|
+
"""Helper to extract list of mods from event"""
|
|
172
|
+
mods = []
|
|
173
|
+
mods += [keys.CONTROL] if evt.ControlDown() else []
|
|
174
|
+
mods += [keys.ALT] if evt.AltDown() else []
|
|
175
|
+
mods += [keys.SHIFT] if evt.ShiftDown() else []
|
|
176
|
+
mods += [keys.META] if evt.MetaDown() else []
|
|
177
|
+
return mods
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _process_key(evt):
|
|
181
|
+
"""Helper to convert from wx keycode to vispy keycode"""
|
|
182
|
+
key = evt.GetKeyCode()
|
|
183
|
+
if key in KEYMAP:
|
|
184
|
+
return KEYMAP[key], ''
|
|
185
|
+
if 97 <= key <= 122:
|
|
186
|
+
key -= 32
|
|
187
|
+
if key >= 32 and key <= 127:
|
|
188
|
+
return keys.Key(chr(key)), chr(key)
|
|
189
|
+
else:
|
|
190
|
+
return None, None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class DummySize(object):
|
|
194
|
+
def __init__(self, size):
|
|
195
|
+
self.size = size
|
|
196
|
+
|
|
197
|
+
def GetSize(self):
|
|
198
|
+
return self.size
|
|
199
|
+
|
|
200
|
+
def Skip(self):
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class CanvasBackend(GLCanvas, BaseCanvasBackend):
|
|
205
|
+
"""wxPython backend for Canvas abstract class."""
|
|
206
|
+
|
|
207
|
+
def __init__(self, vispy_canvas, **kwargs):
|
|
208
|
+
BaseCanvasBackend.__init__(self, vispy_canvas)
|
|
209
|
+
p = self._process_backend_kwargs(kwargs)
|
|
210
|
+
|
|
211
|
+
# WX supports OS double-click events, so we set this here to
|
|
212
|
+
# avoid double events
|
|
213
|
+
self._double_click_supported = True
|
|
214
|
+
|
|
215
|
+
# Set config
|
|
216
|
+
self._gl_attribs = _set_config(p.context.config)
|
|
217
|
+
# Deal with context
|
|
218
|
+
p.context.shared.add_ref('wx', self)
|
|
219
|
+
if p.context.shared.ref is self:
|
|
220
|
+
self._gl_context = None # set for real once we init the GLCanvas
|
|
221
|
+
else:
|
|
222
|
+
self._gl_context = p.context.shared.ref._gl_context
|
|
223
|
+
|
|
224
|
+
if p.position is None:
|
|
225
|
+
pos = wx.DefaultPosition
|
|
226
|
+
else:
|
|
227
|
+
pos = p.position
|
|
228
|
+
|
|
229
|
+
if p.parent is None:
|
|
230
|
+
style = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.CLOSE_BOX |
|
|
231
|
+
wx.SYSTEM_MENU | wx.CAPTION | wx.CLIP_CHILDREN)
|
|
232
|
+
style |= wx.NO_BORDER if not p.decorate else wx.RESIZE_BORDER
|
|
233
|
+
style |= wx.STAY_ON_TOP if p.always_on_top else 0
|
|
234
|
+
self._frame = wx.Frame(None, wx.ID_ANY, p.title, pos, p.size,
|
|
235
|
+
style)
|
|
236
|
+
|
|
237
|
+
if not p.resizable:
|
|
238
|
+
self._frame.SetSizeHints(p.size[0], p.size[1],
|
|
239
|
+
p.size[0], p.size[1])
|
|
240
|
+
if p.fullscreen is not False:
|
|
241
|
+
if p.fullscreen is not True:
|
|
242
|
+
logger.warning('Cannot specify monitor number for wx '
|
|
243
|
+
'fullscreen, using default')
|
|
244
|
+
self._fullscreen = True
|
|
245
|
+
else:
|
|
246
|
+
self._fullscreen = False
|
|
247
|
+
_wx_app.SetTopWindow(self._frame)
|
|
248
|
+
parent = self._frame
|
|
249
|
+
self._frame.Show()
|
|
250
|
+
self._frame.Raise()
|
|
251
|
+
self._frame.Bind(wx.EVT_CLOSE, self.on_close)
|
|
252
|
+
else:
|
|
253
|
+
parent = p.parent
|
|
254
|
+
self._frame = None
|
|
255
|
+
self._fullscreen = False
|
|
256
|
+
self._init = False
|
|
257
|
+
GLCanvas.__init__(self, parent, wx.ID_ANY, pos=pos,
|
|
258
|
+
size=p.size, style=0, name='GLCanvas',
|
|
259
|
+
attribList=self._gl_attribs)
|
|
260
|
+
|
|
261
|
+
if self._gl_context is None:
|
|
262
|
+
self._gl_context = glcanvas.GLContext(self)
|
|
263
|
+
|
|
264
|
+
self.SetFocus()
|
|
265
|
+
self._vispy_set_title(p.title)
|
|
266
|
+
self._size = None
|
|
267
|
+
self.Bind(wx.EVT_SIZE, self.on_resize)
|
|
268
|
+
self.Bind(wx.EVT_PAINT, self.on_draw)
|
|
269
|
+
self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
|
|
270
|
+
self.Bind(wx.EVT_KEY_UP, self.on_key_up)
|
|
271
|
+
self.Bind(wx.EVT_MOUSE_EVENTS, self.on_mouse_event)
|
|
272
|
+
self._size_init = p.size
|
|
273
|
+
self._vispy_set_visible(p.show)
|
|
274
|
+
|
|
275
|
+
def on_resize(self, event):
|
|
276
|
+
if self._vispy_canvas is None or not self._init:
|
|
277
|
+
event.Skip()
|
|
278
|
+
return
|
|
279
|
+
size = event.GetSize()
|
|
280
|
+
self._vispy_canvas.events.resize(size=size)
|
|
281
|
+
self.Refresh()
|
|
282
|
+
event.Skip()
|
|
283
|
+
|
|
284
|
+
def on_draw(self, event):
|
|
285
|
+
if self._vispy_canvas is None:
|
|
286
|
+
return
|
|
287
|
+
dc = wx.PaintDC(self) # needed for wx
|
|
288
|
+
if not self._init:
|
|
289
|
+
self._initialize()
|
|
290
|
+
self._vispy_canvas.set_current()
|
|
291
|
+
self._vispy_canvas.events.draw(region=None)
|
|
292
|
+
del dc
|
|
293
|
+
event.Skip()
|
|
294
|
+
|
|
295
|
+
def _initialize(self):
|
|
296
|
+
if self._vispy_canvas is None:
|
|
297
|
+
return
|
|
298
|
+
self._init = True
|
|
299
|
+
self._vispy_canvas.set_current()
|
|
300
|
+
self._vispy_canvas.events.initialize()
|
|
301
|
+
self.on_resize(DummySize(self._size_init))
|
|
302
|
+
|
|
303
|
+
def _vispy_set_current(self):
|
|
304
|
+
if self.IsShown():
|
|
305
|
+
self.SetCurrent(self._gl_context)
|
|
306
|
+
|
|
307
|
+
def _vispy_warmup(self):
|
|
308
|
+
etime = time() + 0.3
|
|
309
|
+
while time() < etime:
|
|
310
|
+
sleep(0.01)
|
|
311
|
+
self._vispy_canvas.set_current()
|
|
312
|
+
self._vispy_canvas.app.process_events()
|
|
313
|
+
|
|
314
|
+
def _vispy_swap_buffers(self):
|
|
315
|
+
# Swap front and back buffer
|
|
316
|
+
self._vispy_canvas.set_current()
|
|
317
|
+
self.SwapBuffers()
|
|
318
|
+
|
|
319
|
+
def _vispy_set_title(self, title):
|
|
320
|
+
# Set the window title. Has no effect for widgets
|
|
321
|
+
if self._frame is not None:
|
|
322
|
+
self._frame.SetLabel(title)
|
|
323
|
+
|
|
324
|
+
def _vispy_set_size(self, w, h):
|
|
325
|
+
# Set size of the widget or window
|
|
326
|
+
if not self._init:
|
|
327
|
+
self._size_init = (w, h)
|
|
328
|
+
if hasattr(self, 'SetSize'):
|
|
329
|
+
# phoenix
|
|
330
|
+
self.SetSize(w, h)
|
|
331
|
+
else:
|
|
332
|
+
# legacy
|
|
333
|
+
self.SetSizeWH(w, h)
|
|
334
|
+
|
|
335
|
+
def _vispy_set_position(self, x, y):
|
|
336
|
+
# Set positionof the widget or window. May have no effect for widgets
|
|
337
|
+
if self._frame is not None:
|
|
338
|
+
self._frame.SetPosition((x, y))
|
|
339
|
+
|
|
340
|
+
def _vispy_get_fullscreen(self):
|
|
341
|
+
return self._fullscreen
|
|
342
|
+
|
|
343
|
+
def _vispy_set_fullscreen(self, fullscreen):
|
|
344
|
+
if self._frame is not None:
|
|
345
|
+
self._fullscreen = bool(fullscreen)
|
|
346
|
+
self._vispy_set_visible(True)
|
|
347
|
+
|
|
348
|
+
def _vispy_set_visible(self, visible):
|
|
349
|
+
# Show or hide the window or widget
|
|
350
|
+
self.Show(visible)
|
|
351
|
+
if visible:
|
|
352
|
+
if self._frame is not None:
|
|
353
|
+
self._frame.ShowFullScreen(self._fullscreen)
|
|
354
|
+
|
|
355
|
+
def _vispy_update(self):
|
|
356
|
+
# Invoke a redraw
|
|
357
|
+
self.Refresh()
|
|
358
|
+
|
|
359
|
+
def _vispy_close(self):
|
|
360
|
+
if self._vispy_canvas is None:
|
|
361
|
+
return
|
|
362
|
+
# Force the window or widget to shut down
|
|
363
|
+
canvas = self
|
|
364
|
+
frame = self._frame
|
|
365
|
+
self._gl_context = None # let RC destroy this in case it's shared
|
|
366
|
+
canvas.Close()
|
|
367
|
+
canvas.Destroy()
|
|
368
|
+
if frame:
|
|
369
|
+
frame.Close()
|
|
370
|
+
frame.Destroy()
|
|
371
|
+
gc.collect() # ensure context gets destroyed if it should be
|
|
372
|
+
|
|
373
|
+
def _vispy_get_size(self):
|
|
374
|
+
if self._vispy_canvas is None:
|
|
375
|
+
return
|
|
376
|
+
w, h = self.GetClientSize()
|
|
377
|
+
return w, h
|
|
378
|
+
|
|
379
|
+
def _vispy_get_physical_size(self):
|
|
380
|
+
w, h = self.GetClientSize()
|
|
381
|
+
ratio = self.GetContentScaleFactor()
|
|
382
|
+
return int(w * ratio), int(h * ratio)
|
|
383
|
+
|
|
384
|
+
def _vispy_get_position(self):
|
|
385
|
+
if self._vispy_canvas is None:
|
|
386
|
+
return
|
|
387
|
+
x, y = self.GetPosition()
|
|
388
|
+
return x, y
|
|
389
|
+
|
|
390
|
+
def on_close(self, evt):
|
|
391
|
+
if not self: # wx control evaluates to false if C++ part deleted
|
|
392
|
+
return
|
|
393
|
+
if self._vispy_canvas is None:
|
|
394
|
+
return
|
|
395
|
+
self._vispy_canvas.close()
|
|
396
|
+
|
|
397
|
+
def on_mouse_event(self, evt):
|
|
398
|
+
if self._vispy_canvas is None:
|
|
399
|
+
return
|
|
400
|
+
pos = (evt.GetX(), evt.GetY())
|
|
401
|
+
mods = _get_mods(evt)
|
|
402
|
+
if evt.GetWheelRotation() != 0:
|
|
403
|
+
delta = (0., float(evt.GetWheelRotation())/120.0)
|
|
404
|
+
self._vispy_canvas.events.mouse_wheel(delta=delta, pos=pos,
|
|
405
|
+
modifiers=mods)
|
|
406
|
+
elif evt.Moving() or evt.Dragging(): # mouse move event
|
|
407
|
+
self._vispy_mouse_move(pos=pos, modifiers=mods)
|
|
408
|
+
elif evt.ButtonDown():
|
|
409
|
+
if evt.LeftDown():
|
|
410
|
+
button = 1
|
|
411
|
+
elif evt.MiddleDown():
|
|
412
|
+
button = 3
|
|
413
|
+
elif evt.RightDown():
|
|
414
|
+
button = 2
|
|
415
|
+
else:
|
|
416
|
+
evt.Skip()
|
|
417
|
+
self._vispy_mouse_press(pos=pos, button=button, modifiers=mods)
|
|
418
|
+
elif evt.ButtonUp():
|
|
419
|
+
if evt.LeftUp():
|
|
420
|
+
button = 1
|
|
421
|
+
elif evt.MiddleUp():
|
|
422
|
+
button = 3
|
|
423
|
+
elif evt.RightUp():
|
|
424
|
+
button = 2
|
|
425
|
+
else:
|
|
426
|
+
evt.Skip()
|
|
427
|
+
self._vispy_mouse_release(pos=pos, button=button, modifiers=mods)
|
|
428
|
+
elif evt.ButtonDClick():
|
|
429
|
+
if evt.LeftDClick():
|
|
430
|
+
button = 1
|
|
431
|
+
elif evt.MiddleDClick():
|
|
432
|
+
button = 3
|
|
433
|
+
elif evt.RightDClick():
|
|
434
|
+
button = 2
|
|
435
|
+
else:
|
|
436
|
+
evt.Skip()
|
|
437
|
+
self._vispy_mouse_press(pos=pos, button=button, modifiers=mods)
|
|
438
|
+
self._vispy_mouse_double_click(pos=pos, button=button,
|
|
439
|
+
modifiers=mods)
|
|
440
|
+
evt.Skip()
|
|
441
|
+
|
|
442
|
+
def on_key_down(self, evt):
|
|
443
|
+
if self._vispy_canvas is None:
|
|
444
|
+
return
|
|
445
|
+
key, text = _process_key(evt)
|
|
446
|
+
self._vispy_canvas.events.key_press(key=key, text=text,
|
|
447
|
+
modifiers=_get_mods(evt))
|
|
448
|
+
|
|
449
|
+
def on_key_up(self, evt):
|
|
450
|
+
if self._vispy_canvas is None:
|
|
451
|
+
return
|
|
452
|
+
key, text = _process_key(evt)
|
|
453
|
+
self._vispy_canvas.events.key_release(key=key, text=text,
|
|
454
|
+
modifiers=_get_mods(evt))
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
# ------------------------------------------------------------------- timer ---
|
|
458
|
+
|
|
459
|
+
class TimerBackend(BaseTimerBackend):
|
|
460
|
+
|
|
461
|
+
def __init__(self, vispy_timer):
|
|
462
|
+
BaseTimerBackend.__init__(self, vispy_timer)
|
|
463
|
+
assert _wx_app is not None
|
|
464
|
+
parent = _wx_app.GetTopWindow() # assume it's the parent window
|
|
465
|
+
self._timer = wx.Timer(parent, -1)
|
|
466
|
+
parent.Bind(wx.EVT_TIMER, self._vispy_timeout, self._timer)
|
|
467
|
+
|
|
468
|
+
def _vispy_start(self, interval):
|
|
469
|
+
self._timer.Start(int(interval * 1000.), False)
|
|
470
|
+
|
|
471
|
+
def _vispy_stop(self):
|
|
472
|
+
self._timer.Stop()
|
|
473
|
+
|
|
474
|
+
def _vispy_timeout(self, evt):
|
|
475
|
+
self._vispy_timer._timeout()
|
|
476
|
+
evt.Skip()
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from vispy.app.backends._offscreen_util import OffscreenContext, FrameBufferHelper
|
|
2
|
+
from vispy.testing import run_tests_if_main, requires_application
|
|
3
|
+
from vispy import gloo
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@requires_application()
|
|
8
|
+
def test_offscreen_context():
|
|
9
|
+
c1 = OffscreenContext()
|
|
10
|
+
c2 = OffscreenContext.get_global_instance()
|
|
11
|
+
c3 = OffscreenContext.get_global_instance()
|
|
12
|
+
c4 = OffscreenContext()
|
|
13
|
+
|
|
14
|
+
assert c1 is not c2
|
|
15
|
+
assert c1 is not c4
|
|
16
|
+
assert c2 is c3
|
|
17
|
+
|
|
18
|
+
c1.make_current()
|
|
19
|
+
c1.close()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class FakeCanvas(object):
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
self.context = gloo.GLContext()
|
|
26
|
+
gloo.context.set_current_canvas(self)
|
|
27
|
+
|
|
28
|
+
def flush(self):
|
|
29
|
+
self.context.flush_commands()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@requires_application()
|
|
33
|
+
def test_frame_buffer_helper():
|
|
34
|
+
canvas = FakeCanvas()
|
|
35
|
+
gl_context = OffscreenContext()
|
|
36
|
+
fbh = FrameBufferHelper()
|
|
37
|
+
|
|
38
|
+
gl_context.make_current()
|
|
39
|
+
fbh.set_physical_size(43, 67)
|
|
40
|
+
with fbh:
|
|
41
|
+
gloo.set_clear_color((0, 0.5, 1))
|
|
42
|
+
gloo.clear()
|
|
43
|
+
canvas.flush()
|
|
44
|
+
array = fbh.get_frame()
|
|
45
|
+
|
|
46
|
+
assert array.shape == (67, 43, 4)
|
|
47
|
+
assert np.all(array[:, :, 0] == 0)
|
|
48
|
+
assert np.all(array[:, :, 1] == 128)
|
|
49
|
+
assert np.all(array[:, :, 2] == 255)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
run_tests_if_main()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# This currenly only tests that the backend exists and can be imported ...
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from vispy import gloo
|
|
5
|
+
from vispy.app import Application, Canvas
|
|
6
|
+
from vispy.app.backends import _jupyter_rfb
|
|
7
|
+
from vispy.testing import run_tests_if_main, requires_application
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import jupyter_rfb
|
|
12
|
+
except ImportError:
|
|
13
|
+
jupyter_rfb = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_rfb_app():
|
|
17
|
+
|
|
18
|
+
# Raw
|
|
19
|
+
app_backend = _jupyter_rfb.ApplicationBackend()
|
|
20
|
+
|
|
21
|
+
# Test that run and quit don't do anything - Jupyter is an interactive session!
|
|
22
|
+
app_backend._vispy_run()
|
|
23
|
+
app_backend._vispy_quit()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MyCanvas(Canvas):
|
|
27
|
+
|
|
28
|
+
def on_draw(self, event):
|
|
29
|
+
gloo.set_clear_color((0, 1, 0))
|
|
30
|
+
gloo.clear()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.mark.skipif(jupyter_rfb is None, reason='jupyter_rfb is not installed')
|
|
34
|
+
@requires_application()
|
|
35
|
+
def test_rfb_canvas():
|
|
36
|
+
|
|
37
|
+
app = Application("jupyter_rfb")
|
|
38
|
+
canvas = MyCanvas(app=app)
|
|
39
|
+
canvas_backend = canvas.native
|
|
40
|
+
|
|
41
|
+
assert isinstance(canvas_backend, _jupyter_rfb.CanvasBackend)
|
|
42
|
+
|
|
43
|
+
# Check that resize works
|
|
44
|
+
assert "42" not in canvas_backend.css_width
|
|
45
|
+
canvas.size = 42, 42
|
|
46
|
+
assert canvas_backend.css_width == "42px"
|
|
47
|
+
# Manually mimic what a browser would do, but round to 50
|
|
48
|
+
canvas_backend.handle_event({"event_type": "resize", "width": 50, "height": 50, "pixel_ratio": 2.0})
|
|
49
|
+
assert canvas.size == (50, 50)
|
|
50
|
+
assert canvas.physical_size == (100, 100)
|
|
51
|
+
|
|
52
|
+
# Mimic a draw
|
|
53
|
+
frame = canvas_backend.get_frame()
|
|
54
|
+
assert frame.shape[:2] == (100, 100)
|
|
55
|
+
assert np.all(frame[:, :, 0] == 0)
|
|
56
|
+
assert np.all(frame[:, :, 1] == 255)
|
|
57
|
+
|
|
58
|
+
# Pretend that the user resized in the browser
|
|
59
|
+
canvas_backend.handle_event({"event_type": "resize", "width": 60, "height": 60, "pixel_ratio": 1.0})
|
|
60
|
+
assert canvas.size == (60, 60)
|
|
61
|
+
assert canvas.physical_size == (60, 60)
|
|
62
|
+
|
|
63
|
+
# Mimic another draw
|
|
64
|
+
frame = canvas_backend.get_frame()
|
|
65
|
+
assert frame.shape[:2] == (60, 60)
|
|
66
|
+
assert np.all(frame[:, :, 0] == 0)
|
|
67
|
+
assert np.all(frame[:, :, 1] == 255)
|
|
68
|
+
|
|
69
|
+
# Test mouse event
|
|
70
|
+
events = []
|
|
71
|
+
canvas.events.mouse_press.connect(lambda e: events.append(e))
|
|
72
|
+
canvas_backend.handle_event({"event_type": "pointer_down", "x": 11, "y": 12, "button": 1, "modifiers": []})
|
|
73
|
+
assert len(events) == 1
|
|
74
|
+
assert tuple(events[0].pos) == (11, 12)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
run_tests_if_main()
|