vispy 0.14.0__cp311-cp311-macosx_11_0_arm64.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.

Files changed (519) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +968 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1134 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +352 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1542 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +134 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +698 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +506 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +566 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1816 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1045 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +106 -0
  274. vispy/scene/cameras/base_camera.py +538 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +308 -0
  278. vispy/scene/cameras/perspective.py +333 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +173 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +446 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +473 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +17 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +4 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +485 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +163 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +796 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +105 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +688 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +810 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_histogram.py +24 -0
  477. vispy/visuals/tests/test_image.py +390 -0
  478. vispy/visuals/tests/test_image_complex.py +36 -0
  479. vispy/visuals/tests/test_infinite_line.py +53 -0
  480. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  481. vispy/visuals/tests/test_isosurface.py +22 -0
  482. vispy/visuals/tests/test_linear_region.py +152 -0
  483. vispy/visuals/tests/test_markers.py +54 -0
  484. vispy/visuals/tests/test_mesh.py +261 -0
  485. vispy/visuals/tests/test_mesh_normals.py +218 -0
  486. vispy/visuals/tests/test_polygon.py +112 -0
  487. vispy/visuals/tests/test_rectangle.py +163 -0
  488. vispy/visuals/tests/test_regular_polygon.py +111 -0
  489. vispy/visuals/tests/test_scalable_textures.py +180 -0
  490. vispy/visuals/tests/test_sdf.py +73 -0
  491. vispy/visuals/tests/test_spectrogram.py +42 -0
  492. vispy/visuals/tests/test_text.py +95 -0
  493. vispy/visuals/tests/test_volume.py +542 -0
  494. vispy/visuals/tests/test_windbarb.py +33 -0
  495. vispy/visuals/text/__init__.py +7 -0
  496. vispy/visuals/text/_sdf_cpu.cpython-311-darwin.so +0 -0
  497. vispy/visuals/text/_sdf_cpu.pyx +110 -0
  498. vispy/visuals/text/_sdf_gpu.py +316 -0
  499. vispy/visuals/text/text.py +675 -0
  500. vispy/visuals/transforms/__init__.py +34 -0
  501. vispy/visuals/transforms/_util.py +191 -0
  502. vispy/visuals/transforms/base_transform.py +233 -0
  503. vispy/visuals/transforms/chain.py +300 -0
  504. vispy/visuals/transforms/interactive.py +98 -0
  505. vispy/visuals/transforms/linear.py +564 -0
  506. vispy/visuals/transforms/nonlinear.py +398 -0
  507. vispy/visuals/transforms/tests/__init__.py +0 -0
  508. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  509. vispy/visuals/transforms/transform_system.py +339 -0
  510. vispy/visuals/tube.py +173 -0
  511. vispy/visuals/visual.py +923 -0
  512. vispy/visuals/volume.py +1335 -0
  513. vispy/visuals/windbarb.py +291 -0
  514. vispy/visuals/xyz_axis.py +34 -0
  515. vispy-0.14.0.dist-info/LICENSE.txt +36 -0
  516. vispy-0.14.0.dist-info/METADATA +218 -0
  517. vispy-0.14.0.dist-info/RECORD +519 -0
  518. vispy-0.14.0.dist-info/WHEEL +5 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
