vispy 0.15.0__cp312-cp312-macosx_10_13_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-312-darwin.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
|
@@ -0,0 +1,444 @@
|
|
|
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
|
+
"""vispy backend for sdl2."""
|
|
5
|
+
|
|
6
|
+
from __future__ import division
|
|
7
|
+
|
|
8
|
+
import atexit
|
|
9
|
+
import ctypes
|
|
10
|
+
from time import sleep
|
|
11
|
+
import warnings
|
|
12
|
+
import gc
|
|
13
|
+
|
|
14
|
+
from ..base import (BaseApplicationBackend, BaseCanvasBackend,
|
|
15
|
+
BaseTimerBackend)
|
|
16
|
+
from ...util import keys, logger
|
|
17
|
+
from ...util.ptime import time
|
|
18
|
+
from ... import config
|
|
19
|
+
|
|
20
|
+
USE_EGL = config['gl_backend'].lower().startswith('es')
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# -------------------------------------------------------------------- init ---
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
with warnings.catch_warnings(record=True): # can throw warnings
|
|
27
|
+
import sdl2
|
|
28
|
+
import sdl2.ext
|
|
29
|
+
|
|
30
|
+
# Map native keys to vispy keys
|
|
31
|
+
KEYMAP = {
|
|
32
|
+
# http://www.ginkgobitter.org/sdl/?SDL_Keycode
|
|
33
|
+
sdl2.SDLK_LSHIFT: keys.SHIFT,
|
|
34
|
+
sdl2.SDLK_RSHIFT: keys.SHIFT,
|
|
35
|
+
sdl2.SDLK_LCTRL: keys.CONTROL,
|
|
36
|
+
sdl2.SDLK_RCTRL: keys.CONTROL,
|
|
37
|
+
sdl2.SDLK_LALT: keys.ALT,
|
|
38
|
+
sdl2.SDLK_RALT: keys.ALT,
|
|
39
|
+
sdl2.SDLK_LGUI: keys.META,
|
|
40
|
+
sdl2.SDLK_RGUI: keys.META,
|
|
41
|
+
|
|
42
|
+
sdl2.SDLK_LEFT: keys.LEFT,
|
|
43
|
+
sdl2.SDLK_UP: keys.UP,
|
|
44
|
+
sdl2.SDLK_RIGHT: keys.RIGHT,
|
|
45
|
+
sdl2.SDLK_DOWN: keys.DOWN,
|
|
46
|
+
sdl2.SDLK_PAGEUP: keys.PAGEUP,
|
|
47
|
+
sdl2.SDLK_PAGEDOWN: keys.PAGEDOWN,
|
|
48
|
+
|
|
49
|
+
sdl2.SDLK_INSERT: keys.INSERT,
|
|
50
|
+
sdl2.SDLK_DELETE: keys.DELETE,
|
|
51
|
+
sdl2.SDLK_HOME: keys.HOME,
|
|
52
|
+
sdl2.SDLK_END: keys.END,
|
|
53
|
+
|
|
54
|
+
sdl2.SDLK_ESCAPE: keys.ESCAPE,
|
|
55
|
+
sdl2.SDLK_BACKSPACE: keys.BACKSPACE,
|
|
56
|
+
|
|
57
|
+
sdl2.SDLK_F1: keys.F1,
|
|
58
|
+
sdl2.SDLK_F2: keys.F2,
|
|
59
|
+
sdl2.SDLK_F3: keys.F3,
|
|
60
|
+
sdl2.SDLK_F4: keys.F4,
|
|
61
|
+
sdl2.SDLK_F5: keys.F5,
|
|
62
|
+
sdl2.SDLK_F6: keys.F6,
|
|
63
|
+
sdl2.SDLK_F7: keys.F7,
|
|
64
|
+
sdl2.SDLK_F8: keys.F8,
|
|
65
|
+
sdl2.SDLK_F9: keys.F9,
|
|
66
|
+
sdl2.SDLK_F10: keys.F10,
|
|
67
|
+
sdl2.SDLK_F11: keys.F11,
|
|
68
|
+
sdl2.SDLK_F12: keys.F12,
|
|
69
|
+
|
|
70
|
+
sdl2.SDLK_SPACE: keys.SPACE,
|
|
71
|
+
sdl2.SDLK_RETURN: keys.ENTER,
|
|
72
|
+
sdl2.SDLK_TAB: keys.TAB,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
BUTTONMAP = {sdl2.SDL_BUTTON_LEFT: 1,
|
|
76
|
+
sdl2.SDL_BUTTON_MIDDLE: 2,
|
|
77
|
+
sdl2.SDL_BUTTON_RIGHT: 3
|
|
78
|
+
}
|
|
79
|
+
except Exception as exp:
|
|
80
|
+
available, testable, why_not, which = False, False, str(exp), None
|
|
81
|
+
else:
|
|
82
|
+
if USE_EGL:
|
|
83
|
+
available, testable, why_not = False, False, 'EGL not supported'
|
|
84
|
+
else:
|
|
85
|
+
available, testable, why_not = True, True, None
|
|
86
|
+
which = 'sdl2 %d.%d.%d' % sdl2.version_info[:3]
|
|
87
|
+
|
|
88
|
+
_SDL2_INITIALIZED = False
|
|
89
|
+
_VP_SDL2_ALL_WINDOWS = {}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _get_sdl2_windows():
|
|
93
|
+
return list(_VP_SDL2_ALL_WINDOWS.values())
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# -------------------------------------------------------------- capability ---
|
|
97
|
+
|
|
98
|
+
capability = dict( # things that can be set by the backend
|
|
99
|
+
title=True,
|
|
100
|
+
size=True,
|
|
101
|
+
position=True,
|
|
102
|
+
show=True,
|
|
103
|
+
vsync=True,
|
|
104
|
+
resizable=True,
|
|
105
|
+
decorate=True,
|
|
106
|
+
fullscreen=True,
|
|
107
|
+
context=True,
|
|
108
|
+
multi_window=True,
|
|
109
|
+
scroll=True,
|
|
110
|
+
parent=False,
|
|
111
|
+
always_on_top=False,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# ------------------------------------------------------- set_configuration ---
|
|
116
|
+
|
|
117
|
+
def _set_config(c):
|
|
118
|
+
"""Set gl configuration for SDL2"""
|
|
119
|
+
func = sdl2.SDL_GL_SetAttribute
|
|
120
|
+
func(sdl2.SDL_GL_RED_SIZE, c['red_size'])
|
|
121
|
+
func(sdl2.SDL_GL_GREEN_SIZE, c['green_size'])
|
|
122
|
+
func(sdl2.SDL_GL_BLUE_SIZE, c['blue_size'])
|
|
123
|
+
func(sdl2.SDL_GL_ALPHA_SIZE, c['alpha_size'])
|
|
124
|
+
func(sdl2.SDL_GL_DEPTH_SIZE, c['depth_size'])
|
|
125
|
+
func(sdl2.SDL_GL_STENCIL_SIZE, c['stencil_size'])
|
|
126
|
+
func(sdl2.SDL_GL_DOUBLEBUFFER, 1 if c['double_buffer'] else 0)
|
|
127
|
+
samps = c['samples']
|
|
128
|
+
func(sdl2.SDL_GL_MULTISAMPLEBUFFERS, 1 if samps > 0 else 0)
|
|
129
|
+
func(sdl2.SDL_GL_MULTISAMPLESAMPLES, samps if samps > 0 else 0)
|
|
130
|
+
func(sdl2.SDL_GL_STEREO, c['stereo'])
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# ------------------------------------------------------------- application ---
|
|
134
|
+
|
|
135
|
+
class ApplicationBackend(BaseApplicationBackend):
|
|
136
|
+
|
|
137
|
+
def __init__(self):
|
|
138
|
+
BaseApplicationBackend.__init__(self)
|
|
139
|
+
self._timers = list()
|
|
140
|
+
|
|
141
|
+
def _add_timer(self, timer):
|
|
142
|
+
if timer not in self._timers:
|
|
143
|
+
self._timers.append(timer)
|
|
144
|
+
|
|
145
|
+
def _vispy_get_backend_name(self):
|
|
146
|
+
return 'SDL2'
|
|
147
|
+
|
|
148
|
+
def _vispy_process_events(self):
|
|
149
|
+
events = sdl2.ext.get_events()
|
|
150
|
+
while len(events) > 0:
|
|
151
|
+
for event in events:
|
|
152
|
+
_id = event.window.windowID
|
|
153
|
+
if _id in _VP_SDL2_ALL_WINDOWS:
|
|
154
|
+
win = _VP_SDL2_ALL_WINDOWS[_id]
|
|
155
|
+
win._on_event(event)
|
|
156
|
+
events = sdl2.ext.get_events()
|
|
157
|
+
for timer in self._timers:
|
|
158
|
+
timer._tick()
|
|
159
|
+
wins = _get_sdl2_windows()
|
|
160
|
+
for win in wins:
|
|
161
|
+
if win._needs_draw:
|
|
162
|
+
win._needs_draw = False
|
|
163
|
+
win._on_draw()
|
|
164
|
+
|
|
165
|
+
def _vispy_run(self):
|
|
166
|
+
wins = _get_sdl2_windows()
|
|
167
|
+
while any(w._id is not None for w in wins):
|
|
168
|
+
self._vispy_process_events()
|
|
169
|
+
self._vispy_quit() # to clean up
|
|
170
|
+
|
|
171
|
+
def _vispy_quit(self):
|
|
172
|
+
# Close windows
|
|
173
|
+
wins = _get_sdl2_windows()
|
|
174
|
+
for win in wins:
|
|
175
|
+
win._vispy_close()
|
|
176
|
+
# tear down timers
|
|
177
|
+
for timer in self._timers:
|
|
178
|
+
timer._vispy_stop()
|
|
179
|
+
self._timers = []
|
|
180
|
+
|
|
181
|
+
def _vispy_get_native_app(self):
|
|
182
|
+
global _SDL2_INITIALIZED
|
|
183
|
+
if not _SDL2_INITIALIZED:
|
|
184
|
+
sdl2.ext.init()
|
|
185
|
+
atexit.register(sdl2.ext.quit)
|
|
186
|
+
_SDL2_INITIALIZED = True
|
|
187
|
+
return sdl2
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# ------------------------------------------------------------------ canvas ---
|
|
191
|
+
|
|
192
|
+
class CanvasBackend(BaseCanvasBackend):
|
|
193
|
+
"""SDL2 backend for Canvas abstract class."""
|
|
194
|
+
|
|
195
|
+
def __init__(self, vispy_canvas, **kwargs):
|
|
196
|
+
BaseCanvasBackend.__init__(self, vispy_canvas)
|
|
197
|
+
p = self._process_backend_kwargs(kwargs)
|
|
198
|
+
self._initialized = False
|
|
199
|
+
|
|
200
|
+
# Deal with config
|
|
201
|
+
_set_config(p.context.config)
|
|
202
|
+
# Deal with context
|
|
203
|
+
p.context.shared.add_ref('sdl2', self)
|
|
204
|
+
if p.context.shared.ref is self:
|
|
205
|
+
share = None
|
|
206
|
+
else:
|
|
207
|
+
other = p.context.shared.ref
|
|
208
|
+
share = other._id.window, other._native_context
|
|
209
|
+
sdl2.SDL_GL_MakeCurrent(*share)
|
|
210
|
+
sdl2.SDL_GL_SetAttribute(sdl2.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1)
|
|
211
|
+
|
|
212
|
+
sdl2.SDL_GL_SetSwapInterval(1 if p.vsync else 0)
|
|
213
|
+
flags = sdl2.SDL_WINDOW_OPENGL
|
|
214
|
+
flags |= sdl2.SDL_WINDOW_SHOWN # start out shown
|
|
215
|
+
flags |= sdl2.SDL_WINDOW_ALLOW_HIGHDPI
|
|
216
|
+
flags |= sdl2.SDL_WINDOW_RESIZABLE if p.resizable else 0
|
|
217
|
+
flags |= sdl2.SDL_WINDOW_BORDERLESS if not p.decorate else 0
|
|
218
|
+
if p.fullscreen is not False:
|
|
219
|
+
self._fullscreen = True
|
|
220
|
+
if p.fullscreen is not True:
|
|
221
|
+
logger.warning('Cannot specify monitor number for SDL2 '
|
|
222
|
+
'fullscreen, using default')
|
|
223
|
+
flags |= sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP
|
|
224
|
+
else:
|
|
225
|
+
self._fullscreen = False
|
|
226
|
+
self._mods = list()
|
|
227
|
+
if p.position is None:
|
|
228
|
+
position = [sdl2.SDL_WINDOWPOS_UNDEFINED] * 2
|
|
229
|
+
else:
|
|
230
|
+
position = None
|
|
231
|
+
self._id = sdl2.ext.Window(p.title, p.size, position, flags)
|
|
232
|
+
if not self._id.window:
|
|
233
|
+
raise RuntimeError('Could not create window')
|
|
234
|
+
if share is None:
|
|
235
|
+
self._native_context = sdl2.SDL_GL_CreateContext(self._id.window)
|
|
236
|
+
else:
|
|
237
|
+
self._native_context = sdl2.SDL_GL_CreateContext(share[0])
|
|
238
|
+
self._sdl_id = sdl2.SDL_GetWindowID(self._id.window)
|
|
239
|
+
_VP_SDL2_ALL_WINDOWS[self._sdl_id] = self
|
|
240
|
+
|
|
241
|
+
# Init
|
|
242
|
+
self._initialized = True
|
|
243
|
+
self._needs_draw = False
|
|
244
|
+
self._vispy_canvas.set_current()
|
|
245
|
+
self._vispy_canvas.events.initialize()
|
|
246
|
+
if not p.show:
|
|
247
|
+
self._vispy_set_visible(False)
|
|
248
|
+
|
|
249
|
+
def _vispy_warmup(self):
|
|
250
|
+
etime = time() + 0.1
|
|
251
|
+
while time() < etime:
|
|
252
|
+
sleep(0.01)
|
|
253
|
+
self._vispy_canvas.set_current()
|
|
254
|
+
self._vispy_canvas.app.process_events()
|
|
255
|
+
|
|
256
|
+
def _vispy_set_current(self):
|
|
257
|
+
if self._id is None:
|
|
258
|
+
return
|
|
259
|
+
# Make this the current context
|
|
260
|
+
sdl2.SDL_GL_MakeCurrent(self._id.window, self._native_context)
|
|
261
|
+
|
|
262
|
+
def _vispy_swap_buffers(self):
|
|
263
|
+
if self._id is None:
|
|
264
|
+
return
|
|
265
|
+
# Swap front and back buffer
|
|
266
|
+
sdl2.SDL_GL_SwapWindow(self._id.window)
|
|
267
|
+
|
|
268
|
+
def _vispy_set_title(self, title):
|
|
269
|
+
if self._id is None:
|
|
270
|
+
return
|
|
271
|
+
# Set the window title. Has no effect for widgets
|
|
272
|
+
sdl2.SDL_SetWindowTitle(self._id.window, title.encode('UTF-8'))
|
|
273
|
+
|
|
274
|
+
def _vispy_set_size(self, w, h):
|
|
275
|
+
if self._id is None:
|
|
276
|
+
return
|
|
277
|
+
# Set size of the widget or window
|
|
278
|
+
sdl2.SDL_SetWindowSize(self._id.window, w, h)
|
|
279
|
+
|
|
280
|
+
def _vispy_set_position(self, x, y):
|
|
281
|
+
if self._id is None:
|
|
282
|
+
return
|
|
283
|
+
# Set position of the widget or window. May have no effect for widgets
|
|
284
|
+
sdl2.SDL_SetWindowPosition(self._id.window, x, y)
|
|
285
|
+
|
|
286
|
+
def _vispy_set_visible(self, visible):
|
|
287
|
+
# Show or hide the window or widget
|
|
288
|
+
if self._id is None:
|
|
289
|
+
return
|
|
290
|
+
if visible:
|
|
291
|
+
self._id.show()
|
|
292
|
+
# this ensures that the show takes effect
|
|
293
|
+
self._vispy_update()
|
|
294
|
+
else:
|
|
295
|
+
self._id.hide()
|
|
296
|
+
|
|
297
|
+
def _vispy_update(self):
|
|
298
|
+
# Invoke a redraw, passing it on to the canvas
|
|
299
|
+
if self._vispy_canvas is None or self._id is None:
|
|
300
|
+
return
|
|
301
|
+
# Mark that this window wants to be drawn on the next loop iter
|
|
302
|
+
self._needs_draw = True
|
|
303
|
+
|
|
304
|
+
def _vispy_close(self):
|
|
305
|
+
# Force the window or widget to shut down
|
|
306
|
+
if self._id is not None:
|
|
307
|
+
_id = self._id.window
|
|
308
|
+
self._vispy_canvas = None
|
|
309
|
+
self._id = None
|
|
310
|
+
sdl2.SDL_DestroyWindow(_id)
|
|
311
|
+
del _VP_SDL2_ALL_WINDOWS[self._sdl_id]
|
|
312
|
+
self._sdl_id = None
|
|
313
|
+
gc.collect() # enforce gc to help context get destroyed
|
|
314
|
+
|
|
315
|
+
def _vispy_get_size(self):
|
|
316
|
+
if self._id is None:
|
|
317
|
+
return
|
|
318
|
+
w, h = ctypes.c_int(), ctypes.c_int()
|
|
319
|
+
sdl2.SDL_GetWindowSize(self._id.window,
|
|
320
|
+
ctypes.byref(w), ctypes.byref(h))
|
|
321
|
+
w, h = w.value, h.value
|
|
322
|
+
return w, h
|
|
323
|
+
|
|
324
|
+
def _vispy_get_fullscreen(self):
|
|
325
|
+
return self._fullscreen
|
|
326
|
+
|
|
327
|
+
def _vispy_set_fullscreen(self, fullscreen):
|
|
328
|
+
self._fullscreen = bool(fullscreen)
|
|
329
|
+
flags = sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP if self._fullscreen else 0
|
|
330
|
+
sdl2.SDL_SetWindowFullscreen(self._id.window, flags)
|
|
331
|
+
|
|
332
|
+
def _vispy_get_position(self):
|
|
333
|
+
if self._id is None:
|
|
334
|
+
return
|
|
335
|
+
x, y = ctypes.c_int(), ctypes.c_int()
|
|
336
|
+
sdl2.SDL_GetWindowPosition(self._id.window,
|
|
337
|
+
ctypes.byref(x), ctypes.byref(y))
|
|
338
|
+
x, y = x.value, y.value
|
|
339
|
+
return x, y
|
|
340
|
+
|
|
341
|
+
##########################################
|
|
342
|
+
# Notify vispy of events triggered by SDL2
|
|
343
|
+
def _get_mouse_position(self):
|
|
344
|
+
if self._id is None:
|
|
345
|
+
return (0, 0)
|
|
346
|
+
x, y = ctypes.c_int(), ctypes.c_int()
|
|
347
|
+
sdl2.SDL_GetMouseState(ctypes.byref(x), ctypes.byref(y))
|
|
348
|
+
return x.value, y.value
|
|
349
|
+
|
|
350
|
+
def _on_draw(self):
|
|
351
|
+
if self._vispy_canvas is None or self._id is None:
|
|
352
|
+
return
|
|
353
|
+
self._vispy_canvas.set_current()
|
|
354
|
+
self._vispy_canvas.events.draw(region=None) # (0, 0, w, h))
|
|
355
|
+
|
|
356
|
+
def _on_event(self, event):
|
|
357
|
+
if self._vispy_canvas is None:
|
|
358
|
+
return
|
|
359
|
+
# triage event to proper handler
|
|
360
|
+
if event.type == sdl2.SDL_QUIT:
|
|
361
|
+
self._vispy_canvas.close()
|
|
362
|
+
elif event.type == sdl2.SDL_WINDOWEVENT:
|
|
363
|
+
if event.window.event == sdl2.SDL_WINDOWEVENT_RESIZED:
|
|
364
|
+
w, h = event.window.data1, event.window.data2
|
|
365
|
+
self._vispy_canvas.events.resize(size=(w, h))
|
|
366
|
+
elif event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE:
|
|
367
|
+
self._vispy_canvas.close()
|
|
368
|
+
elif event.type == sdl2.SDL_MOUSEMOTION:
|
|
369
|
+
x, y = event.motion.x, event.motion.y
|
|
370
|
+
self._vispy_mouse_move(pos=(x, y), modifiers=self._mods)
|
|
371
|
+
elif event.type in (sdl2.SDL_MOUSEBUTTONDOWN,
|
|
372
|
+
sdl2.SDL_MOUSEBUTTONUP):
|
|
373
|
+
x, y = event.button.x, event.button.y
|
|
374
|
+
button = event.button.button
|
|
375
|
+
if button in BUTTONMAP:
|
|
376
|
+
button = BUTTONMAP.get(button, 0)
|
|
377
|
+
if event.type == sdl2.SDL_MOUSEBUTTONDOWN:
|
|
378
|
+
func = self._vispy_mouse_press
|
|
379
|
+
else:
|
|
380
|
+
func = self._vispy_mouse_release
|
|
381
|
+
func(pos=(x, y), button=button, modifiers=self._mods)
|
|
382
|
+
elif event.type == sdl2.SDL_MOUSEWHEEL:
|
|
383
|
+
pos = self._get_mouse_position()
|
|
384
|
+
delta = float(event.wheel.x), float(event.wheel.y)
|
|
385
|
+
self._vispy_canvas.events.mouse_wheel(pos=pos, delta=delta,
|
|
386
|
+
modifiers=self._mods)
|
|
387
|
+
elif event.type in (sdl2.SDL_KEYDOWN, sdl2.SDL_KEYUP):
|
|
388
|
+
down = (event.type == sdl2.SDL_KEYDOWN)
|
|
389
|
+
keysym = event.key.keysym
|
|
390
|
+
mods = keysym.mod
|
|
391
|
+
key = keysym.sym
|
|
392
|
+
self._process_mod(mods, down)
|
|
393
|
+
if key in KEYMAP:
|
|
394
|
+
key, text = KEYMAP[key], ''
|
|
395
|
+
elif key >= 32 and key <= 127:
|
|
396
|
+
key, text = keys.Key(chr(key)), chr(key)
|
|
397
|
+
else:
|
|
398
|
+
key, text = None, ''
|
|
399
|
+
if down:
|
|
400
|
+
fun = self._vispy_canvas.events.key_press
|
|
401
|
+
else:
|
|
402
|
+
fun = self._vispy_canvas.events.key_release
|
|
403
|
+
fun(key=key, text=text, modifiers=self._mods)
|
|
404
|
+
|
|
405
|
+
def _process_mod(self, key, down):
|
|
406
|
+
_modifiers = list()
|
|
407
|
+
if key & (sdl2.SDLK_LSHIFT | sdl2.SDLK_RSHIFT):
|
|
408
|
+
_modifiers.append(keys.SHIFT)
|
|
409
|
+
if key & (sdl2.SDLK_LCTRL | sdl2.SDLK_RCTRL):
|
|
410
|
+
_modifiers.append(keys.CONTROL)
|
|
411
|
+
if key & (sdl2.SDLK_LALT | sdl2.SDLK_RALT):
|
|
412
|
+
_modifiers.append(keys.ALT)
|
|
413
|
+
if key & (sdl2.SDLK_LGUI | sdl2.SDLK_RGUI):
|
|
414
|
+
_modifiers.append(keys.META)
|
|
415
|
+
for mod in _modifiers:
|
|
416
|
+
if mod not in self._mods:
|
|
417
|
+
if down:
|
|
418
|
+
self._mods.append(mod)
|
|
419
|
+
elif not down:
|
|
420
|
+
self._mods.pop(self._mods.index(mod))
|
|
421
|
+
|
|
422
|
+
# ------------------------------------------------------------------- timer ---
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
# XXX should probably use SDL_Timer (and SDL_INIT_TIMER)
|
|
426
|
+
|
|
427
|
+
class TimerBackend(BaseTimerBackend):
|
|
428
|
+
|
|
429
|
+
def __init__(self, vispy_timer):
|
|
430
|
+
BaseTimerBackend.__init__(self, vispy_timer)
|
|
431
|
+
vispy_timer._app._backend._add_timer(self)
|
|
432
|
+
self._vispy_stop()
|
|
433
|
+
|
|
434
|
+
def _vispy_start(self, interval):
|
|
435
|
+
self._interval = interval
|
|
436
|
+
self._next_time = time() + self._interval
|
|
437
|
+
|
|
438
|
+
def _vispy_stop(self):
|
|
439
|
+
self._next_time = float('inf')
|
|
440
|
+
|
|
441
|
+
def _tick(self):
|
|
442
|
+
if time() >= self._next_time:
|
|
443
|
+
self._vispy_timer._timeout()
|
|
444
|
+
self._next_time = time() + self._interval
|
|
@@ -0,0 +1,244 @@
|
|
|
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
|
+
"""This module provides an template for creating backends for vispy.
|
|
6
|
+
It clearly indicates what methods should be implemented and what events
|
|
7
|
+
should be emitted.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import division
|
|
11
|
+
|
|
12
|
+
from ..base import (BaseApplicationBackend, BaseCanvasBackend,
|
|
13
|
+
BaseTimerBackend)
|
|
14
|
+
from ...util import keys
|
|
15
|
+
from ... import config
|
|
16
|
+
|
|
17
|
+
USE_EGL = config['gl_backend'].lower().startswith('es')
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# -------------------------------------------------------------------- init ---
|
|
21
|
+
|
|
22
|
+
# Map native keys to vispy keys
|
|
23
|
+
KEYMAP = {
|
|
24
|
+
-1: keys.SHIFT,
|
|
25
|
+
-2: keys.CONTROL,
|
|
26
|
+
-3: keys.ALT,
|
|
27
|
+
-4: keys.META,
|
|
28
|
+
|
|
29
|
+
-5: keys.LEFT,
|
|
30
|
+
-6: keys.UP,
|
|
31
|
+
-7: keys.RIGHT,
|
|
32
|
+
-8: keys.DOWN,
|
|
33
|
+
-9: keys.PAGEUP,
|
|
34
|
+
-10: keys.PAGEDOWN,
|
|
35
|
+
|
|
36
|
+
-11: keys.INSERT,
|
|
37
|
+
-12: keys.DELETE,
|
|
38
|
+
-13: keys.HOME,
|
|
39
|
+
-14: keys.END,
|
|
40
|
+
|
|
41
|
+
-15: keys.ESCAPE,
|
|
42
|
+
-16: keys.BACKSPACE,
|
|
43
|
+
|
|
44
|
+
-17: keys.SPACE,
|
|
45
|
+
-18: keys.ENTER,
|
|
46
|
+
-19: keys.TAB,
|
|
47
|
+
|
|
48
|
+
-20: keys.F1,
|
|
49
|
+
-21: keys.F2,
|
|
50
|
+
-22: keys.F3,
|
|
51
|
+
-23: keys.F4,
|
|
52
|
+
-24: keys.F5,
|
|
53
|
+
-25: keys.F6,
|
|
54
|
+
-26: keys.F7,
|
|
55
|
+
-27: keys.F8,
|
|
56
|
+
-28: keys.F9,
|
|
57
|
+
-29: keys.F10,
|
|
58
|
+
-30: keys.F11,
|
|
59
|
+
-31: keys.F12,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# -------------------------------------------------------------- capability ---
|
|
64
|
+
|
|
65
|
+
# These are all booleans. Note that they mirror many of the kwargs to
|
|
66
|
+
# the initialization of the Canvas class.
|
|
67
|
+
capability = dict(
|
|
68
|
+
# if True they mean:
|
|
69
|
+
title=False, # can set title on the fly
|
|
70
|
+
size=False, # can set size on the fly
|
|
71
|
+
position=False, # can set position on the fly
|
|
72
|
+
show=False, # can show/hide window XXX ?
|
|
73
|
+
vsync=False, # can set window to sync to blank
|
|
74
|
+
resizable=False, # can toggle resizability (e.g., no user resizing)
|
|
75
|
+
decorate=False, # can toggle decorations
|
|
76
|
+
fullscreen=False, # fullscreen window support
|
|
77
|
+
context=False, # can share contexts between windows
|
|
78
|
+
multi_window=False, # can use multiple windows at once
|
|
79
|
+
scroll=False, # scroll-wheel events are supported
|
|
80
|
+
parent=False, # can pass native widget backend parent
|
|
81
|
+
always_on_top=False, # can be made always-on-top
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# ------------------------------------------------------- set_configuration ---
|
|
86
|
+
def _set_config(c):
|
|
87
|
+
"""Set gl configuration for template"""
|
|
88
|
+
raise NotImplementedError
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# ------------------------------------------------------------- application ---
|
|
92
|
+
|
|
93
|
+
class ApplicationBackend(BaseApplicationBackend):
|
|
94
|
+
|
|
95
|
+
def __init__(self):
|
|
96
|
+
BaseApplicationBackend.__init__(self)
|
|
97
|
+
|
|
98
|
+
def _vispy_get_backend_name(self):
|
|
99
|
+
return 'ThisBackendsName'
|
|
100
|
+
|
|
101
|
+
def _vispy_process_events(self):
|
|
102
|
+
raise NotImplementedError()
|
|
103
|
+
|
|
104
|
+
def _vispy_run(self):
|
|
105
|
+
raise NotImplementedError()
|
|
106
|
+
|
|
107
|
+
def _vispy_quit(self):
|
|
108
|
+
raise NotImplementedError()
|
|
109
|
+
|
|
110
|
+
def _vispy_get_native_app(self):
|
|
111
|
+
raise NotImplementedError()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# ------------------------------------------------------------------ canvas ---
|
|
115
|
+
|
|
116
|
+
# You can mix this class with the native widget
|
|
117
|
+
class CanvasBackend(BaseCanvasBackend):
|
|
118
|
+
"""Template backend
|
|
119
|
+
|
|
120
|
+
Events to emit are shown below. Most backends will probably
|
|
121
|
+
have one method for each event:
|
|
122
|
+
|
|
123
|
+
self._vispy_canvas.events.initialize()
|
|
124
|
+
self._vispy_canvas.events.resize(size=(w, h))
|
|
125
|
+
self._vispy_canvas.events.draw(region=None)
|
|
126
|
+
self._vispy_canvas.close()
|
|
127
|
+
self._vispy_canvas.events.mouse_press(pos=(x, y), button=1,
|
|
128
|
+
modifiers=())
|
|
129
|
+
self._vispy_canvas.events.mouse_release(pos=(x, y), button=1,
|
|
130
|
+
modifiers=())
|
|
131
|
+
self._vispy_canvas.events.mouse_double_click(pos=(x, y), button=1,
|
|
132
|
+
modifiers=())
|
|
133
|
+
self._vispy_canvas.events.mouse_move(pos=(x, y), modifiers=())
|
|
134
|
+
self._vispy_canvas.events.mouse_wheel(pos=(x, y), delta=(0, 0),
|
|
135
|
+
modifiers=())
|
|
136
|
+
self._vispy_canvas.events.key_press(key=key, text=text, modifiers=())
|
|
137
|
+
self._vispy_canvas.events.key_release(key=key, text=text, modifiers=())
|
|
138
|
+
|
|
139
|
+
In most cases, if the window-cross is clicked, a native close-event is
|
|
140
|
+
generated, which should then call canvas.close(). The Canvas class is
|
|
141
|
+
responsible for firing the close event and calling
|
|
142
|
+
backend_canvas._vispy_close, which closes the native widget.
|
|
143
|
+
If this happens to result in a second close event, canvas.close() gets
|
|
144
|
+
called again, but Canvas knows it is closing so it stops there.
|
|
145
|
+
|
|
146
|
+
If canvas.close() is called (by the user), it calls
|
|
147
|
+
backend_canvas._vispy_close, which closes the native widget,
|
|
148
|
+
and we get the same stream of actions as above. This deviation from
|
|
149
|
+
having events come from the CanvasBackend is necessitated by how
|
|
150
|
+
different backends handle close events, and the various ways such
|
|
151
|
+
events can be triggered.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
def __init__(self, vispy_canvas, **kwargs):
|
|
155
|
+
BaseCanvasBackend.__init__(self, vispy_canvas)
|
|
156
|
+
# We use _process_backend_kwargs() to "serialize" the kwargs
|
|
157
|
+
# and to check whether they match this backend's capability
|
|
158
|
+
p = self._process_backend_kwargs(kwargs)
|
|
159
|
+
|
|
160
|
+
# Deal with config
|
|
161
|
+
# ... use context.config
|
|
162
|
+
# Deal with context
|
|
163
|
+
p.context.shared.add_ref('backend-name', self)
|
|
164
|
+
if p.context.shared.ref is self:
|
|
165
|
+
self._native_context = None # ...
|
|
166
|
+
else:
|
|
167
|
+
self._native_context = p.context.shared.ref._native_context
|
|
168
|
+
|
|
169
|
+
# NativeWidgetClass.__init__(self, foo, bar)
|
|
170
|
+
|
|
171
|
+
def _vispy_set_current(self):
|
|
172
|
+
# Make this the current context
|
|
173
|
+
raise NotImplementedError()
|
|
174
|
+
|
|
175
|
+
def _vispy_swap_buffers(self):
|
|
176
|
+
# Swap front and back buffer
|
|
177
|
+
raise NotImplementedError()
|
|
178
|
+
|
|
179
|
+
def _vispy_set_title(self, title):
|
|
180
|
+
# Set the window title. Has no effect for widgets
|
|
181
|
+
raise NotImplementedError()
|
|
182
|
+
|
|
183
|
+
def _vispy_set_size(self, w, h):
|
|
184
|
+
# Set size of the widget or window
|
|
185
|
+
raise NotImplementedError()
|
|
186
|
+
|
|
187
|
+
def _vispy_set_position(self, x, y):
|
|
188
|
+
# Set location of the widget or window. May have no effect for widgets
|
|
189
|
+
raise NotImplementedError()
|
|
190
|
+
|
|
191
|
+
def _vispy_set_visible(self, visible):
|
|
192
|
+
# Show or hide the window or widget
|
|
193
|
+
raise NotImplementedError()
|
|
194
|
+
|
|
195
|
+
def _vispy_set_fullscreen(self, fullscreen):
|
|
196
|
+
# Set the current fullscreen state
|
|
197
|
+
raise NotImplementedError()
|
|
198
|
+
|
|
199
|
+
def _vispy_update(self):
|
|
200
|
+
# Invoke a redraw
|
|
201
|
+
raise NotImplementedError()
|
|
202
|
+
|
|
203
|
+
def _vispy_close(self):
|
|
204
|
+
# Force the window or widget to shut down
|
|
205
|
+
raise NotImplementedError()
|
|
206
|
+
|
|
207
|
+
def _vispy_get_size(self):
|
|
208
|
+
# Should return widget size
|
|
209
|
+
raise NotImplementedError()
|
|
210
|
+
|
|
211
|
+
def _vispy_get_position(self):
|
|
212
|
+
# Should return widget position
|
|
213
|
+
raise NotImplementedError()
|
|
214
|
+
|
|
215
|
+
def _vispy_get_fullscreen(self):
|
|
216
|
+
# Should return the current fullscreen state
|
|
217
|
+
raise NotImplementedError()
|
|
218
|
+
|
|
219
|
+
def _vispy_get_native_canvas(self):
|
|
220
|
+
# Should return the native widget object.
|
|
221
|
+
# If this is self, this method can be omitted.
|
|
222
|
+
return self
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# ------------------------------------------------------------------- timer ---
|
|
226
|
+
|
|
227
|
+
class TimerBackend(BaseTimerBackend): # Can be mixed with native timer class
|
|
228
|
+
|
|
229
|
+
def __init__(self, vispy_timer):
|
|
230
|
+
BaseTimerBackend.__init__(self, vispy_timer)
|
|
231
|
+
|
|
232
|
+
def _vispy_start(self, interval):
|
|
233
|
+
raise NotImplementedError()
|
|
234
|
+
|
|
235
|
+
def _vispy_stop(self):
|
|
236
|
+
raise NotImplementedError()
|
|
237
|
+
|
|
238
|
+
def _vispy_timeout(self):
|
|
239
|
+
raise NotImplementedError()
|
|
240
|
+
|
|
241
|
+
def _vispy_get_native_timer(self):
|
|
242
|
+
# Should return the native widget object.
|
|
243
|
+
# If this is self, this method can be omitted.
|
|
244
|
+
return self
|