vispy/app/canvas.py ADDED
@@ -0,0 +1,828 @@
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
+ from __future__ import division, print_function
6
+
7
+ import sys
8
+ import numpy as np
9
+ from time import sleep
10
+
11
+ from ..util.event import EmitterGroup, Event, WarningEmitter
12
+ from ..util.ptime import time
13
+ from ..util.dpi import get_dpi
14
+ from ..util import config as util_config, logger
15
+ from . import Application, use_app
16
+ from ..gloo.context import (GLContext, set_current_canvas, forget_canvas)
17
+ from ..gloo import FrameBuffer, RenderBuffer
18
+
19
+
20
+ # todo: add functions for asking about current mouse/keyboard state
21
+ # todo: add hover enter/exit events
22
+ # todo: add focus events
23
+
24
+
25
+ class Canvas(object):
26
+ """Representation of a GUI element with an OpenGL context
27
+
28
+ Parameters
29
+ ----------
30
+ title : str
31
+ The widget title
32
+ size : (width, height)
33
+ The size of the window.
34
+ position : (x, y)
35
+ The position of the window in screen coordinates.
36
+ show : bool
37
+ Whether to show the widget immediately. Default False.
38
+ autoswap : bool
39
+ Whether to swap the buffers automatically after a draw event.
40
+ Default True. If True, the ``swap_buffers`` Canvas method will
41
+ be called last (by default) by the ``canvas.draw`` event handler.
42
+ app : Application | str
43
+ Give vispy Application instance to use as a backend.
44
+ (vispy.app is used by default.) If str, then an application
45
+ using the chosen backend (e.g., 'pyglet') will be created.
46
+ Note the canvas application can be accessed at ``canvas.app``.
47
+ create_native : bool
48
+ Whether to create the widget immediately. Default True.
49
+ vsync : bool
50
+ Enable vertical synchronization.
51
+ resizable : bool
52
+ Allow the window to be resized.
53
+ decorate : bool
54
+ Decorate the window. Default True.
55
+ fullscreen : bool | int
56
+ If False, windowed mode is used (default). If True, the default
57
+ monitor is used. If int, the given monitor number is used.
58
+ config : dict
59
+ A dict with OpenGL configuration options, which is combined
60
+ with the default configuration options and used to initialize
61
+ the context. See ``canvas.context.config`` for possible
62
+ options.
63
+ shared : Canvas | GLContext | None
64
+ An existing canvas or context to share OpenGL objects with.
65
+ keys : str | dict | None
66
+ Default key mapping to use. If 'interactive', escape and F11 will
67
+ close the canvas and toggle full-screen mode, respectively.
68
+ If dict, maps keys to functions. If dict values are strings,
69
+ they are assumed to be ``Canvas`` methods, otherwise they should
70
+ be callable.
71
+ parent : widget-object
72
+ The parent widget if this makes sense for the used backend.
73
+ dpi : float | None
74
+ Resolution in dots-per-inch to use for the canvas. If dpi is None,
75
+ then the value will be determined by querying the global config first,
76
+ and then the operating system.
77
+ always_on_top : bool
78
+ If True, try to create the window in always-on-top mode.
79
+ px_scale : int > 0
80
+ A scale factor to apply between logical and physical pixels in addition
81
+ to the actual scale factor determined by the backend. This option
82
+ allows the scale factor to be adjusted for testing.
83
+ backend_kwargs : dict
84
+ Keyword arguments to be supplied to the backend canvas object.
85
+
86
+ Notes
87
+ -----
88
+ The `Canvas` receives the following events:
89
+
90
+ * initialize
91
+ * resize
92
+ * draw
93
+ * mouse_press
94
+ * mouse_release
95
+ * mouse_double_click
96
+ * mouse_move
97
+ * mouse_wheel
98
+ * key_press
99
+ * key_release
100
+ * stylus
101
+ * touch
102
+ * close
103
+
104
+ The ordering of the mouse_double_click, mouse_press, and mouse_release
105
+ events are not guaranteed to be consistent between backends. Only certain
106
+ backends natively support double-clicking (currently Qt and WX); on other
107
+ backends, they are detected manually with a fixed time delay.
108
+ This can cause problems with accessibility, as increasing the OS detection
109
+ time or using a dedicated double-click button will not be respected.
110
+
111
+ Backend-specific arguments can be given through the `backend_kwargs`
112
+ argument.
113
+ """
114
+
115
+ def __init__(self, title='VisPy canvas', size=(800, 600), position=None,
116
+ show=False, autoswap=True, app=None, create_native=True,
117
+ vsync=False, resizable=True, decorate=True, fullscreen=False,
118
+ config=None, shared=None, keys=None, parent=None, dpi=None,
119
+ always_on_top=False, px_scale=1, backend_kwargs=None):
120
+
121
+ size = tuple(int(s) * px_scale for s in size)
122
+ if len(size) != 2:
123
+ raise ValueError('size must be a 2-element list')
124
+ title = str(title)
125
+ if not isinstance(fullscreen, (bool, int)):
126
+ raise TypeError('fullscreen must be bool or int')
127
+
128
+ # Initialize some values
129
+ self._autoswap = autoswap
130
+ self._title = title
131
+ self._frame_count = 0
132
+ self._fps = 0
133
+ self._basetime = time()
134
+ self._fps_callback = None
135
+ self._backend = None
136
+ self._closed = False
137
+ self._fps_window = 0.
138
+ self._px_scale = int(px_scale)
139
+
140
+ if dpi is None:
141
+ dpi = util_config['dpi']
142
+ if dpi is None:
143
+ dpi = get_dpi(raise_error=False)
144
+ self.dpi = dpi
145
+
146
+ # Create events
147
+ self.events = EmitterGroup(source=self,
148
+ initialize=Event,
149
+ resize=ResizeEvent,
150
+ draw=DrawEvent,
151
+ mouse_press=MouseEvent,
152
+ mouse_release=MouseEvent,
153
+ mouse_double_click=MouseEvent,
154
+ mouse_move=MouseEvent,
155
+ mouse_wheel=MouseEvent,
156
+ key_press=KeyEvent,
157
+ key_release=KeyEvent,
158
+ stylus=Event,
159
+ touch=Event,
160
+ close=Event)
161
+
162
+ # Deprecated paint emitter
163
+ emitter = WarningEmitter('Canvas.events.paint and Canvas.on_paint are '
164
+ 'deprecated; use Canvas.events.draw and '
165
+ 'Canvas.on_draw instead.',
166
+ source=self, type='draw',
167
+ event_class=DrawEvent)
168
+ self.events.add(paint=emitter)
169
+ self.events.draw.connect(self.events.paint)
170
+
171
+ # Get app instance
172
+ if app is None:
173
+ self._app = use_app(call_reuse=False)
174
+ elif isinstance(app, Application):
175
+ self._app = app
176
+ elif isinstance(app, str):
177
+ self._app = Application(app)
178
+ else:
179
+ raise ValueError('Invalid value for app %r' % app)
180
+
181
+ # Check shared and context
182
+ if shared is None:
183
+ pass
184
+ elif isinstance(shared, Canvas):
185
+ shared = shared.context.shared
186
+ elif isinstance(shared, GLContext):
187
+ shared = shared.shared
188
+ else:
189
+ raise TypeError('shared must be a Canvas, not %s' % type(shared))
190
+ config = config or {}
191
+ if not isinstance(config, dict):
192
+ raise TypeError('config must be a dict, not %s' % type(config))
193
+
194
+ # Create new context
195
+ self._context = GLContext(config, shared)
196
+
197
+ # Deal with special keys
198
+ self._set_keys(keys)
199
+
200
+ # store arguments that get set on Canvas init
201
+ self._backend_kwargs = dict(
202
+ title=title, size=size, position=position, show=show,
203
+ vsync=vsync, resizable=resizable, decorate=decorate,
204
+ fullscreen=fullscreen, context=self._context,
205
+ parent=parent, always_on_top=always_on_top)
206
+ if backend_kwargs is not None:
207
+ self._backend_kwargs.update(**backend_kwargs)
208
+
209
+ # Create widget now (always do this *last*, after all err checks)
210
+ if create_native:
211
+ self.create_native()
212
+
213
+ # Now we're ready to become current
214
+ self.set_current()
215
+
216
+ if '--vispy-fps' in sys.argv:
217
+ self.measure_fps()
218
+
219
+ def create_native(self):
220
+ """Create the native widget if not already done so. If the widget
221
+ is already created, this function does nothing.
222
+ """
223
+ if self._backend is not None:
224
+ return
225
+ # Make sure that the app is active
226
+ assert self._app.native
227
+ # Instantiate the backend with the right class
228
+ self._app.backend_module.CanvasBackend(self, **self._backend_kwargs)
229
+ # self._backend = set by BaseCanvasBackend
230
+ self._backend_kwargs = None # Clean up
231
+
232
+ # Connect to draw event (append to the end)
233
+ # Process GLIR commands at each paint event
234
+ self.events.draw.connect(self.context.flush_commands, position='last')
235
+ if self._autoswap:
236
+ self.events.draw.connect((self, 'swap_buffers'),
237
+ ref=True, position='last')
238
+
239
+ def _set_keys(self, keys):
240
+ if keys is not None:
241
+ if isinstance(keys, str):
242
+ if keys != 'interactive':
243
+ raise ValueError('keys, if string, must be "interactive", '
244
+ 'not %s' % (keys,))
245
+
246
+ def toggle_fs():
247
+ self.fullscreen = not self.fullscreen
248
+ keys = dict(escape='close', F11=toggle_fs)
249
+ else:
250
+ keys = {}
251
+ if not isinstance(keys, dict):
252
+ raise TypeError('keys must be a dict, str, or None')
253
+ if len(keys) > 0:
254
+ lower_keys = {}
255
+ # ensure all are callable
256
+ for key, val in keys.items():
257
+ if isinstance(val, str):
258
+ new_val = getattr(self, val, None)
259
+ if new_val is None:
260
+ raise ValueError('value %s is not an attribute of '
261
+ 'Canvas' % val)
262
+ val = new_val
263
+ if not hasattr(val, '__call__'):
264
+ raise TypeError('Entry for key %s is not callable' % key)
265
+ # convert to lower-case representation
266
+ lower_keys[key.lower()] = val
267
+ self._keys_check = lower_keys
268
+
269
+ def keys_check(event):
270
+ if event.key is not None:
271
+ use_name = event.key.name.lower()
272
+ if use_name in self._keys_check:
273
+ self._keys_check[use_name]()
274
+ self.events.key_press.connect(keys_check, ref=True)
275
+
276
+ @property
277
+ def context(self):
278
+ """The OpenGL context of the native widget
279
+
280
+ It gives access to OpenGL functions to call on this canvas object,
281
+ and to the shared context namespace.
282
+ """
283
+ return self._context
284
+
285
+ @property
286
+ def app(self):
287
+ """The vispy Application instance on which this Canvas is based."""
288
+ return self._app
289
+
290
+ @property
291
+ def native(self):
292
+ """The native widget object on which this Canvas is based."""
293
+ return self._backend._vispy_get_native_canvas()
294
+
295
+ @property
296
+ def dpi(self):
297
+ """The physical resolution of the canvas in dots per inch."""
298
+ return self._dpi
299
+
300
+ @dpi.setter
301
+ def dpi(self, dpi):
302
+ self._dpi = float(dpi)
303
+ self.update()
304
+
305
+ def connect(self, fun):
306
+ """Connect a function to an event
307
+
308
+ The name of the function
309
+ should be on_X, with X the name of the event (e.g. 'on_draw').
310
+
311
+ This method is typically used as a decorator on a function
312
+ definition for an event handler.
313
+
314
+ Parameters
315
+ ----------
316
+ fun : callable
317
+ The function.
318
+ """
319
+ # Get and check name
320
+ name = fun.__name__
321
+ if not name.startswith('on_'):
322
+ raise ValueError('When connecting a function based on its name, '
323
+ 'the name should start with "on_"')
324
+ eventname = name[3:]
325
+ # Get emitter
326
+ try:
327
+ emitter = self.events[eventname]
328
+ except KeyError:
329
+ raise ValueError(
330
+ 'Event "%s" not available on this canvas.' %
331
+ eventname)
332
+ # Connect
333
+ emitter.connect(fun)
334
+
335
+ # ---------------------------------------------------------------- size ---
336
+ @property
337
+ def size(self):
338
+ """The size of canvas/window."""
339
+ # Note that _px_scale is an additional factor applied in addition to
340
+ # the scale factor imposed by the backend.
341
+ size = self._backend._vispy_get_size()
342
+ return (size[0] // self._px_scale, size[1] // self._px_scale)
343
+
344
+ @size.setter
345
+ def size(self, size):
346
+ return self._backend._vispy_set_size(size[0] * self._px_scale,
347
+ size[1] * self._px_scale)
348
+
349
+ @property
350
+ def physical_size(self):
351
+ """The physical size of the canvas/window, which may differ from the
352
+ size property on backends that expose HiDPI.
353
+ """
354
+ return self._backend._vispy_get_physical_size()
355
+
356
+ @property
357
+ def pixel_scale(self):
358
+ """The ratio between the number of logical pixels, or 'points', and
359
+ the physical pixels on the device. In most cases this will be 1.0,
360
+ but on certain backends this will be greater than 1. This should be
361
+ used as a scaling factor when writing your own visualisations
362
+ with gloo (make a copy and multiply all your logical pixel values
363
+ by it). When writing Visuals or SceneGraph visualisations, this value
364
+ is exposed as `TransformSystem.px_scale`.
365
+ """
366
+ return self.physical_size[0] / self.size[0]
367
+
368
+ @property
369
+ def fullscreen(self):
370
+ return self._backend._vispy_get_fullscreen()
371
+
372
+ @fullscreen.setter
373
+ def fullscreen(self, fullscreen):
374
+ return self._backend._vispy_set_fullscreen(fullscreen)
375
+
376
+ # ------------------------------------------------------------ position ---
377
+ @property
378
+ def position(self):
379
+ """The position of canvas/window relative to screen."""
380
+ return self._backend._vispy_get_position()
381
+
382
+ @position.setter
383
+ def position(self, position):
384
+ assert len(position) == 2
385
+ return self._backend._vispy_set_position(position[0], position[1])
386
+
387
+ # --------------------------------------------------------------- title ---
388
+ @property
389
+ def title(self):
390
+ """The title of canvas/window."""
391
+ return self._title
392
+
393
+ @title.setter
394
+ def title(self, title):
395
+ self._title = title
396
+ self._backend._vispy_set_title(title)
397
+
398
+ # ----------------------------------------------------------------- fps ---
399
+ @property
400
+ def fps(self):
401
+ """The fps of canvas/window, as the rate that events.draw is emitted."""
402
+ return self._fps
403
+
404
+ def set_current(self, event=None):
405
+ """Make this the active GL canvas
406
+
407
+ Parameters
408
+ ----------
409
+ event : None
410
+ Not used.
411
+ """
412
+ self._backend._vispy_set_current()
413
+ set_current_canvas(self)
414
+
415
+ def swap_buffers(self, event=None):
416
+ """Swap GL buffers such that the offscreen buffer becomes visible
417
+
418
+ Parameters
419
+ ----------
420
+ event : None
421
+ Not used.
422
+ """
423
+ self._backend._vispy_swap_buffers()
424
+
425
+ def show(self, visible=True, run=False):
426
+ """Show or hide the canvas
427
+
428
+ Parameters
429
+ ----------
430
+ visible : bool
431
+ Make the canvas visible.
432
+ run : bool
433
+ Run the backend event loop.
434
+ """
435
+ self._backend._vispy_set_visible(visible)
436
+ if run:
437
+ self.app.run()
438
+
439
+ def update(self, event=None):
440
+ """Inform the backend that the Canvas needs to be redrawn
441
+
442
+ Parameters
443
+ ----------
444
+ event : None
445
+ Not used.
446
+ """
447
+ if self._backend is not None:
448
+ self._backend._vispy_update()
449
+
450
+ def close(self):
451
+ """Close the canvas
452
+
453
+ Notes
454
+ -----
455
+ This will usually destroy the GL context. For Qt, the context
456
+ (and widget) will be destroyed only if the widget is top-level.
457
+ To avoid having the widget destroyed (more like standard Qt
458
+ behavior), consider making the widget a sub-widget.
459
+ """
460
+ if self._backend is not None and not self._closed:
461
+ logger.debug('Closing canvas %s' % (self,))
462
+ self._closed = True
463
+ self.events.close()
464
+ self._backend._vispy_close()
465
+ forget_canvas(self)
466
+
467
+ def _update_fps(self, event):
468
+ """Update the fps after every window"""
469
+ self._frame_count += 1
470
+ diff = time() - self._basetime
471
+ if (diff > self._fps_window):
472
+ self._fps = self._frame_count / diff
473
+ self._basetime = time()
474
+ self._frame_count = 0
475
+ self._fps_callback(self.fps)
476
+
477
+ def measure_fps(self, window=1, callback='%1.1f FPS'):
478
+ """Measure the current FPS
479
+
480
+ Sets the update window, connects the draw event to update_fps
481
+ and sets the callback function.
482
+
483
+ Parameters
484
+ ----------
485
+ window : float
486
+ The time-window (in seconds) to calculate FPS. Default 1.0.
487
+ callback : function | str
488
+ The function to call with the float FPS value, or the string
489
+ to be formatted with the fps value and then printed. The
490
+ default is ``'%1.1f FPS'``. If callback evaluates to False, the
491
+ FPS measurement is stopped.
492
+ """
493
+ # Connect update_fps function to draw
494
+ self.events.draw.disconnect(self._update_fps)
495
+ if callback:
496
+ if isinstance(callback, str):
497
+ callback_str = callback # because callback gets overwritten
498
+
499
+ def callback(x):
500
+ print(callback_str % x)
501
+
502
+ self._fps_window = window
503
+ self.events.draw.connect(self._update_fps)
504
+ self._fps_callback = callback
505
+ else:
506
+ self._fps_callback = None
507
+
508
+ # ---------------------------------------------------------------- misc ---
509
+ def __repr__(self):
510
+ return ('<%s (%s) at %s>'
511
+ % (self.__class__.__name__,
512
+ self.app.backend_name, hex(id(self))))
513
+
514
+ def _repr_mimebundle_(self, *args, **kwargs):
515
+ """If the backend implements _repr_mimebundle_, we proxy it here.
516
+ """
517
+ # See https://ipython.readthedocs.io/en/stable/config/integrating.html
518
+ f = getattr(self._backend, "_repr_mimebundle_", None)
519
+ if f is not None:
520
+ return f(*args, **kwargs)
521
+ else:
522
+ # Let Jupyter know this failed - otherwise the standard repr is not shown
523
+ raise NotImplementedError()
524
+
525
+ def _ipython_display_(self):
526
+ """If the backend implements _ipython_display_, we proxy it here.
527
+ """
528
+ # See https://ipython.readthedocs.io/en/stable/config/integrating.html
529
+ f = getattr(self._backend, "_ipython_display_", None)
530
+ if f is not None:
531
+ return f()
532
+ else:
533
+ # Let Jupyter know this failed - otherwise the standard repr is not shown
534
+ raise NotImplementedError()
535
+
536
+ def __enter__(self):
537
+ logger.debug('Context manager enter starting for %s' % (self,))
538
+ self.show()
539
+ self._backend._vispy_warmup()
540
+ return self
541
+
542
+ def __exit__(self, type, value, traceback):
543
+ # ensure all GL calls are complete
544
+ logger.debug('Context manager exit starting for %s' % (self,))
545
+ if not self._closed:
546
+ self._backend._vispy_set_current()
547
+ self.context.finish()
548
+ self.close()
549
+ sleep(0.1) # ensure window is really closed/destroyed
550
+ logger.debug('Context manager exit complete for %s' % (self,))
551
+
552
+ def render(self, alpha=True):
553
+ """Render the canvas to an offscreen buffer and return the image array.
554
+
555
+ Parameters
556
+ ----------
557
+ alpha : bool
558
+ If True (default) produce an RGBA array (M, N, 4). If False,
559
+ remove the Alpha channel and return the RGB array (M, N, 3).
560
+ This may be useful if blending of various elements requires a
561
+ solid background to produce the expected visualization.
562
+
563
+ Returns
564
+ -------
565
+ image : array
566
+ Numpy array of type ubyte and shape (h, w, 4). Index [0, 0] is the
567
+ upper-left corner of the rendered region. If ``alpha`` is ``False``,
568
+ then only 3 channels will be returned (RGB).
569
+
570
+
571
+ """
572
+ self.set_current()
573
+ size = self.physical_size
574
+ fbo = FrameBuffer(color=RenderBuffer(size[::-1]),
575
+ depth=RenderBuffer(size[::-1]))
576
+
577
+ try:
578
+ fbo.activate()
579
+ self.events.draw()
580
+ result = fbo.read()
581
+ finally:
582
+ fbo.deactivate()
583
+
584
+ if not alpha:
585
+ result = result[..., :3]
586
+ return result
587
+
588
+
589
+ # Event subclasses specific to the Canvas
590
+ class MouseEvent(Event):
591
+ """Mouse event class
592
+
593
+ Note that each event object has an attribute for each of the input
594
+ arguments listed below, as well as a "time" attribute with the event's
595
+ precision start time.
596
+
597
+ Parameters
598
+ ----------
599
+ type : str
600
+ String indicating the event type (e.g. mouse_press, key_release)
601
+ pos : (int, int)
602
+ The position of the mouse (in screen coordinates).
603
+ button : int | None
604
+ The button that generated this event (can be None).
605
+ Left=1, right=2, middle=3. During a mouse drag, this
606
+ will return the button that started the drag (same thing as
607
+ ``event.press_event.button``).
608
+ buttons : [int, ...]
609
+ The list of buttons pressed during this event.
610
+ modifiers : tuple of Key instances
611
+ Tuple that specifies which modifier keys were pressed down at the
612
+ time of the event (shift, control, alt, meta).
613
+ delta : (float, float)
614
+ The amount of scrolling in horizontal and vertical direction. One
615
+ "tick" corresponds to a delta of 1.0.
616
+ press_event : MouseEvent
617
+ The press event that was generated at the start of the current drag,
618
+ if any.
619
+ last_event : MouseEvent
620
+ The MouseEvent immediately preceding the current event. During drag
621
+ operations, all generated events retain their last_event properties,
622
+ allowing the entire drag to be reconstructed.
623
+ native : object (optional)
624
+ The native GUI event object
625
+ **kwargs : keyword arguments
626
+ All extra keyword arguments become attributes of the event object.
627
+ """
628
+
629
+ def __init__(self, type, pos=None, button=None, buttons=None,
630
+ modifiers=None, delta=None, last_event=None, press_event=None,
631
+ **kwargs):
632
+ Event.__init__(self, type, **kwargs)
633
+ self._pos = np.array([0, 0]) if (pos is None) else np.array(pos)
634
+ self._button = int(button) if (button is not None) else None
635
+ # Explicitly add button to buttons if newly pressed, check #2344 for more reference
636
+ newly_pressed_buttons = [button] if button is not None and type == 'mouse_press' else []
637
+ self._buttons = [] if (buttons is None) else buttons + newly_pressed_buttons
638
+ self._modifiers = tuple(modifiers or ())
639
+ self._delta = np.zeros(2) if (delta is None) else np.array(delta)
640
+ self._last_event = last_event
641
+ self._press_event = press_event
642
+ self._time = time()
643
+
644
+ @property
645
+ def pos(self):
646
+ return self._pos
647
+
648
+ @property
649
+ def button(self):
650
+ return self._button
651
+
652
+ @property
653
+ def buttons(self):
654
+ return self._buttons
655
+
656
+ @property
657
+ def modifiers(self):
658
+ return self._modifiers
659
+
660
+ @property
661
+ def delta(self):
662
+ return self._delta
663
+
664
+ @property
665
+ def press_event(self):
666
+ return self._press_event
667
+
668
+ @property
669
+ def last_event(self):
670
+ return self._last_event
671
+
672
+ @property
673
+ def time(self):
674
+ return self._time
675
+
676
+ def _forget_last_event(self):
677
+ # Needed to break otherwise endless last-event chains
678
+ self._last_event = None
679
+
680
+ @property
681
+ def is_dragging(self):
682
+ """Indicates whether this event is part of a mouse drag operation."""
683
+ return self.press_event is not None
684
+
685
+ def drag_events(self):
686
+ """Return a list of all mouse events in the current drag operation.
687
+
688
+ Returns None if there is no current drag operation.
689
+ """
690
+ if not self.is_dragging:
691
+ return None
692
+
693
+ event = self
694
+ events = []
695
+ while True:
696
+ # mouse_press events can only be the start of a trail
697
+ if event is None or event.type == 'mouse_press':
698
+ break
699
+ events.append(event)
700
+ event = event.last_event
701
+
702
+ return events[::-1]
703
+
704
+ def trail(self):
705
+ """Return an (N, 2) array of mouse coordinates for every event in the
706
+ current mouse drag operation.
707
+
708
+ Returns None if there is no current drag operation.
709
+ """
710
+ events = self.drag_events()
711
+ if events is None:
712
+ return None
713
+
714
+ trail = np.empty((len(events), 2), dtype=int)
715
+ for i, ev in enumerate(events):
716
+ trail[i] = ev.pos
717
+
718
+ return trail
719
+
720
+
721
+ class KeyEvent(Event):
722
+ """Key event class
723
+
724
+ Note that each event object has an attribute for each of the input
725
+ arguments listed below.
726
+
727
+ Parameters
728
+ ----------
729
+ type : str
730
+ String indicating the event type (e.g. mouse_press, key_release)
731
+ key : vispy.keys.Key instance
732
+ The Key object for this event. Can be compared to string names.
733
+ text : str
734
+ The text representation of the key (can be an empty string).
735
+ modifiers : tuple of Key instances
736
+ Tuple that specifies which modifier keys were pressed down at the
737
+ time of the event (shift, control, alt, meta).
738
+ native : object (optional)
739
+ The native GUI event object
740
+ **kwargs : keyword arguments
741
+ All extra keyword arguments become attributes of the event object.
742
+ """
743
+
744
+ def __init__(self, type, key=None, text='', modifiers=None, **kwargs):
745
+ Event.__init__(self, type, **kwargs)
746
+ self._key = key
747
+ self._text = text
748
+ self._modifiers = tuple(modifiers or ())
749
+
750
+ @property
751
+ def key(self):
752
+ return self._key
753
+
754
+ @property
755
+ def text(self):
756
+ return self._text
757
+
758
+ @property
759
+ def modifiers(self):
760
+ return self._modifiers
761
+
762
+
763
+ class ResizeEvent(Event):
764
+ """Resize event class
765
+
766
+ Note that each event object has an attribute for each of the input
767
+ arguments listed below.
768
+
769
+ Parameters
770
+ ----------
771
+ type : str
772
+ String indicating the event type (e.g. mouse_press, key_release)
773
+ size : (int, int)
774
+ The new size of the Canvas, in points (logical pixels).
775
+ physical_size : (int, int)
776
+ The new physical size of the Canvas, in pixels.
777
+ native : object (optional)
778
+ The native GUI event object
779
+ **kwargs : extra keyword arguments
780
+ All extra keyword arguments become attributes of the event object.
781
+ """
782
+
783
+ def __init__(self, type, size=None, physical_size=None, **kwargs):
784
+ Event.__init__(self, type, **kwargs)
785
+ self._size = tuple(size)
786
+ if physical_size is None:
787
+ self._physical_size = self._size
788
+ else:
789
+ self._physical_size = tuple(physical_size)
790
+
791
+ @property
792
+ def size(self):
793
+ return self._size
794
+
795
+ @property
796
+ def physical_size(self):
797
+ return self._physical_size
798
+
799
+
800
+ class DrawEvent(Event):
801
+ """Draw event class
802
+
803
+ This type of event is sent to Canvas.events.draw when a redraw
804
+ is required.
805
+
806
+ Note that each event object has an attribute for each of the input
807
+ arguments listed below.
808
+
809
+ Parameters
810
+ ----------
811
+ type : str
812
+ String indicating the event type (e.g. mouse_press, key_release)
813
+ region : (int, int, int, int) or None
814
+ The region of the canvas which needs to be redrawn (x, y, w, h).
815
+ If None, the entire canvas must be redrawn.
816
+ native : object (optional)
817
+ The native GUI event object
818
+ **kwargs : extra keyword arguments
819
+ All extra keyword arguments become attributes of the event object.
820
+ """
821
+
822
+ def __init__(self, type, region=None, **kwargs):
823
+ Event.__init__(self, type, **kwargs)
824
+ self._region = region
825
+
826
+ @property
827
+ def region(self):
828
+ return self._region