psychopy 2024.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of psychopy might be problematic. Click here for more details.

Files changed (2950) hide show
  1. psychopy/CHANGELOG.txt +3571 -0
  2. psychopy/LICENSE.txt +11 -0
  3. psychopy/LICENSES.txt +55 -0
  4. psychopy/__init__.py +74 -0
  5. psychopy/alerts/__init__.py +65 -0
  6. psychopy/alerts/_alerts.py +184 -0
  7. psychopy/alerts/_errorHandler.py +51 -0
  8. psychopy/alerts/alertsCatalogue/1000.yaml +0 -0
  9. psychopy/alerts/alertsCatalogue/1100.yaml +0 -0
  10. psychopy/alerts/alertsCatalogue/1500.yaml +0 -0
  11. psychopy/alerts/alertsCatalogue/2000.yaml +0 -0
  12. psychopy/alerts/alertsCatalogue/2100.yaml +0 -0
  13. psychopy/alerts/alertsCatalogue/2110.yaml +0 -0
  14. psychopy/alerts/alertsCatalogue/2115.yaml +21 -0
  15. psychopy/alerts/alertsCatalogue/2120.yaml +22 -0
  16. psychopy/alerts/alertsCatalogue/2150.yaml +0 -0
  17. psychopy/alerts/alertsCatalogue/2155.yaml +21 -0
  18. psychopy/alerts/alertsCatalogue/2300.yaml +0 -0
  19. psychopy/alerts/alertsCatalogue/2500.yaml +0 -0
  20. psychopy/alerts/alertsCatalogue/3000.yaml +0 -0
  21. psychopy/alerts/alertsCatalogue/3100.yaml +0 -0
  22. psychopy/alerts/alertsCatalogue/3110.yaml +25 -0
  23. psychopy/alerts/alertsCatalogue/3115.yaml +24 -0
  24. psychopy/alerts/alertsCatalogue/3200.yaml +0 -0
  25. psychopy/alerts/alertsCatalogue/3400.yaml +0 -0
  26. psychopy/alerts/alertsCatalogue/4000.yaml +0 -0
  27. psychopy/alerts/alertsCatalogue/4051.yaml +19 -0
  28. psychopy/alerts/alertsCatalogue/4052.yaml +19 -0
  29. psychopy/alerts/alertsCatalogue/4100.yaml +0 -0
  30. psychopy/alerts/alertsCatalogue/4105.yaml +18 -0
  31. psychopy/alerts/alertsCatalogue/4115.yaml +21 -0
  32. psychopy/alerts/alertsCatalogue/4120.yaml +19 -0
  33. psychopy/alerts/alertsCatalogue/4125.yaml +23 -0
  34. psychopy/alerts/alertsCatalogue/4200.yaml +0 -0
  35. psychopy/alerts/alertsCatalogue/4205.yaml +19 -0
  36. psychopy/alerts/alertsCatalogue/4210.yaml +19 -0
  37. psychopy/alerts/alertsCatalogue/4305.yaml +21 -0
  38. psychopy/alerts/alertsCatalogue/4310.yaml +21 -0
  39. psychopy/alerts/alertsCatalogue/4315.yaml +21 -0
  40. psychopy/alerts/alertsCatalogue/4320.yaml +19 -0
  41. psychopy/alerts/alertsCatalogue/4325.yaml +23 -0
  42. psychopy/alerts/alertsCatalogue/4330.yaml +19 -0
  43. psychopy/alerts/alertsCatalogue/4335.yaml +19 -0
  44. psychopy/alerts/alertsCatalogue/4340.yaml +19 -0
  45. psychopy/alerts/alertsCatalogue/4405.yaml +24 -0
  46. psychopy/alerts/alertsCatalogue/4505.yaml +22 -0
  47. psychopy/alerts/alertsCatalogue/4510.yaml +25 -0
  48. psychopy/alerts/alertsCatalogue/4520.yaml +26 -0
  49. psychopy/alerts/alertsCatalogue/4530.yaml +23 -0
  50. psychopy/alerts/alertsCatalogue/4540.yaml +19 -0
  51. psychopy/alerts/alertsCatalogue/4545.yaml +22 -0
  52. psychopy/alerts/alertsCatalogue/4550.yaml +19 -0
  53. psychopy/alerts/alertsCatalogue/4605.yaml +22 -0
  54. psychopy/alerts/alertsCatalogue/4610.yaml +22 -0
  55. psychopy/alerts/alertsCatalogue/4615.yaml +19 -0
  56. psychopy/alerts/alertsCatalogue/4705.yaml +19 -0
  57. psychopy/alerts/alertsCatalogue/4710.yaml +19 -0
  58. psychopy/alerts/alertsCatalogue/5000.yaml +0 -0
  59. psychopy/alerts/alertsCatalogue/5055.yaml +25 -0
  60. psychopy/alerts/alertsCatalogue/6000.yaml +0 -0
  61. psychopy/alerts/alertsCatalogue/6105.yaml +18 -0
  62. psychopy/alerts/alertsCatalogue/7105.yaml +19 -0
  63. psychopy/alerts/alertsCatalogue/8105.yaml +21 -0
  64. psychopy/alerts/alertsCatalogue/8110.yaml +21 -0
  65. psychopy/alerts/alertsCatalogue/9998.yaml +19 -0
  66. psychopy/alerts/alertsCatalogue/9999.yaml +19 -0
  67. psychopy/alerts/alertsCatalogue/alertCategories.yaml +109 -0
  68. psychopy/alerts/alertsCatalogue/alertTemplate.yaml +19 -0
  69. psychopy/alerts/alertsCatalogue/alertmsg.py +144 -0
  70. psychopy/alerts/alertsCatalogue/generateAlertmsg.py +34 -0
  71. psychopy/alerts/alerttools.py +338 -0
  72. psychopy/app/Resources/Psychopy Window Favicon@16w.png +0 -0
  73. psychopy/app/Resources/Psychopy Window Favicon@32w.png +0 -0
  74. psychopy/app/Resources/README.md +12 -0
  75. psychopy/app/Resources/USB-C.png +0 -0
  76. psychopy/app/Resources/USB.png +0 -0
  77. psychopy/app/Resources/__init__.py +0 -0
  78. psychopy/app/Resources/builder.ico +0 -0
  79. psychopy/app/Resources/classic/FlowBottom_CompLeft.png +0 -0
  80. psychopy/app/Resources/classic/FlowBottom_CompRight.png +0 -0
  81. psychopy/app/Resources/classic/FlowTop_CompLeft.png +0 -0
  82. psychopy/app/Resources/classic/FlowTop_CompRight.png +0 -0
  83. psychopy/app/Resources/classic/README.txt +9 -0
  84. psychopy/app/Resources/classic/__init__.py +0 -0
  85. psychopy/app/Resources/classic/_layouts.ai +1138 -1
  86. psychopy/app/Resources/classic/add.png +0 -0
  87. psychopy/app/Resources/classic/add@2x.png +0 -0
  88. psychopy/app/Resources/classic/addExp32.png +0 -0
  89. psychopy/app/Resources/classic/alerts.png +0 -0
  90. psychopy/app/Resources/classic/beta.png +0 -0
  91. psychopy/app/Resources/classic/browser.png +0 -0
  92. psychopy/app/Resources/classic/browser@2x.png +0 -0
  93. psychopy/app/Resources/classic/bug16.png +0 -0
  94. psychopy/app/Resources/classic/circle_mask.png +0 -0
  95. psychopy/app/Resources/classic/circle_mask@2x.png +0 -0
  96. psychopy/app/Resources/classic/clear.png +0 -0
  97. psychopy/app/Resources/classic/clear@2x.png +0 -0
  98. psychopy/app/Resources/classic/coderclass16.png +0 -0
  99. psychopy/app/Resources/classic/coderfunc16.png +0 -0
  100. psychopy/app/Resources/classic/coderimport16.png +0 -0
  101. psychopy/app/Resources/classic/coderjs16.png +0 -0
  102. psychopy/app/Resources/classic/coderpython16.png +0 -0
  103. psychopy/app/Resources/classic/codervar16.png +0 -0
  104. psychopy/app/Resources/classic/cogwindow32.png +0 -0
  105. psychopy/app/Resources/classic/color32.png +0 -0
  106. psychopy/app/Resources/classic/compile32.png +0 -0
  107. psychopy/app/Resources/classic/compile_js.png +0 -0
  108. psychopy/app/Resources/classic/compile_js@2x.png +0 -0
  109. psychopy/app/Resources/classic/compile_py.png +0 -0
  110. psychopy/app/Resources/classic/compile_py@2x.png +0 -0
  111. psychopy/app/Resources/classic/copy16.png +0 -0
  112. psychopy/app/Resources/classic/currentFile.png +0 -0
  113. psychopy/app/Resources/classic/currentFile@2x.png +0 -0
  114. psychopy/app/Resources/classic/delete16.png +0 -0
  115. psychopy/app/Resources/classic/desktop.png +0 -0
  116. psychopy/app/Resources/classic/desktop@2x.png +0 -0
  117. psychopy/app/Resources/classic/dirup16.png +0 -0
  118. psychopy/app/Resources/classic/docclose16.png +0 -0
  119. psychopy/app/Resources/classic/download.png +0 -0
  120. psychopy/app/Resources/classic/edit.png +0 -0
  121. psychopy/app/Resources/classic/edit@2x.png +0 -0
  122. psychopy/app/Resources/classic/editbtn.png +0 -0
  123. psychopy/app/Resources/classic/editbtn16.png +0 -0
  124. psychopy/app/Resources/classic/editbtn16@2x.png +0 -0
  125. psychopy/app/Resources/classic/editbtn@2x.png +0 -0
  126. psychopy/app/Resources/classic/email.png +0 -0
  127. psychopy/app/Resources/classic/email@2x.png +0 -0
  128. psychopy/app/Resources/classic/experiment.png +0 -0
  129. psychopy/app/Resources/classic/experiment@2x.png +0 -0
  130. psychopy/app/Resources/classic/expsettings.png +0 -0
  131. psychopy/app/Resources/classic/expsettings@2x.png +0 -0
  132. psychopy/app/Resources/classic/file.png +0 -0
  133. psychopy/app/Resources/classic/file@2x.png +0 -0
  134. psychopy/app/Resources/classic/filecsv16.png +0 -0
  135. psychopy/app/Resources/classic/fileimage16.png +0 -0
  136. psychopy/app/Resources/classic/filenew.png +0 -0
  137. psychopy/app/Resources/classic/filenew32.png +0 -0
  138. psychopy/app/Resources/classic/filenew@2x.png +0 -0
  139. psychopy/app/Resources/classic/fileopen.png +0 -0
  140. psychopy/app/Resources/classic/fileopen32.png +0 -0
  141. psychopy/app/Resources/classic/fileopen@2x.png +0 -0
  142. psychopy/app/Resources/classic/filesave.png +0 -0
  143. psychopy/app/Resources/classic/filesave32.png +0 -0
  144. psychopy/app/Resources/classic/filesave@2x.png +0 -0
  145. psychopy/app/Resources/classic/filesaveas.png +0 -0
  146. psychopy/app/Resources/classic/filesaveas32.png +0 -0
  147. psychopy/app/Resources/classic/filesaveas@2x.png +0 -0
  148. psychopy/app/Resources/classic/fileunknown16.png +0 -0
  149. psychopy/app/Resources/classic/filter.png +0 -0
  150. psychopy/app/Resources/classic/filter@2x.png +0 -0
  151. psychopy/app/Resources/classic/folder-open16.png +0 -0
  152. psychopy/app/Resources/classic/folder16.png +0 -0
  153. psychopy/app/Resources/classic/foldernew16.png +0 -0
  154. psychopy/app/Resources/classic/fork.png +0 -0
  155. psychopy/app/Resources/classic/fork@2x.png +0 -0
  156. psychopy/app/Resources/classic/github.png +0 -0
  157. psychopy/app/Resources/classic/github@2x.png +0 -0
  158. psychopy/app/Resources/classic/globe.png +0 -0
  159. psychopy/app/Resources/classic/globe@2x.png +0 -0
  160. psychopy/app/Resources/classic/globe_bug.png +0 -0
  161. psychopy/app/Resources/classic/globe_bug@2x.png +0 -0
  162. psychopy/app/Resources/classic/globe_greensync.png +0 -0
  163. psychopy/app/Resources/classic/globe_greensync@2x.png +0 -0
  164. psychopy/app/Resources/classic/globe_info.png +0 -0
  165. psychopy/app/Resources/classic/globe_info@2x.png +0 -0
  166. psychopy/app/Resources/classic/globe_magnifier.png +0 -0
  167. psychopy/app/Resources/classic/globe_magnifier@2x.png +0 -0
  168. psychopy/app/Resources/classic/globe_run.png +0 -0
  169. psychopy/app/Resources/classic/globe_run@2x.png +0 -0
  170. psychopy/app/Resources/classic/globe_user.png +0 -0
  171. psychopy/app/Resources/classic/globe_user@2x.png +0 -0
  172. psychopy/app/Resources/classic/goto16.png +0 -0
  173. psychopy/app/Resources/classic/greendot.png +0 -0
  174. psychopy/app/Resources/classic/greendot@2x.png +0 -0
  175. psychopy/app/Resources/classic/greenglobe.png +0 -0
  176. psychopy/app/Resources/classic/greenglobe@2x.png +0 -0
  177. psychopy/app/Resources/classic/greenglobe_bug.png +0 -0
  178. psychopy/app/Resources/classic/greenglobe_bug@2x.png +0 -0
  179. psychopy/app/Resources/classic/greenglobe_greensync.png +0 -0
  180. psychopy/app/Resources/classic/greenglobe_greensync@2x.png +0 -0
  181. psychopy/app/Resources/classic/greenglobe_info.png +0 -0
  182. psychopy/app/Resources/classic/greenglobe_info@2x.png +0 -0
  183. psychopy/app/Resources/classic/greenglobe_magnifier.png +0 -0
  184. psychopy/app/Resources/classic/greenglobe_magnifier@2x.png +0 -0
  185. psychopy/app/Resources/classic/greenglobe_run.png +0 -0
  186. psychopy/app/Resources/classic/greenglobe_run@2x.png +0 -0
  187. psychopy/app/Resources/classic/greenglobe_user.png +0 -0
  188. psychopy/app/Resources/classic/greenglobe_user@2x.png +0 -0
  189. psychopy/app/Resources/classic/greydot.png +0 -0
  190. psychopy/app/Resources/classic/greydot@2x.png +0 -0
  191. psychopy/app/Resources/classic/greytick.png +0 -0
  192. psychopy/app/Resources/classic/greytick@2x.png +0 -0
  193. psychopy/app/Resources/classic/invalid_img.png +0 -0
  194. psychopy/app/Resources/classic/jsPilot.png +0 -0
  195. psychopy/app/Resources/classic/jsPilot@2x.png +0 -0
  196. psychopy/app/Resources/classic/jsRun.png +0 -0
  197. psychopy/app/Resources/classic/jsRun@2x.png +0 -0
  198. psychopy/app/Resources/classic/libroot.png +0 -0
  199. psychopy/app/Resources/classic/libroot@2x.png +0 -0
  200. psychopy/app/Resources/classic/monitor16.png +0 -0
  201. psychopy/app/Resources/classic/monitors.png +0 -0
  202. psychopy/app/Resources/classic/monitors16.png +0 -0
  203. psychopy/app/Resources/classic/monitors32.png +0 -0
  204. psychopy/app/Resources/classic/monitors@2x.png +0 -0
  205. psychopy/app/Resources/classic/orangedot.png +0 -0
  206. psychopy/app/Resources/classic/orangedot@2x.png +0 -0
  207. psychopy/app/Resources/classic/pavlovia.png +0 -0
  208. psychopy/app/Resources/classic/pavlovia16.png +0 -0
  209. psychopy/app/Resources/classic/pavlovia16@2x.png +0 -0
  210. psychopy/app/Resources/classic/pavlovia@2x.png +0 -0
  211. psychopy/app/Resources/classic/pavsync.png +0 -0
  212. psychopy/app/Resources/classic/pavsync@2x.png +0 -0
  213. psychopy/app/Resources/classic/person_off.png +0 -0
  214. psychopy/app/Resources/classic/person_off@2x.png +0 -0
  215. psychopy/app/Resources/classic/person_on.png +0 -0
  216. psychopy/app/Resources/classic/person_on@2x.png +0 -0
  217. psychopy/app/Resources/classic/plugins32.png +0 -0
  218. psychopy/app/Resources/classic/plus.png +0 -0
  219. psychopy/app/Resources/classic/plus@2x.png +0 -0
  220. psychopy/app/Resources/classic/preferences-app.png +0 -0
  221. psychopy/app/Resources/classic/preferences-app48.png +0 -0
  222. psychopy/app/Resources/classic/preferences-app@2x.png +0 -0
  223. psychopy/app/Resources/classic/preferences-conn.png +0 -0
  224. psychopy/app/Resources/classic/preferences-conn48.png +0 -0
  225. psychopy/app/Resources/classic/preferences-conn@2x.png +0 -0
  226. psychopy/app/Resources/classic/preferences-debug.png +0 -0
  227. psychopy/app/Resources/classic/preferences-debug@2x.png +0 -0
  228. psychopy/app/Resources/classic/preferences-general.png +0 -0
  229. psychopy/app/Resources/classic/preferences-general48.png +0 -0
  230. psychopy/app/Resources/classic/preferences-general@2x.png +0 -0
  231. psychopy/app/Resources/classic/preferences-hardware.png +0 -0
  232. psychopy/app/Resources/classic/preferences-hardware48.png +0 -0
  233. psychopy/app/Resources/classic/preferences-hardware@2x.png +0 -0
  234. psychopy/app/Resources/classic/preferences-keyboard.png +0 -0
  235. psychopy/app/Resources/classic/preferences-keyboard48.png +0 -0
  236. psychopy/app/Resources/classic/preferences-keyboard@2x.png +0 -0
  237. psychopy/app/Resources/classic/preferences-pilot.png +0 -0
  238. psychopy/app/Resources/classic/preferences-pilot@2x.png +0 -0
  239. psychopy/app/Resources/classic/preferences32.png +0 -0
  240. psychopy/app/Resources/classic/pyPilot.png +0 -0
  241. psychopy/app/Resources/classic/pyPilot@2x.png +0 -0
  242. psychopy/app/Resources/classic/pyRun.png +0 -0
  243. psychopy/app/Resources/classic/pyRun@2x.png +0 -0
  244. psychopy/app/Resources/classic/reddot.png +0 -0
  245. psychopy/app/Resources/classic/reddot@2x.png +0 -0
  246. psychopy/app/Resources/classic/redglobe.png +0 -0
  247. psychopy/app/Resources/classic/redglobe@2x.png +0 -0
  248. psychopy/app/Resources/classic/redglobe_bug.png +0 -0
  249. psychopy/app/Resources/classic/redglobe_bug@2x.png +0 -0
  250. psychopy/app/Resources/classic/redglobe_greensync.png +0 -0
  251. psychopy/app/Resources/classic/redglobe_greensync@2x.png +0 -0
  252. psychopy/app/Resources/classic/redglobe_info.png +0 -0
  253. psychopy/app/Resources/classic/redglobe_info@2x.png +0 -0
  254. psychopy/app/Resources/classic/redglobe_magnifier.png +0 -0
  255. psychopy/app/Resources/classic/redglobe_magnifier@2x.png +0 -0
  256. psychopy/app/Resources/classic/redglobe_run.png +0 -0
  257. psychopy/app/Resources/classic/redglobe_run@2x.png +0 -0
  258. psychopy/app/Resources/classic/redglobe_user.png +0 -0
  259. psychopy/app/Resources/classic/redglobe_user@2x.png +0 -0
  260. psychopy/app/Resources/classic/redo.png +0 -0
  261. psychopy/app/Resources/classic/redo32.png +0 -0
  262. psychopy/app/Resources/classic/redo@2x.png +0 -0
  263. psychopy/app/Resources/classic/removeExp32.png +0 -0
  264. psychopy/app/Resources/classic/rename16.png +0 -0
  265. psychopy/app/Resources/classic/restart.png +0 -0
  266. psychopy/app/Resources/classic/restart@2x.png +0 -0
  267. psychopy/app/Resources/classic/run.png +0 -0
  268. psychopy/app/Resources/classic/run@2x.png +0 -0
  269. psychopy/app/Resources/classic/runner.png +0 -0
  270. psychopy/app/Resources/classic/runner@2x.png +0 -0
  271. psychopy/app/Resources/classic/runnerPilot.png +0 -0
  272. psychopy/app/Resources/classic/runnerPilot@2x.png +0 -0
  273. psychopy/app/Resources/classic/savebtn.png +0 -0
  274. psychopy/app/Resources/classic/savebtn16.png +0 -0
  275. psychopy/app/Resources/classic/savebtn16@2x.png +0 -0
  276. psychopy/app/Resources/classic/savebtn@2x.png +0 -0
  277. psychopy/app/Resources/classic/search.png +0 -0
  278. psychopy/app/Resources/classic/search@2x.png +0 -0
  279. psychopy/app/Resources/classic/showBuilder.png +0 -0
  280. psychopy/app/Resources/classic/showBuilder@2x.png +0 -0
  281. psychopy/app/Resources/classic/showCoder.png +0 -0
  282. psychopy/app/Resources/classic/showCoder@2x.png +0 -0
  283. psychopy/app/Resources/classic/showRunner.png +0 -0
  284. psychopy/app/Resources/classic/showRunner@2x.png +0 -0
  285. psychopy/app/Resources/classic/starred.png +0 -0
  286. psychopy/app/Resources/classic/starred@2x.png +0 -0
  287. psychopy/app/Resources/classic/start.png +0 -0
  288. psychopy/app/Resources/classic/start@2x.png +0 -0
  289. psychopy/app/Resources/classic/stdout.png +0 -0
  290. psychopy/app/Resources/classic/stop.png +0 -0
  291. psychopy/app/Resources/classic/stop32.png +0 -0
  292. psychopy/app/Resources/classic/stop@2x.png +0 -0
  293. psychopy/app/Resources/classic/switchCtrlBot.png +0 -0
  294. psychopy/app/Resources/classic/switchCtrlBot@2x.png +0 -0
  295. psychopy/app/Resources/classic/switchCtrlLeft.png +0 -0
  296. psychopy/app/Resources/classic/switchCtrlLeft@2x.png +0 -0
  297. psychopy/app/Resources/classic/switchCtrlRight.png +0 -0
  298. psychopy/app/Resources/classic/switchCtrlRight@2x.png +0 -0
  299. psychopy/app/Resources/classic/switchCtrlTop.png +0 -0
  300. psychopy/app/Resources/classic/switchCtrlTop@2x.png +0 -0
  301. psychopy/app/Resources/classic/tick.png +0 -0
  302. psychopy/app/Resources/classic/tick@2x.png +0 -0
  303. psychopy/app/Resources/classic/undo.png +0 -0
  304. psychopy/app/Resources/classic/undo32.png +0 -0
  305. psychopy/app/Resources/classic/undo@2x.png +0 -0
  306. psychopy/app/Resources/classic/unstarred.png +0 -0
  307. psychopy/app/Resources/classic/unstarred@2x.png +0 -0
  308. psychopy/app/Resources/classic/user_none.png +0 -0
  309. psychopy/app/Resources/classic/view-refresh16.png +0 -0
  310. psychopy/app/Resources/classic/viewbtn.png +0 -0
  311. psychopy/app/Resources/classic/viewbtn16.png +0 -0
  312. psychopy/app/Resources/classic/viewbtn16@2x.png +0 -0
  313. psychopy/app/Resources/classic/viewbtn@2x.png +0 -0
  314. psychopy/app/Resources/classic/windows16.png +0 -0
  315. psychopy/app/Resources/classic/windows16@2x.png +0 -0
  316. psychopy/app/Resources/click.png +0 -0
  317. psychopy/app/Resources/coder.ico +0 -0
  318. psychopy/app/Resources/creditCard.png +0 -0
  319. psychopy/app/Resources/dark/FlowBottom_CompLeft.png +0 -0
  320. psychopy/app/Resources/dark/FlowBottom_CompRight.png +0 -0
  321. psychopy/app/Resources/dark/FlowTop_CompLeft.png +0 -0
  322. psychopy/app/Resources/dark/FlowTop_CompRight.png +0 -0
  323. psychopy/app/Resources/dark/README.txt +3 -0
  324. psychopy/app/Resources/dark/__init__.py +0 -0
  325. psychopy/app/Resources/dark/add.png +0 -0
  326. psychopy/app/Resources/dark/add@2x.png +0 -0
  327. psychopy/app/Resources/dark/addExp32.png +0 -0
  328. psychopy/app/Resources/dark/addExp32@2x.png +0 -0
  329. psychopy/app/Resources/dark/alerts.png +0 -0
  330. psychopy/app/Resources/dark/alerts@2x.png +0 -0
  331. psychopy/app/Resources/dark/beta.png +0 -0
  332. psychopy/app/Resources/dark/beta@2x.png +0 -0
  333. psychopy/app/Resources/dark/browser.png +0 -0
  334. psychopy/app/Resources/dark/browser@2x.png +0 -0
  335. psychopy/app/Resources/dark/bug16.png +0 -0
  336. psychopy/app/Resources/dark/bug16@2x.png +0 -0
  337. psychopy/app/Resources/dark/circle_mask.png +0 -0
  338. psychopy/app/Resources/dark/circle_mask@2x.png +0 -0
  339. psychopy/app/Resources/dark/clear.png +0 -0
  340. psychopy/app/Resources/dark/clear@2x.png +0 -0
  341. psychopy/app/Resources/dark/coderclass16.png +0 -0
  342. psychopy/app/Resources/dark/coderclass16@2x.png +0 -0
  343. psychopy/app/Resources/dark/coderfunc16.png +0 -0
  344. psychopy/app/Resources/dark/coderfunc16@2x.png +0 -0
  345. psychopy/app/Resources/dark/coderimport16.png +0 -0
  346. psychopy/app/Resources/dark/coderimport16@2x.png +0 -0
  347. psychopy/app/Resources/dark/coderjs.png +0 -0
  348. psychopy/app/Resources/dark/coderjs@2x.png +0 -0
  349. psychopy/app/Resources/dark/coderpython.png +0 -0
  350. psychopy/app/Resources/dark/coderpython@2x.png +0 -0
  351. psychopy/app/Resources/dark/codervar16.png +0 -0
  352. psychopy/app/Resources/dark/codervar16@2x.png +0 -0
  353. psychopy/app/Resources/dark/cogwindow32.png +0 -0
  354. psychopy/app/Resources/dark/cogwindow32@2x.png +0 -0
  355. psychopy/app/Resources/dark/color32.png +0 -0
  356. psychopy/app/Resources/dark/color32@2x.png +0 -0
  357. psychopy/app/Resources/dark/compile_js.png +0 -0
  358. psychopy/app/Resources/dark/compile_js@2x.png +0 -0
  359. psychopy/app/Resources/dark/compile_py.png +0 -0
  360. psychopy/app/Resources/dark/compile_py@2x.png +0 -0
  361. psychopy/app/Resources/dark/copy16.png +0 -0
  362. psychopy/app/Resources/dark/copy16@2x.png +0 -0
  363. psychopy/app/Resources/dark/currentFile16.png +0 -0
  364. psychopy/app/Resources/dark/currentFile16@2x.png +0 -0
  365. psychopy/app/Resources/dark/delete16.png +0 -0
  366. psychopy/app/Resources/dark/delete16@2x.png +0 -0
  367. psychopy/app/Resources/dark/desktop.png +0 -0
  368. psychopy/app/Resources/dark/desktop@2x.png +0 -0
  369. psychopy/app/Resources/dark/dirup16.png +0 -0
  370. psychopy/app/Resources/dark/dirup16@2x.png +0 -0
  371. psychopy/app/Resources/dark/docclose16.png +0 -0
  372. psychopy/app/Resources/dark/docclose16@2x.png +0 -0
  373. psychopy/app/Resources/dark/download.png +0 -0
  374. psychopy/app/Resources/dark/download@2x.png +0 -0
  375. psychopy/app/Resources/dark/edit.png +0 -0
  376. psychopy/app/Resources/dark/edit@2x.png +0 -0
  377. psychopy/app/Resources/dark/editbtn16.png +0 -0
  378. psychopy/app/Resources/dark/editbtn16@2x.png +0 -0
  379. psychopy/app/Resources/dark/email.png +0 -0
  380. psychopy/app/Resources/dark/email@2x.png +0 -0
  381. psychopy/app/Resources/dark/experiment.png +0 -0
  382. psychopy/app/Resources/dark/experiment@2x.png +0 -0
  383. psychopy/app/Resources/dark/expsettings.png +0 -0
  384. psychopy/app/Resources/dark/expsettings@2x.png +0 -0
  385. psychopy/app/Resources/dark/file.png +0 -0
  386. psychopy/app/Resources/dark/file@16w.png +0 -0
  387. psychopy/app/Resources/dark/file@16w@2x.png +0 -0
  388. psychopy/app/Resources/dark/file@2x.png +0 -0
  389. psychopy/app/Resources/dark/filecsv16.png +0 -0
  390. psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
  391. psychopy/app/Resources/dark/fileimage16.png +0 -0
  392. psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
  393. psychopy/app/Resources/dark/filenew.png +0 -0
  394. psychopy/app/Resources/dark/filenew32.png +0 -0
  395. psychopy/app/Resources/dark/filenew32@2x.png +0 -0
  396. psychopy/app/Resources/dark/filenew@2x.png +0 -0
  397. psychopy/app/Resources/dark/fileopen.png +0 -0
  398. psychopy/app/Resources/dark/fileopen32.png +0 -0
  399. psychopy/app/Resources/dark/fileopen32@2x.png +0 -0
  400. psychopy/app/Resources/dark/fileopen@2x.png +0 -0
  401. psychopy/app/Resources/dark/filesave.png +0 -0
  402. psychopy/app/Resources/dark/filesave32.png +0 -0
  403. psychopy/app/Resources/dark/filesave32@2x.png +0 -0
  404. psychopy/app/Resources/dark/filesave@2x.png +0 -0
  405. psychopy/app/Resources/dark/filesaveas.png +0 -0
  406. psychopy/app/Resources/dark/filesaveas32.png +0 -0
  407. psychopy/app/Resources/dark/filesaveas32@2x.png +0 -0
  408. psychopy/app/Resources/dark/filesaveas@2x.png +0 -0
  409. psychopy/app/Resources/dark/fileunknown16.png +0 -0
  410. psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
  411. psychopy/app/Resources/dark/filter.png +0 -0
  412. psychopy/app/Resources/dark/filter@2x.png +0 -0
  413. psychopy/app/Resources/dark/folder-open16.png +0 -0
  414. psychopy/app/Resources/dark/folder-open16@2x.png +0 -0
  415. psychopy/app/Resources/dark/folder16.png +0 -0
  416. psychopy/app/Resources/dark/folder16@2x.png +0 -0
  417. psychopy/app/Resources/dark/foldernew16.png +0 -0
  418. psychopy/app/Resources/dark/foldernew16@2x.png +0 -0
  419. psychopy/app/Resources/dark/fork.png +0 -0
  420. psychopy/app/Resources/dark/fork@2x.png +0 -0
  421. psychopy/app/Resources/dark/github.png +0 -0
  422. psychopy/app/Resources/dark/github@2x.png +0 -0
  423. psychopy/app/Resources/dark/globe.png +0 -0
  424. psychopy/app/Resources/dark/globe@2x.png +0 -0
  425. psychopy/app/Resources/dark/globe_bug.png +0 -0
  426. psychopy/app/Resources/dark/globe_bug@2x.png +0 -0
  427. psychopy/app/Resources/dark/globe_greensync.png +0 -0
  428. psychopy/app/Resources/dark/globe_greensync@2x.png +0 -0
  429. psychopy/app/Resources/dark/globe_info.png +0 -0
  430. psychopy/app/Resources/dark/globe_info@2x.png +0 -0
  431. psychopy/app/Resources/dark/globe_magnifier.png +0 -0
  432. psychopy/app/Resources/dark/globe_magnifier@2x.png +0 -0
  433. psychopy/app/Resources/dark/globe_run.png +0 -0
  434. psychopy/app/Resources/dark/globe_run@2x.png +0 -0
  435. psychopy/app/Resources/dark/globe_user.png +0 -0
  436. psychopy/app/Resources/dark/globe_user@2x.png +0 -0
  437. psychopy/app/Resources/dark/goto.png +0 -0
  438. psychopy/app/Resources/dark/goto@2x.png +0 -0
  439. psychopy/app/Resources/dark/greendot.png +0 -0
  440. psychopy/app/Resources/dark/greendot@2x.png +0 -0
  441. psychopy/app/Resources/dark/greenglobe.png +0 -0
  442. psychopy/app/Resources/dark/greenglobe@2x.png +0 -0
  443. psychopy/app/Resources/dark/greenglobe_bug.png +0 -0
  444. psychopy/app/Resources/dark/greenglobe_bug@2x.png +0 -0
  445. psychopy/app/Resources/dark/greenglobe_greensync.png +0 -0
  446. psychopy/app/Resources/dark/greenglobe_greensync@2x.png +0 -0
  447. psychopy/app/Resources/dark/greenglobe_info.png +0 -0
  448. psychopy/app/Resources/dark/greenglobe_info@2x.png +0 -0
  449. psychopy/app/Resources/dark/greenglobe_magnifier.png +0 -0
  450. psychopy/app/Resources/dark/greenglobe_magnifier@2x.png +0 -0
  451. psychopy/app/Resources/dark/greenglobe_run.png +0 -0
  452. psychopy/app/Resources/dark/greenglobe_run@2x.png +0 -0
  453. psychopy/app/Resources/dark/greenglobe_user.png +0 -0
  454. psychopy/app/Resources/dark/greenglobe_user@2x.png +0 -0
  455. psychopy/app/Resources/dark/greydot.png +0 -0
  456. psychopy/app/Resources/dark/greydot@2x.png +0 -0
  457. psychopy/app/Resources/dark/greytick.png +0 -0
  458. psychopy/app/Resources/dark/greytick@2x.png +0 -0
  459. psychopy/app/Resources/dark/invalid_img.png +0 -0
  460. psychopy/app/Resources/dark/jsPilot.png +0 -0
  461. psychopy/app/Resources/dark/jsPilot@2x.png +0 -0
  462. psychopy/app/Resources/dark/jsRun.png +0 -0
  463. psychopy/app/Resources/dark/jsRun@2x.png +0 -0
  464. psychopy/app/Resources/dark/libroot16.png +0 -0
  465. psychopy/app/Resources/dark/libroot16@2x.png +0 -0
  466. psychopy/app/Resources/dark/monitor16.png +0 -0
  467. psychopy/app/Resources/dark/monitor16@2x.png +0 -0
  468. psychopy/app/Resources/dark/monitors.png +0 -0
  469. psychopy/app/Resources/dark/monitors32.png +0 -0
  470. psychopy/app/Resources/dark/monitors32@2x.png +0 -0
  471. psychopy/app/Resources/dark/monitors@2x.png +0 -0
  472. psychopy/app/Resources/dark/orangedot.png +0 -0
  473. psychopy/app/Resources/dark/orangedot@2x.png +0 -0
  474. psychopy/app/Resources/dark/pavlovia.png +0 -0
  475. psychopy/app/Resources/dark/pavlovia16.png +0 -0
  476. psychopy/app/Resources/dark/pavlovia16@2x.png +0 -0
  477. psychopy/app/Resources/dark/pavlovia@2x.png +0 -0
  478. psychopy/app/Resources/dark/pavsync.png +0 -0
  479. psychopy/app/Resources/dark/pavsync@2x.png +0 -0
  480. psychopy/app/Resources/dark/person_off.png +0 -0
  481. psychopy/app/Resources/dark/person_off@2x.png +0 -0
  482. psychopy/app/Resources/dark/person_on.png +0 -0
  483. psychopy/app/Resources/dark/person_on@2x.png +0 -0
  484. psychopy/app/Resources/dark/plugins32.png +0 -0
  485. psychopy/app/Resources/dark/plugins32@2x.png +0 -0
  486. psychopy/app/Resources/dark/plus.png +0 -0
  487. psychopy/app/Resources/dark/plus@2x.png +0 -0
  488. psychopy/app/Resources/dark/preferences-app.png +0 -0
  489. psychopy/app/Resources/dark/preferences-app48.png +0 -0
  490. psychopy/app/Resources/dark/preferences-app48@2x.png +0 -0
  491. psychopy/app/Resources/dark/preferences-app@2x.png +0 -0
  492. psychopy/app/Resources/dark/preferences-conn.png +0 -0
  493. psychopy/app/Resources/dark/preferences-conn48.png +0 -0
  494. psychopy/app/Resources/dark/preferences-conn48@2x.png +0 -0
  495. psychopy/app/Resources/dark/preferences-conn@2x.png +0 -0
  496. psychopy/app/Resources/dark/preferences-debug.png +0 -0
  497. psychopy/app/Resources/dark/preferences-debug@2x.png +0 -0
  498. psychopy/app/Resources/dark/preferences-general.png +0 -0
  499. psychopy/app/Resources/dark/preferences-general48.png +0 -0
  500. psychopy/app/Resources/dark/preferences-general48@2x.png +0 -0
  501. psychopy/app/Resources/dark/preferences-general@2x.png +0 -0
  502. psychopy/app/Resources/dark/preferences-hardware.png +0 -0
  503. psychopy/app/Resources/dark/preferences-hardware48.png +0 -0
  504. psychopy/app/Resources/dark/preferences-hardware48@2x.png +0 -0
  505. psychopy/app/Resources/dark/preferences-hardware@2x.png +0 -0
  506. psychopy/app/Resources/dark/preferences-keyboard.png +0 -0
  507. psychopy/app/Resources/dark/preferences-keyboard48.png +0 -0
  508. psychopy/app/Resources/dark/preferences-keyboard48@2x.png +0 -0
  509. psychopy/app/Resources/dark/preferences-keyboard@2x.png +0 -0
  510. psychopy/app/Resources/dark/preferences-pilot.png +0 -0
  511. psychopy/app/Resources/dark/preferences-pilot@2x.png +0 -0
  512. psychopy/app/Resources/dark/preferences32.png +0 -0
  513. psychopy/app/Resources/dark/preferences32@2x.png +0 -0
  514. psychopy/app/Resources/dark/pyPilot.png +0 -0
  515. psychopy/app/Resources/dark/pyPilot@2x.png +0 -0
  516. psychopy/app/Resources/dark/pyRun.png +0 -0
  517. psychopy/app/Resources/dark/pyRun@2x.png +0 -0
  518. psychopy/app/Resources/dark/reddot.png +0 -0
  519. psychopy/app/Resources/dark/reddot@2x.png +0 -0
  520. psychopy/app/Resources/dark/redglobe.png +0 -0
  521. psychopy/app/Resources/dark/redglobe@2x.png +0 -0
  522. psychopy/app/Resources/dark/redglobe_bug.png +0 -0
  523. psychopy/app/Resources/dark/redglobe_bug@2x.png +0 -0
  524. psychopy/app/Resources/dark/redglobe_greensync.png +0 -0
  525. psychopy/app/Resources/dark/redglobe_greensync@2x.png +0 -0
  526. psychopy/app/Resources/dark/redglobe_info.png +0 -0
  527. psychopy/app/Resources/dark/redglobe_info@2x.png +0 -0
  528. psychopy/app/Resources/dark/redglobe_magnifier.png +0 -0
  529. psychopy/app/Resources/dark/redglobe_magnifier@2x.png +0 -0
  530. psychopy/app/Resources/dark/redglobe_run.png +0 -0
  531. psychopy/app/Resources/dark/redglobe_run@2x.png +0 -0
  532. psychopy/app/Resources/dark/redglobe_user.png +0 -0
  533. psychopy/app/Resources/dark/redglobe_user@2x.png +0 -0
  534. psychopy/app/Resources/dark/redo.png +0 -0
  535. psychopy/app/Resources/dark/redo32.png +0 -0
  536. psychopy/app/Resources/dark/redo32@2x.png +0 -0
  537. psychopy/app/Resources/dark/redo@2x.png +0 -0
  538. psychopy/app/Resources/dark/removeExp32.png +0 -0
  539. psychopy/app/Resources/dark/removeExp32@2x.png +0 -0
  540. psychopy/app/Resources/dark/rename16.png +0 -0
  541. psychopy/app/Resources/dark/rename16@2x.png +0 -0
  542. psychopy/app/Resources/dark/restart.png +0 -0
  543. psychopy/app/Resources/dark/restart@2x.png +0 -0
  544. psychopy/app/Resources/dark/runner.png +0 -0
  545. psychopy/app/Resources/dark/runner@2x.png +0 -0
  546. psychopy/app/Resources/dark/runnerPilot.png +0 -0
  547. psychopy/app/Resources/dark/runnerPilot@2x.png +0 -0
  548. psychopy/app/Resources/dark/savebtn16.png +0 -0
  549. psychopy/app/Resources/dark/savebtn16@2x.png +0 -0
  550. psychopy/app/Resources/dark/search.png +0 -0
  551. psychopy/app/Resources/dark/search@2x.png +0 -0
  552. psychopy/app/Resources/dark/showBuilder.png +0 -0
  553. psychopy/app/Resources/dark/showBuilder@2x.png +0 -0
  554. psychopy/app/Resources/dark/showCoder.png +0 -0
  555. psychopy/app/Resources/dark/showCoder@2x.png +0 -0
  556. psychopy/app/Resources/dark/showRunner.png +0 -0
  557. psychopy/app/Resources/dark/showRunner@2x.png +0 -0
  558. psychopy/app/Resources/dark/starred.png +0 -0
  559. psychopy/app/Resources/dark/starred@2x.png +0 -0
  560. psychopy/app/Resources/dark/start.png +0 -0
  561. psychopy/app/Resources/dark/start@2x.png +0 -0
  562. psychopy/app/Resources/dark/stdout.png +0 -0
  563. psychopy/app/Resources/dark/stdout@2x.png +0 -0
  564. psychopy/app/Resources/dark/stop.png +0 -0
  565. psychopy/app/Resources/dark/stop32.png +0 -0
  566. psychopy/app/Resources/dark/stop32@2x.png +0 -0
  567. psychopy/app/Resources/dark/stop@2x.png +0 -0
  568. psychopy/app/Resources/dark/switchCtrlBot.png +0 -0
  569. psychopy/app/Resources/dark/switchCtrlBot@2x.png +0 -0
  570. psychopy/app/Resources/dark/switchCtrlLeft.png +0 -0
  571. psychopy/app/Resources/dark/switchCtrlLeft@2x.png +0 -0
  572. psychopy/app/Resources/dark/switchCtrlRight.png +0 -0
  573. psychopy/app/Resources/dark/switchCtrlRight@2x.png +0 -0
  574. psychopy/app/Resources/dark/switchCtrlTop.png +0 -0
  575. psychopy/app/Resources/dark/switchCtrlTop@2x.png +0 -0
  576. psychopy/app/Resources/dark/tick.png +0 -0
  577. psychopy/app/Resources/dark/tick@2x.png +0 -0
  578. psychopy/app/Resources/dark/undo.png +0 -0
  579. psychopy/app/Resources/dark/undo32.png +0 -0
  580. psychopy/app/Resources/dark/undo32@2x.png +0 -0
  581. psychopy/app/Resources/dark/undo@2x.png +0 -0
  582. psychopy/app/Resources/dark/unstarred.png +0 -0
  583. psychopy/app/Resources/dark/unstarred@2x.png +0 -0
  584. psychopy/app/Resources/dark/user_none.png +0 -0
  585. psychopy/app/Resources/dark/view-refresh16.png +0 -0
  586. psychopy/app/Resources/dark/view-refresh16@2x.png +0 -0
  587. psychopy/app/Resources/dark/viewbtn16.png +0 -0
  588. psychopy/app/Resources/dark/viewbtn16@2x.png +0 -0
  589. psychopy/app/Resources/dark/windows16.png +0 -0
  590. psychopy/app/Resources/dark/windows16@2x.png +0 -0
  591. psychopy/app/Resources/default.mp3 +0 -0
  592. psychopy/app/Resources/default.mp4 +0 -0
  593. psychopy/app/Resources/default.png +0 -0
  594. psychopy/app/Resources/fonts/Arvo-Bold.ttf +0 -0
  595. psychopy/app/Resources/fonts/Arvo-BoldItalic.ttf +0 -0
  596. psychopy/app/Resources/fonts/Arvo-Italic.ttf +0 -0
  597. psychopy/app/Resources/fonts/Arvo-Regular.ttf +0 -0
  598. psychopy/app/Resources/fonts/DejaVuSerif.ttf +0 -0
  599. psychopy/app/Resources/fonts/IndieFlower-Regular.ttf +0 -0
  600. psychopy/app/Resources/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
  601. psychopy/app/Resources/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
  602. psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
  603. psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
  604. psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
  605. psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  606. psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
  607. psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
  608. psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
  609. psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
  610. psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
  611. psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
  612. psychopy/app/Resources/instruct1.png +0 -0
  613. psychopy/app/Resources/instruct2.png +0 -0
  614. psychopy/app/Resources/light/FlowBottom_CompLeft.png +0 -0
  615. psychopy/app/Resources/light/FlowBottom_CompRight.png +0 -0
  616. psychopy/app/Resources/light/FlowTop_CompLeft.png +0 -0
  617. psychopy/app/Resources/light/FlowTop_CompRight.png +0 -0
  618. psychopy/app/Resources/light/README.txt +3 -0
  619. psychopy/app/Resources/light/__init__.py +0 -0
  620. psychopy/app/Resources/light/add.png +0 -0
  621. psychopy/app/Resources/light/add@2x.png +0 -0
  622. psychopy/app/Resources/light/addExp32.png +0 -0
  623. psychopy/app/Resources/light/addExp32@2x.png +0 -0
  624. psychopy/app/Resources/light/alerts.png +0 -0
  625. psychopy/app/Resources/light/alerts@2x.png +0 -0
  626. psychopy/app/Resources/light/beta.png +0 -0
  627. psychopy/app/Resources/light/beta@2x.png +0 -0
  628. psychopy/app/Resources/light/browser.png +0 -0
  629. psychopy/app/Resources/light/browser@2x.png +0 -0
  630. psychopy/app/Resources/light/bug16.png +0 -0
  631. psychopy/app/Resources/light/bug16@2x.png +0 -0
  632. psychopy/app/Resources/light/circle_mask.png +0 -0
  633. psychopy/app/Resources/light/circle_mask@2x.png +0 -0
  634. psychopy/app/Resources/light/clear.png +0 -0
  635. psychopy/app/Resources/light/clear@2x.png +0 -0
  636. psychopy/app/Resources/light/coderclass16.png +0 -0
  637. psychopy/app/Resources/light/coderclass16@2x.png +0 -0
  638. psychopy/app/Resources/light/coderfunc16.png +0 -0
  639. psychopy/app/Resources/light/coderfunc16@2x.png +0 -0
  640. psychopy/app/Resources/light/coderimport16.png +0 -0
  641. psychopy/app/Resources/light/coderimport16@2x.png +0 -0
  642. psychopy/app/Resources/light/coderjs.png +0 -0
  643. psychopy/app/Resources/light/coderjs@2x.png +0 -0
  644. psychopy/app/Resources/light/coderpython.png +0 -0
  645. psychopy/app/Resources/light/coderpython@2x.png +0 -0
  646. psychopy/app/Resources/light/codervar16.png +0 -0
  647. psychopy/app/Resources/light/codervar16@2x.png +0 -0
  648. psychopy/app/Resources/light/cogwindow32.png +0 -0
  649. psychopy/app/Resources/light/cogwindow32@2x.png +0 -0
  650. psychopy/app/Resources/light/color16.png +0 -0
  651. psychopy/app/Resources/light/color16@2x.png +0 -0
  652. psychopy/app/Resources/light/color32.png +0 -0
  653. psychopy/app/Resources/light/color32@2x.png +0 -0
  654. psychopy/app/Resources/light/compile_js.png +0 -0
  655. psychopy/app/Resources/light/compile_js@2x.png +0 -0
  656. psychopy/app/Resources/light/compile_py.png +0 -0
  657. psychopy/app/Resources/light/compile_py@2x.png +0 -0
  658. psychopy/app/Resources/light/copy16.png +0 -0
  659. psychopy/app/Resources/light/copy16@2x.png +0 -0
  660. psychopy/app/Resources/light/currentFile16.png +0 -0
  661. psychopy/app/Resources/light/currentFile16@2x.png +0 -0
  662. psychopy/app/Resources/light/delete16.png +0 -0
  663. psychopy/app/Resources/light/delete16@2x.png +0 -0
  664. psychopy/app/Resources/light/delete8.png +0 -0
  665. psychopy/app/Resources/light/desktop.png +0 -0
  666. psychopy/app/Resources/light/desktop@2x.png +0 -0
  667. psychopy/app/Resources/light/dirup16.png +0 -0
  668. psychopy/app/Resources/light/dirup16@2x.png +0 -0
  669. psychopy/app/Resources/light/docclose16.png +0 -0
  670. psychopy/app/Resources/light/docclose16@2x.png +0 -0
  671. psychopy/app/Resources/light/download.png +0 -0
  672. psychopy/app/Resources/light/download@2x.png +0 -0
  673. psychopy/app/Resources/light/edit.png +0 -0
  674. psychopy/app/Resources/light/edit@2x.png +0 -0
  675. psychopy/app/Resources/light/editbtn16.png +0 -0
  676. psychopy/app/Resources/light/editbtn16@2x.png +0 -0
  677. psychopy/app/Resources/light/email.png +0 -0
  678. psychopy/app/Resources/light/email@2x.png +0 -0
  679. psychopy/app/Resources/light/experiment.png +0 -0
  680. psychopy/app/Resources/light/experiment@2x.png +0 -0
  681. psychopy/app/Resources/light/expsettings.png +0 -0
  682. psychopy/app/Resources/light/expsettings@2x.png +0 -0
  683. psychopy/app/Resources/light/file.png +0 -0
  684. psychopy/app/Resources/light/file@2x.png +0 -0
  685. psychopy/app/Resources/light/filecsv16.png +0 -0
  686. psychopy/app/Resources/light/filecsv16@2x.png +0 -0
  687. psychopy/app/Resources/light/fileimage16.png +0 -0
  688. psychopy/app/Resources/light/fileimage16@2x.png +0 -0
  689. psychopy/app/Resources/light/filenew.png +0 -0
  690. psychopy/app/Resources/light/filenew32.png +0 -0
  691. psychopy/app/Resources/light/filenew32@2x.png +0 -0
  692. psychopy/app/Resources/light/filenew@2x.png +0 -0
  693. psychopy/app/Resources/light/fileopen.png +0 -0
  694. psychopy/app/Resources/light/fileopen32.png +0 -0
  695. psychopy/app/Resources/light/fileopen32@2x.png +0 -0
  696. psychopy/app/Resources/light/fileopen@2x.png +0 -0
  697. psychopy/app/Resources/light/filesave.png +0 -0
  698. psychopy/app/Resources/light/filesave32.png +0 -0
  699. psychopy/app/Resources/light/filesave32@2x.png +0 -0
  700. psychopy/app/Resources/light/filesave@2x.png +0 -0
  701. psychopy/app/Resources/light/filesaveas.png +0 -0
  702. psychopy/app/Resources/light/filesaveas32.png +0 -0
  703. psychopy/app/Resources/light/filesaveas32@2x.png +0 -0
  704. psychopy/app/Resources/light/filesaveas@2x.png +0 -0
  705. psychopy/app/Resources/light/fileunknown16.png +0 -0
  706. psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
  707. psychopy/app/Resources/light/filter.png +0 -0
  708. psychopy/app/Resources/light/filter@2x.png +0 -0
  709. psychopy/app/Resources/light/folder-open16.png +0 -0
  710. psychopy/app/Resources/light/folder-open16@2x.png +0 -0
  711. psychopy/app/Resources/light/folder16.png +0 -0
  712. psychopy/app/Resources/light/folder16@2x.png +0 -0
  713. psychopy/app/Resources/light/foldernew16.png +0 -0
  714. psychopy/app/Resources/light/foldernew16@2x.png +0 -0
  715. psychopy/app/Resources/light/fork.png +0 -0
  716. psychopy/app/Resources/light/fork@2x.png +0 -0
  717. psychopy/app/Resources/light/github.png +0 -0
  718. psychopy/app/Resources/light/github@2x.png +0 -0
  719. psychopy/app/Resources/light/globe.png +0 -0
  720. psychopy/app/Resources/light/globe@2x.png +0 -0
  721. psychopy/app/Resources/light/globe_bug.png +0 -0
  722. psychopy/app/Resources/light/globe_bug@2x.png +0 -0
  723. psychopy/app/Resources/light/globe_greensync.png +0 -0
  724. psychopy/app/Resources/light/globe_greensync@2x.png +0 -0
  725. psychopy/app/Resources/light/globe_info.png +0 -0
  726. psychopy/app/Resources/light/globe_info@2x.png +0 -0
  727. psychopy/app/Resources/light/globe_magnifier.png +0 -0
  728. psychopy/app/Resources/light/globe_magnifier@2x.png +0 -0
  729. psychopy/app/Resources/light/globe_run.png +0 -0
  730. psychopy/app/Resources/light/globe_run@2x.png +0 -0
  731. psychopy/app/Resources/light/globe_user.png +0 -0
  732. psychopy/app/Resources/light/globe_user@2x.png +0 -0
  733. psychopy/app/Resources/light/goto16.png +0 -0
  734. psychopy/app/Resources/light/goto16@2x.png +0 -0
  735. psychopy/app/Resources/light/greendot.png +0 -0
  736. psychopy/app/Resources/light/greendot@2x.png +0 -0
  737. psychopy/app/Resources/light/greenglobe.png +0 -0
  738. psychopy/app/Resources/light/greenglobe@2x.png +0 -0
  739. psychopy/app/Resources/light/greenglobe_bug.png +0 -0
  740. psychopy/app/Resources/light/greenglobe_bug@2x.png +0 -0
  741. psychopy/app/Resources/light/greenglobe_greensync.png +0 -0
  742. psychopy/app/Resources/light/greenglobe_greensync@2x.png +0 -0
  743. psychopy/app/Resources/light/greenglobe_info.png +0 -0
  744. psychopy/app/Resources/light/greenglobe_info@2x.png +0 -0
  745. psychopy/app/Resources/light/greenglobe_magnifier.png +0 -0
  746. psychopy/app/Resources/light/greenglobe_magnifier@2x.png +0 -0
  747. psychopy/app/Resources/light/greenglobe_run.png +0 -0
  748. psychopy/app/Resources/light/greenglobe_run@2x.png +0 -0
  749. psychopy/app/Resources/light/greenglobe_user.png +0 -0
  750. psychopy/app/Resources/light/greenglobe_user@2x.png +0 -0
  751. psychopy/app/Resources/light/greydot.png +0 -0
  752. psychopy/app/Resources/light/greydot@2x.png +0 -0
  753. psychopy/app/Resources/light/greytick.png +0 -0
  754. psychopy/app/Resources/light/greytick@2x.png +0 -0
  755. psychopy/app/Resources/light/invalid_img.png +0 -0
  756. psychopy/app/Resources/light/jsPilot.png +0 -0
  757. psychopy/app/Resources/light/jsPilot@2x.png +0 -0
  758. psychopy/app/Resources/light/jsRun.png +0 -0
  759. psychopy/app/Resources/light/jsRun@2x.png +0 -0
  760. psychopy/app/Resources/light/libroot16.png +0 -0
  761. psychopy/app/Resources/light/libroot16@2x.png +0 -0
  762. psychopy/app/Resources/light/monitor16.png +0 -0
  763. psychopy/app/Resources/light/monitor16@2x.png +0 -0
  764. psychopy/app/Resources/light/monitors.png +0 -0
  765. psychopy/app/Resources/light/monitors32.png +0 -0
  766. psychopy/app/Resources/light/monitors32@2x.png +0 -0
  767. psychopy/app/Resources/light/monitors@2x.png +0 -0
  768. psychopy/app/Resources/light/orangedot.png +0 -0
  769. psychopy/app/Resources/light/orangedot@2x.png +0 -0
  770. psychopy/app/Resources/light/pavlovia.png +0 -0
  771. psychopy/app/Resources/light/pavlovia16.png +0 -0
  772. psychopy/app/Resources/light/pavlovia16@2x.png +0 -0
  773. psychopy/app/Resources/light/pavlovia@2x.png +0 -0
  774. psychopy/app/Resources/light/pavsync.png +0 -0
  775. psychopy/app/Resources/light/pavsync@2x.png +0 -0
  776. psychopy/app/Resources/light/person_off.png +0 -0
  777. psychopy/app/Resources/light/person_off@2x.png +0 -0
  778. psychopy/app/Resources/light/person_on.png +0 -0
  779. psychopy/app/Resources/light/person_on@2x.png +0 -0
  780. psychopy/app/Resources/light/plugins32.png +0 -0
  781. psychopy/app/Resources/light/plugins32@2x.png +0 -0
  782. psychopy/app/Resources/light/plus.png +0 -0
  783. psychopy/app/Resources/light/plus@2x.png +0 -0
  784. psychopy/app/Resources/light/preferences-app.png +0 -0
  785. psychopy/app/Resources/light/preferences-app48.png +0 -0
  786. psychopy/app/Resources/light/preferences-app48@2x.png +0 -0
  787. psychopy/app/Resources/light/preferences-app@2x.png +0 -0
  788. psychopy/app/Resources/light/preferences-conn.png +0 -0
  789. psychopy/app/Resources/light/preferences-conn48.png +0 -0
  790. psychopy/app/Resources/light/preferences-conn48@2x.png +0 -0
  791. psychopy/app/Resources/light/preferences-conn@2x.png +0 -0
  792. psychopy/app/Resources/light/preferences-general.png +0 -0
  793. psychopy/app/Resources/light/preferences-general48.png +0 -0
  794. psychopy/app/Resources/light/preferences-general48@2x.png +0 -0
  795. psychopy/app/Resources/light/preferences-general@2x.png +0 -0
  796. psychopy/app/Resources/light/preferences-hardware.png +0 -0
  797. psychopy/app/Resources/light/preferences-hardware48.png +0 -0
  798. psychopy/app/Resources/light/preferences-hardware48@2x.png +0 -0
  799. psychopy/app/Resources/light/preferences-hardware@2x.png +0 -0
  800. psychopy/app/Resources/light/preferences-keyboard.png +0 -0
  801. psychopy/app/Resources/light/preferences-keyboard48.png +0 -0
  802. psychopy/app/Resources/light/preferences-keyboard48@2x.png +0 -0
  803. psychopy/app/Resources/light/preferences-keyboard@2x.png +0 -0
  804. psychopy/app/Resources/light/preferences-pilot.png +0 -0
  805. psychopy/app/Resources/light/preferences-pilot@2x.png +0 -0
  806. psychopy/app/Resources/light/preferences32.png +0 -0
  807. psychopy/app/Resources/light/preferences32@2x.png +0 -0
  808. psychopy/app/Resources/light/pyPilot.png +0 -0
  809. psychopy/app/Resources/light/pyPilot@2x.png +0 -0
  810. psychopy/app/Resources/light/pyRun.png +0 -0
  811. psychopy/app/Resources/light/pyRun@2x.png +0 -0
  812. psychopy/app/Resources/light/reddot.png +0 -0
  813. psychopy/app/Resources/light/reddot@2x.png +0 -0
  814. psychopy/app/Resources/light/redglobe.png +0 -0
  815. psychopy/app/Resources/light/redglobe@2x.png +0 -0
  816. psychopy/app/Resources/light/redglobe_bug.png +0 -0
  817. psychopy/app/Resources/light/redglobe_bug@2x.png +0 -0
  818. psychopy/app/Resources/light/redglobe_greensync.png +0 -0
  819. psychopy/app/Resources/light/redglobe_greensync@2x.png +0 -0
  820. psychopy/app/Resources/light/redglobe_info.png +0 -0
  821. psychopy/app/Resources/light/redglobe_info@2x.png +0 -0
  822. psychopy/app/Resources/light/redglobe_magnifier.png +0 -0
  823. psychopy/app/Resources/light/redglobe_magnifier@2x.png +0 -0
  824. psychopy/app/Resources/light/redglobe_run.png +0 -0
  825. psychopy/app/Resources/light/redglobe_run@2x.png +0 -0
  826. psychopy/app/Resources/light/redglobe_user.png +0 -0
  827. psychopy/app/Resources/light/redglobe_user@2x.png +0 -0
  828. psychopy/app/Resources/light/redo.png +0 -0
  829. psychopy/app/Resources/light/redo32.png +0 -0
  830. psychopy/app/Resources/light/redo32@2x.png +0 -0
  831. psychopy/app/Resources/light/redo@2x.png +0 -0
  832. psychopy/app/Resources/light/removeExp32.png +0 -0
  833. psychopy/app/Resources/light/removeExp32@2x.png +0 -0
  834. psychopy/app/Resources/light/rename16.png +0 -0
  835. psychopy/app/Resources/light/rename16@2x.png +0 -0
  836. psychopy/app/Resources/light/restart.png +0 -0
  837. psychopy/app/Resources/light/restart@2x.png +0 -0
  838. psychopy/app/Resources/light/runner.png +0 -0
  839. psychopy/app/Resources/light/runner@2x.png +0 -0
  840. psychopy/app/Resources/light/runnerPilot.png +0 -0
  841. psychopy/app/Resources/light/runnerPilot@2x.png +0 -0
  842. psychopy/app/Resources/light/savebtn16.png +0 -0
  843. psychopy/app/Resources/light/savebtn16@2x.png +0 -0
  844. psychopy/app/Resources/light/search.png +0 -0
  845. psychopy/app/Resources/light/search@2x.png +0 -0
  846. psychopy/app/Resources/light/showBuilder.png +0 -0
  847. psychopy/app/Resources/light/showBuilder@2x.png +0 -0
  848. psychopy/app/Resources/light/showCoder.png +0 -0
  849. psychopy/app/Resources/light/showCoder@2x.png +0 -0
  850. psychopy/app/Resources/light/showRunner.png +0 -0
  851. psychopy/app/Resources/light/showRunner@2x.png +0 -0
  852. psychopy/app/Resources/light/starred.png +0 -0
  853. psychopy/app/Resources/light/starred@2x.png +0 -0
  854. psychopy/app/Resources/light/start.png +0 -0
  855. psychopy/app/Resources/light/start@2x.png +0 -0
  856. psychopy/app/Resources/light/stdout.png +0 -0
  857. psychopy/app/Resources/light/stdout@2x.png +0 -0
  858. psychopy/app/Resources/light/stop.png +0 -0
  859. psychopy/app/Resources/light/stop32.png +0 -0
  860. psychopy/app/Resources/light/stop32@2x.png +0 -0
  861. psychopy/app/Resources/light/stop@2x.png +0 -0
  862. psychopy/app/Resources/light/switchCtrlBot.png +0 -0
  863. psychopy/app/Resources/light/switchCtrlBot@2x.png +0 -0
  864. psychopy/app/Resources/light/switchCtrlLeft.png +0 -0
  865. psychopy/app/Resources/light/switchCtrlLeft@2x.png +0 -0
  866. psychopy/app/Resources/light/switchCtrlRight.png +0 -0
  867. psychopy/app/Resources/light/switchCtrlRight@2x.png +0 -0
  868. psychopy/app/Resources/light/switchCtrlTop.png +0 -0
  869. psychopy/app/Resources/light/switchCtrlTop@2x.png +0 -0
  870. psychopy/app/Resources/light/tick.png +0 -0
  871. psychopy/app/Resources/light/tick@2x.png +0 -0
  872. psychopy/app/Resources/light/undo.png +0 -0
  873. psychopy/app/Resources/light/undo32.png +0 -0
  874. psychopy/app/Resources/light/undo32@2x.png +0 -0
  875. psychopy/app/Resources/light/undo@2x.png +0 -0
  876. psychopy/app/Resources/light/unstarred.png +0 -0
  877. psychopy/app/Resources/light/unstarred@2x.png +0 -0
  878. psychopy/app/Resources/light/user_none.png +0 -0
  879. psychopy/app/Resources/light/view-refresh16.png +0 -0
  880. psychopy/app/Resources/light/view-refresh16@2x.png +0 -0
  881. psychopy/app/Resources/light/viewbtn16.png +0 -0
  882. psychopy/app/Resources/light/viewbtn16@2x.png +0 -0
  883. psychopy/app/Resources/light/windows16.png +0 -0
  884. psychopy/app/Resources/light/windows16@2x.png +0 -0
  885. psychopy/app/Resources/moveComponentIcons.py +50 -0
  886. psychopy/app/Resources/next.png +0 -0
  887. psychopy/app/Resources/psychopy.desktop +13 -0
  888. psychopy/app/Resources/psychopy.icns +0 -0
  889. psychopy/app/Resources/psychopy.ico +0 -0
  890. psychopy/app/Resources/psychopy.png +0 -0
  891. psychopy/app/Resources/psychopy.xml +9 -0
  892. psychopy/app/Resources/psychopy@2x.png +0 -0
  893. psychopy/app/Resources/psychopySplash.png +0 -0
  894. psychopy/app/Resources/psychopySplash@2x.png +0 -0
  895. psychopy/app/Resources/routine_templates/Basic.psyexp +345 -0
  896. psychopy/app/Resources/routine_templates/Misc.psyexp +229 -0
  897. psychopy/app/Resources/routine_templates/Online.psyexp +202 -0
  898. psychopy/app/Resources/routine_templates/Trials.psyexp +736 -0
  899. psychopy/app/Resources/routine_templates/readme.md +14 -0
  900. psychopy/app/Resources/runner.ico +0 -0
  901. psychopy/app/Resources/tips.txt +45 -0
  902. psychopy/app/Resources/tips_ar_001.txt +45 -0
  903. psychopy/app/Resources/tips_fr_FR.txt +45 -0
  904. psychopy/app/Resources/tips_ja_JP.txt +42 -0
  905. psychopy/app/Resources/tips_zh_CN.txt +45 -0
  906. psychopy/app/Resources/window.ico +0 -0
  907. psychopy/app/__init__.py +224 -0
  908. psychopy/app/_psychopyApp.py +1224 -0
  909. psychopy/app/appData.spec +58 -0
  910. psychopy/app/builder/__init__.py +5 -0
  911. psychopy/app/builder/builder.py +4658 -0
  912. psychopy/app/builder/dialogs/__init__.py +2014 -0
  913. psychopy/app/builder/dialogs/dlgsCode.py +610 -0
  914. psychopy/app/builder/dialogs/dlgsConditions.py +670 -0
  915. psychopy/app/builder/dialogs/findDlg.py +189 -0
  916. psychopy/app/builder/dialogs/paramCtrls.py +1213 -0
  917. psychopy/app/builder/localizedStrings.py +225 -0
  918. psychopy/app/builder/validators.py +581 -0
  919. psychopy/app/coder/__init__.py +8 -0
  920. psychopy/app/coder/codeEditorBase.py +460 -0
  921. psychopy/app/coder/coder.py +3086 -0
  922. psychopy/app/coder/fileBrowser.py +668 -0
  923. psychopy/app/coder/folding.py +128 -0
  924. psychopy/app/coder/psychoParser.py +139 -0
  925. psychopy/app/coder/repl.py +493 -0
  926. psychopy/app/coder/sourceTree.py +302 -0
  927. psychopy/app/colorpicker/__init__.py +594 -0
  928. psychopy/app/colorpicker/ui.py +336 -0
  929. psychopy/app/connections/__init__.py +10 -0
  930. psychopy/app/connections/news.py +104 -0
  931. psychopy/app/connections/sendusage.py +61 -0
  932. psychopy/app/connections/updates.py +642 -0
  933. psychopy/app/console.py +164 -0
  934. psychopy/app/dialogs.py +632 -0
  935. psychopy/app/errorDlg.py +238 -0
  936. psychopy/app/frametracker.py +8 -0
  937. psychopy/app/idle.py +143 -0
  938. psychopy/app/jobs.py +648 -0
  939. psychopy/app/linuxconfig/__init__.py +144 -0
  940. psychopy/app/linuxconfig/ui.py +88 -0
  941. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  942. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +9554 -0
  943. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  944. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +24 -0
  945. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  946. psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +24 -0
  947. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  948. psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +9712 -0
  949. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  950. psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +25 -0
  951. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  952. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +25 -0
  953. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  954. psychopy/app/locale/en_US/LC_MESSAGE/messages.po +18 -0
  955. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  956. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +9100 -0
  957. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  958. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +9094 -0
  959. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  960. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +9100 -0
  961. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  962. psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +9569 -0
  963. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  964. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +5806 -0
  965. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  966. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +24 -0
  967. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  968. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +9577 -0
  969. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  970. psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +9549 -0
  971. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  972. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +9559 -0
  973. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  974. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +25 -0
  975. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  976. psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +9560 -0
  977. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  978. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +11687 -0
  979. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  980. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +24 -0
  981. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  982. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +8757 -0
  983. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  984. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +25 -0
  985. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  986. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +25 -0
  987. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  988. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +25 -0
  989. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  990. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +24 -0
  991. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  992. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +25 -0
  993. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  994. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +24 -0
  995. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  996. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +8747 -0
  997. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  998. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +9545 -0
  999. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  1000. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +8268 -0
  1001. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  1002. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +8022 -0
  1003. psychopy/app/pavlovia_ui/__init__.py +22 -0
  1004. psychopy/app/pavlovia_ui/_base.py +237 -0
  1005. psychopy/app/pavlovia_ui/functions.py +176 -0
  1006. psychopy/app/pavlovia_ui/menu.py +140 -0
  1007. psychopy/app/pavlovia_ui/project.py +943 -0
  1008. psychopy/app/pavlovia_ui/search.py +445 -0
  1009. psychopy/app/pavlovia_ui/sync.py +137 -0
  1010. psychopy/app/pavlovia_ui/user.py +264 -0
  1011. psychopy/app/plugin_manager/__init__.py +5 -0
  1012. psychopy/app/plugin_manager/dialog.py +400 -0
  1013. psychopy/app/plugin_manager/output.py +132 -0
  1014. psychopy/app/plugin_manager/packages.py +502 -0
  1015. psychopy/app/plugin_manager/plugins.py +1315 -0
  1016. psychopy/app/plugin_manager/utils.py +115 -0
  1017. psychopy/app/preferencesDlg.py +790 -0
  1018. psychopy/app/psychopyApp.py +103 -0
  1019. psychopy/app/ribbon.py +907 -0
  1020. psychopy/app/runner/__init__.py +1 -0
  1021. psychopy/app/runner/runner.py +1262 -0
  1022. psychopy/app/runner/scriptProcess.py +353 -0
  1023. psychopy/app/stdout/__init__.py +1 -0
  1024. psychopy/app/stdout/stdOutRich.py +380 -0
  1025. psychopy/app/sysInfoDlg.py +242 -0
  1026. psychopy/app/themes/__init__.py +78 -0
  1027. psychopy/app/themes/colors.py +201 -0
  1028. psychopy/app/themes/css/contrast_black.css +112 -0
  1029. psychopy/app/themes/css/contrast_white.css +115 -0
  1030. psychopy/app/themes/css/dark.css +112 -0
  1031. psychopy/app/themes/css/light.css +115 -0
  1032. psychopy/app/themes/fonts.py +629 -0
  1033. psychopy/app/themes/handlers.py +321 -0
  1034. psychopy/app/themes/icons.py +250 -0
  1035. psychopy/app/themes/spec/Classic.json +154 -0
  1036. psychopy/app/themes/spec/ClassicDark.json +154 -0
  1037. psychopy/app/themes/spec/GitHub.json +154 -0
  1038. psychopy/app/themes/spec/HiVisDark.json +153 -0
  1039. psychopy/app/themes/spec/HiVisLight.json +154 -0
  1040. psychopy/app/themes/spec/MinimalDark.json +154 -0
  1041. psychopy/app/themes/spec/MinimalLight.json +153 -0
  1042. psychopy/app/themes/spec/PsychopyDark.json +231 -0
  1043. psychopy/app/themes/spec/PsychopyLight.json +236 -0
  1044. psychopy/app/themes/ui.py +74 -0
  1045. psychopy/app/ui/__init__.py +184 -0
  1046. psychopy/app/urls.py +31 -0
  1047. psychopy/app/utils.py +1680 -0
  1048. psychopy/app/viewer/__init__.py +0 -0
  1049. psychopy/clock.py +612 -0
  1050. psychopy/colors.py +1050 -0
  1051. psychopy/compatibility.py +95 -0
  1052. psychopy/constants.py +87 -0
  1053. psychopy/contrib/__init__.py +0 -0
  1054. psychopy/contrib/configobj/LICENSE +39 -0
  1055. psychopy/contrib/configobj/__init__.py +2453 -0
  1056. psychopy/contrib/configobj/_version.py +2 -0
  1057. psychopy/contrib/configobj/validate.py +1458 -0
  1058. psychopy/contrib/lazy_import.py +402 -0
  1059. psychopy/contrib/mseq.py +273 -0
  1060. psychopy/contrib/mseqSearch.py +183 -0
  1061. psychopy/contrib/psi.py +100 -0
  1062. psychopy/contrib/quest.py +484 -0
  1063. psychopy/contrib/tesselate.py +188 -0
  1064. psychopy/core.py +167 -0
  1065. psychopy/data/__init__.py +44 -0
  1066. psychopy/data/base.py +566 -0
  1067. psychopy/data/counterbalance.py +210 -0
  1068. psychopy/data/experiment.py +708 -0
  1069. psychopy/data/fit.py +248 -0
  1070. psychopy/data/shelf.py +237 -0
  1071. psychopy/data/staircase.py +2247 -0
  1072. psychopy/data/trial.py +1978 -0
  1073. psychopy/data/utils.py +783 -0
  1074. psychopy/demos/__init__.py +0 -0
  1075. psychopy/demos/builder/Design Templates/branchedExperiment/README.md +5 -0
  1076. psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +239 -0
  1077. psychopy/demos/builder/Design Templates/branchedExperiment/trialTypes.xlsx +0 -0
  1078. psychopy/demos/builder/Design Templates/psychophysicsStaircase/README.md +20 -0
  1079. psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +264 -0
  1080. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/README.md +14 -0
  1081. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +201 -0
  1082. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/stairDefinitions.xlsx +0 -0
  1083. psychopy/demos/builder/Design Templates/randomisedBlocks/README.md +18 -0
  1084. psychopy/demos/builder/Design Templates/randomisedBlocks/chooseBlock.xlsx +0 -0
  1085. psychopy/demos/builder/Design Templates/randomisedBlocks/facesBlock.xlsx +0 -0
  1086. psychopy/demos/builder/Design Templates/randomisedBlocks/housesBlock.xlsx +0 -0
  1087. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +131 -0
  1088. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face01.jpg +0 -0
  1089. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face02.jpg +0 -0
  1090. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face03.jpg +0 -0
  1091. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house01.jpg +0 -0
  1092. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house02.jpg +0 -0
  1093. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house03.jpg +0 -0
  1094. psychopy/demos/builder/Experiments/BART/README.md +30 -0
  1095. psychopy/demos/builder/Experiments/BART/assets/background.png +0 -0
  1096. psychopy/demos/builder/Experiments/BART/assets/bang.mp3 +0 -0
  1097. psychopy/demos/builder/Experiments/BART/assets/bang.wav +0 -0
  1098. psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
  1099. psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
  1100. psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
  1101. psychopy/demos/builder/Experiments/BART/bart.psyexp +931 -0
  1102. psychopy/demos/builder/Experiments/BART/spreadsheets/conditions.xlsx +0 -0
  1103. psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +193 -0
  1104. psychopy/demos/builder/Experiments/BigFiveInventory/README.md +23 -0
  1105. psychopy/demos/builder/Experiments/BigFiveInventory/TIPI.xlsx +0 -0
  1106. psychopy/demos/builder/Experiments/BigFiveInventory/bigFiveItems.xlsx +0 -0
  1107. psychopy/demos/builder/Experiments/BigFiveInventory/demographics.xlsx +0 -0
  1108. psychopy/demos/builder/Experiments/BigFiveInventory/mini_IPIP.xlsx +0 -0
  1109. psychopy/demos/builder/Experiments/dragAndDrop/README.md +40 -0
  1110. psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
  1111. psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +1221 -0
  1112. psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +61 -0
  1113. psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +91 -0
  1114. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
  1115. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
  1116. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
  1117. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
  1118. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
  1119. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
  1120. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
  1121. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
  1122. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
  1123. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
  1124. psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
  1125. psychopy/demos/builder/Experiments/goNoGo/conditions.xlsx +0 -0
  1126. psychopy/demos/builder/Experiments/goNoGo/gng.psyexp +449 -0
  1127. psychopy/demos/builder/Experiments/goNoGo/go.png +0 -0
  1128. psychopy/demos/builder/Experiments/goNoGo/nogo.png +0 -0
  1129. psychopy/demos/builder/Experiments/goNoGo/readme.md +14 -0
  1130. psychopy/demos/builder/Experiments/mentalRotation/F.png +0 -0
  1131. psychopy/demos/builder/Experiments/mentalRotation/FR.png +0 -0
  1132. psychopy/demos/builder/Experiments/mentalRotation/MentalRot.csv +33 -0
  1133. psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +605 -0
  1134. psychopy/demos/builder/Experiments/mentalRotation/README.md +23 -0
  1135. psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +478 -0
  1136. psychopy/demos/builder/Experiments/navon/README.md +26 -0
  1137. psychopy/demos/builder/Experiments/navon/bigHsmallH.png +0 -0
  1138. psychopy/demos/builder/Experiments/navon/bigHsmallS.png +0 -0
  1139. psychopy/demos/builder/Experiments/navon/bigSsmallH.png +0 -0
  1140. psychopy/demos/builder/Experiments/navon/bigSsmallS.png +0 -0
  1141. psychopy/demos/builder/Experiments/navon/mask.png +0 -0
  1142. psychopy/demos/builder/Experiments/navon/stimuli.pptx +0 -0
  1143. psychopy/demos/builder/Experiments/navon/trialTypes.xlsx +0 -0
  1144. psychopy/demos/builder/Experiments/sternberg/README.md +14 -0
  1145. psychopy/demos/builder/Experiments/sternberg/mainTrials.xlsx +0 -0
  1146. psychopy/demos/builder/Experiments/sternberg/pracTrials.xlsx +0 -0
  1147. psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +611 -0
  1148. psychopy/demos/builder/Experiments/stroop/README.md +15 -0
  1149. psychopy/demos/builder/Experiments/stroop/stroop.psyexp +225 -0
  1150. psychopy/demos/builder/Experiments/stroop/trialTypes.csv +7 -0
  1151. psychopy/demos/builder/Experiments/stroopExtended/README.md +14 -0
  1152. psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +243 -0
  1153. psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +243 -0
  1154. psychopy/demos/builder/Experiments/stroopExtended/trialTypes.xlsx +0 -0
  1155. psychopy/demos/builder/Experiments/stroopExtended/trialTypesReverse.xlsx +0 -0
  1156. psychopy/demos/builder/Experiments/stroopVoice/README.md +27 -0
  1157. psychopy/demos/builder/Experiments/stroopVoice/conditions.xlsx +0 -0
  1158. psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +366 -0
  1159. psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +298 -0
  1160. psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +341 -0
  1161. psychopy/demos/builder/Feature Demos/gratings/readme.md +8 -0
  1162. psychopy/demos/builder/Feature Demos/noise/face.jpg +0 -0
  1163. psychopy/demos/builder/Feature Demos/noise/noise.psyexp +424 -0
  1164. psychopy/demos/builder/Feature Demos/noise/readme.md +3 -0
  1165. psychopy/demos/builder/Feature Demos/panorama/panImg.jpg +0 -0
  1166. psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +142 -0
  1167. psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +423 -0
  1168. psychopy/demos/builder/Feature Demos/progress/readme.md +1 -0
  1169. psychopy/demos/builder/Feature Demos/sliders/README.md +8 -0
  1170. psychopy/demos/builder/Feature Demos/sliders/fruitConditions.xlsx +0 -0
  1171. psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +938 -0
  1172. psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +621 -0
  1173. psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +404 -0
  1174. psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +641 -0
  1175. psychopy/demos/builder/Hardware/EGI_netstation/README.md +17 -0
  1176. psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +254 -0
  1177. psychopy/demos/builder/Hardware/EGI_netstation/trialTypesEEG.csv +7 -0
  1178. psychopy/demos/builder/Hardware/Eyetracking_visual_search/readme.md +19 -0
  1179. psychopy/demos/builder/Hardware/Eyetracking_visual_search/trials_params.xlsx +0 -0
  1180. psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +691 -0
  1181. psychopy/demos/builder/Hardware/camera/camera.psyexp +263 -0
  1182. psychopy/demos/builder/Hardware/camera/readme.md +6 -0
  1183. psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +354 -0
  1184. psychopy/demos/builder/Hardware/eyetracking/readme.md +7 -0
  1185. psychopy/demos/builder/Hardware/eyetracking_custom_cal/Bullseye_grey.mov +0 -0
  1186. psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +349 -0
  1187. psychopy/demos/builder/Hardware/eyetracking_custom_cal/readme.md +7 -0
  1188. psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +202 -0
  1189. psychopy/demos/builder/Hardware/fMRI/readme.md +7 -0
  1190. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +349 -0
  1191. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +304 -0
  1192. psychopy/demos/builder/Hardware/microphone/microphone.psyexp +451 -0
  1193. psychopy/demos/builder/Hardware/microphone/phrases.xlsx +0 -0
  1194. psychopy/demos/builder/Hardware/microphone/readme.md +9 -0
  1195. psychopy/demos/builder/Hardware/pump/README.md +19 -0
  1196. psychopy/demos/builder/Hardware/pump/pump.psyexp +382 -0
  1197. psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +288 -0
  1198. psychopy/demos/builder/Helper Tools/achorVSalignment/readme.md +5 -0
  1199. psychopy/demos/builder/Helper Tools/clockFace/README.md +3 -0
  1200. psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +160 -0
  1201. psychopy/demos/builder/Helper Tools/colors/README.md +5 -0
  1202. psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -0
  1203. psychopy/demos/builder/Helper Tools/drawPolygon/README.md +5 -0
  1204. psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +591 -0
  1205. psychopy/demos/builder/Helper Tools/keyNameFinder/README.md +14 -0
  1206. psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +169 -0
  1207. psychopy/demos/builder/Helper Tools/spatialUnits/README.md +6 -0
  1208. psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +157 -0
  1209. psychopy/demos/builder/README.txt +43 -0
  1210. psychopy/demos/builder/__init__.py +0 -0
  1211. psychopy/demos/coder/__init__.py +0 -0
  1212. psychopy/demos/coder/basic/hello_world.py +37 -0
  1213. psychopy/demos/coder/csvFromPsydat.py +29 -0
  1214. psychopy/demos/coder/experiment control/JND_staircase_analysis.py +85 -0
  1215. psychopy/demos/coder/experiment control/JND_staircase_exp.py +110 -0
  1216. psychopy/demos/coder/experiment control/TrialHandler.py +64 -0
  1217. psychopy/demos/coder/experiment control/TrialHandler2.py +42 -0
  1218. psychopy/demos/coder/experiment control/__init__.py +0 -0
  1219. psychopy/demos/coder/experiment control/autoDraw_autoLog.py +50 -0
  1220. psychopy/demos/coder/experiment control/experimentHandler.py +57 -0
  1221. psychopy/demos/coder/experiment control/fMRI_launchScan.py +74 -0
  1222. psychopy/demos/coder/experiment control/gammaMotionAnalysis.py +68 -0
  1223. psychopy/demos/coder/experiment control/gammaMotionNull.py +169 -0
  1224. psychopy/demos/coder/experiment control/logFiles.py +55 -0
  1225. psychopy/demos/coder/experiment control/piloting.py +65 -0
  1226. psychopy/demos/coder/experiment control/runtimeInfo.py +79 -0
  1227. psychopy/demos/coder/hardware/CRS_BitsBox.py +75 -0
  1228. psychopy/demos/coder/hardware/CRS_BitsPlusPlus.py +73 -0
  1229. psychopy/demos/coder/hardware/RiftHeadTrackingExample.py +95 -0
  1230. psychopy/demos/coder/hardware/RiftMinimal.py +44 -0
  1231. psychopy/demos/coder/hardware/VSHD_Distortion.py +49 -0
  1232. psychopy/demos/coder/hardware/__init__.py +0 -0
  1233. psychopy/demos/coder/hardware/camera.py +90 -0
  1234. psychopy/demos/coder/hardware/cedrusRB730.py +38 -0
  1235. psychopy/demos/coder/hardware/crsBitsAdvancedDemo.py +780 -0
  1236. psychopy/demos/coder/hardware/egi_netstation.py +45 -0
  1237. psychopy/demos/coder/hardware/ioLab_bbox.py +62 -0
  1238. psychopy/demos/coder/hardware/labjack_u3.py +61 -0
  1239. psychopy/demos/coder/hardware/monitorDemo.py +28 -0
  1240. psychopy/demos/coder/hardware/parallelPortOutput.py +49 -0
  1241. psychopy/demos/coder/hardware/qmixPump.py +79 -0
  1242. psychopy/demos/coder/hardware/testSoundLatency.py +127 -0
  1243. psychopy/demos/coder/input/GUI.py +52 -0
  1244. psychopy/demos/coder/input/__init__.py +0 -0
  1245. psychopy/demos/coder/input/customMouse.py +51 -0
  1246. psychopy/demos/coder/input/joystick_universal.py +84 -0
  1247. psychopy/demos/coder/input/keyNameFinder.py +39 -0
  1248. psychopy/demos/coder/input/mic.png +0 -0
  1249. psychopy/demos/coder/input/mouse.py +66 -0
  1250. psychopy/demos/coder/iohub/delaytest.py +231 -0
  1251. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/canal.jpg +0 -0
  1252. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/fall.jpg +0 -0
  1253. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/lake.jpg +0 -0
  1254. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/party.jpg +0 -0
  1255. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/swimming.jpg +0 -0
  1256. psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByConditionVariables.py +67 -0
  1257. psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByMessages.py +34 -0
  1258. psychopy/demos/coder/iohub/eyetracking/gcCursor/run.py +323 -0
  1259. psychopy/demos/coder/iohub/eyetracking/gcCursor/trial_conditions.xlsx +0 -0
  1260. psychopy/demos/coder/iohub/eyetracking/simple.py +147 -0
  1261. psychopy/demos/coder/iohub/eyetracking/validation.py +251 -0
  1262. psychopy/demos/coder/iohub/iodatastore/saveEventReport.py +56 -0
  1263. psychopy/demos/coder/iohub/keyboard.py +189 -0
  1264. psychopy/demos/coder/iohub/keyboardreactiontime.py +88 -0
  1265. psychopy/demos/coder/iohub/launchHub.py +160 -0
  1266. psychopy/demos/coder/iohub/mouse.py +112 -0
  1267. psychopy/demos/coder/iohub/mouse_multi_window.py +124 -0
  1268. psychopy/demos/coder/iohub/serial/_parseserial.py +53 -0
  1269. psychopy/demos/coder/iohub/serial/customparser.py +84 -0
  1270. psychopy/demos/coder/iohub/serial/pstbox.py +166 -0
  1271. psychopy/demos/coder/iohub/wintab/_wintabgraphics.py +281 -0
  1272. psychopy/demos/coder/iohub/wintab/pen_demo.py +260 -0
  1273. psychopy/demos/coder/misc/encrypt_data.py +48 -0
  1274. psychopy/demos/coder/misc/makeMovie.py +28 -0
  1275. psychopy/demos/coder/misc/rigidBodyTransform.py +76 -0
  1276. psychopy/demos/coder/stimuli/Campaign.ttf +0 -0
  1277. psychopy/demos/coder/stimuli/MovieStim.py +65 -0
  1278. psychopy/demos/coder/stimuli/__init__.py +0 -0
  1279. psychopy/demos/coder/stimuli/aperture.py +37 -0
  1280. psychopy/demos/coder/stimuli/beach.jpg +0 -0
  1281. psychopy/demos/coder/stimuli/bufferImageStim.py +78 -0
  1282. psychopy/demos/coder/stimuli/clockface.py +43 -0
  1283. psychopy/demos/coder/stimuli/colorPalette.py +134 -0
  1284. psychopy/demos/coder/stimuli/compare_text_timing.py +193 -0
  1285. psychopy/demos/coder/stimuli/counterphase.py +43 -0
  1286. psychopy/demos/coder/stimuli/customTextures.py +57 -0
  1287. psychopy/demos/coder/stimuli/dot_gabors.py +35 -0
  1288. psychopy/demos/coder/stimuli/dots.py +35 -0
  1289. psychopy/demos/coder/stimuli/elementArrays.py +92 -0
  1290. psychopy/demos/coder/stimuli/embeddedOpenGL.py +35 -0
  1291. psychopy/demos/coder/stimuli/face.jpg +0 -0
  1292. psychopy/demos/coder/stimuli/face_jpg.py +48 -0
  1293. psychopy/demos/coder/stimuli/gabor.py +30 -0
  1294. psychopy/demos/coder/stimuli/imagesAndPatches.py +51 -0
  1295. psychopy/demos/coder/stimuli/jwpIntro.mp4 +0 -0
  1296. psychopy/demos/coder/stimuli/kanizsa.py +41 -0
  1297. psychopy/demos/coder/stimuli/maskReveal.py +63 -0
  1298. psychopy/demos/coder/stimuli/plaid.py +43 -0
  1299. psychopy/demos/coder/stimuli/ratingScale.py +183 -0
  1300. psychopy/demos/coder/stimuli/rotatingFlashingWedge.py +37 -0
  1301. psychopy/demos/coder/stimuli/screensAndWindows.py +58 -0
  1302. psychopy/demos/coder/stimuli/secondOrderGratings.py +66 -0
  1303. psychopy/demos/coder/stimuli/shapeContains.py +50 -0
  1304. psychopy/demos/coder/stimuli/shapes.py +63 -0
  1305. psychopy/demos/coder/stimuli/soundStimuli.py +49 -0
  1306. psychopy/demos/coder/stimuli/starField.py +48 -0
  1307. psychopy/demos/coder/stimuli/stim3d.py +107 -0
  1308. psychopy/demos/coder/stimuli/textBoxStim/textbox_glyph_placement.py +93 -0
  1309. psychopy/demos/coder/stimuli/textBoxStim/textbox_simple.py +71 -0
  1310. psychopy/demos/coder/stimuli/textStimuli.py +106 -0
  1311. psychopy/demos/coder/stimuli/textbox_editable.py +64 -0
  1312. psychopy/demos/coder/stimuli/variousVisualStims.py +47 -0
  1313. psychopy/demos/coder/stimuli/visual_noise.py +31 -0
  1314. psychopy/demos/coder/sysInfo.py +56 -0
  1315. psychopy/demos/coder/timing/__init__.py +0 -0
  1316. psychopy/demos/coder/timing/callOnFlip.py +39 -0
  1317. psychopy/demos/coder/timing/clocksAndTimers.py +46 -0
  1318. psychopy/demos/coder/timing/millikeyKeyboardTimingTest.py +323 -0
  1319. psychopy/demos/coder/timing/timeByFrames.py +74 -0
  1320. psychopy/demos/coder/timing/timeByFramesEx.py +107 -0
  1321. psychopy/demos/coder/understanding psychopy/colors.py +70 -0
  1322. psychopy/demos/coder/understanding psychopy/fontLayout.py +69 -0
  1323. psychopy/demos/demo_migration.py +214 -0
  1324. psychopy/demos/modernizeDemos.py +16 -0
  1325. psychopy/demos/test_demo_migration.py +155 -0
  1326. psychopy/devices/__init__.py +8 -0
  1327. psychopy/event.py +1333 -0
  1328. psychopy/exceptions.py +59 -0
  1329. psychopy/experiment/__init__.py +51 -0
  1330. psychopy/experiment/_experiment.py +1392 -0
  1331. psychopy/experiment/blankTemplate.xltx +0 -0
  1332. psychopy/experiment/components/__init__.py +411 -0
  1333. psychopy/experiment/components/_base.py +1351 -0
  1334. psychopy/experiment/components/aperture/__init__.py +149 -0
  1335. psychopy/experiment/components/aperture/classic/aperture.png +0 -0
  1336. psychopy/experiment/components/aperture/classic/aperture@2x.png +0 -0
  1337. psychopy/experiment/components/aperture/dark/aperture.png +0 -0
  1338. psychopy/experiment/components/aperture/dark/aperture@2x.png +0 -0
  1339. psychopy/experiment/components/aperture/light/aperture.png +0 -0
  1340. psychopy/experiment/components/aperture/light/aperture@2x.png +0 -0
  1341. psychopy/experiment/components/brush/__init__.py +163 -0
  1342. psychopy/experiment/components/brush/classic/brush.png +0 -0
  1343. psychopy/experiment/components/brush/classic/brush@2x.png +0 -0
  1344. psychopy/experiment/components/brush/dark/brush.png +0 -0
  1345. psychopy/experiment/components/brush/dark/brush@2x.png +0 -0
  1346. psychopy/experiment/components/brush/light/brush.png +0 -0
  1347. psychopy/experiment/components/brush/light/brush@2x.png +0 -0
  1348. psychopy/experiment/components/button/__init__.py +489 -0
  1349. psychopy/experiment/components/button/classic/button.png +0 -0
  1350. psychopy/experiment/components/button/classic/button@2x.png +0 -0
  1351. psychopy/experiment/components/button/dark/button.png +0 -0
  1352. psychopy/experiment/components/button/dark/button@2x.png +0 -0
  1353. psychopy/experiment/components/button/light/button.png +0 -0
  1354. psychopy/experiment/components/button/light/button@2x.png +0 -0
  1355. psychopy/experiment/components/buttonBox/__init__.py +316 -0
  1356. psychopy/experiment/components/buttonBox/classic/buttonBox.png +0 -0
  1357. psychopy/experiment/components/buttonBox/classic/buttonBox@2x.png +0 -0
  1358. psychopy/experiment/components/buttonBox/dark/buttonBox.png +0 -0
  1359. psychopy/experiment/components/buttonBox/dark/buttonBox@2x.png +0 -0
  1360. psychopy/experiment/components/buttonBox/light/buttonBox.png +0 -0
  1361. psychopy/experiment/components/buttonBox/light/buttonBox@2x.png +0 -0
  1362. psychopy/experiment/components/camera/__init__.py +591 -0
  1363. psychopy/experiment/components/camera/classic/webcam.png +0 -0
  1364. psychopy/experiment/components/camera/classic/webcam@2x.png +0 -0
  1365. psychopy/experiment/components/camera/dark/webcam.png +0 -0
  1366. psychopy/experiment/components/camera/dark/webcam@2x.png +0 -0
  1367. psychopy/experiment/components/camera/light/webcam.png +0 -0
  1368. psychopy/experiment/components/camera/light/webcam@2x.png +0 -0
  1369. psychopy/experiment/components/code/__init__.py +266 -0
  1370. psychopy/experiment/components/code/classic/code.png +0 -0
  1371. psychopy/experiment/components/code/classic/code@2x.png +0 -0
  1372. psychopy/experiment/components/code/dark/code.png +0 -0
  1373. psychopy/experiment/components/code/dark/code@2x.png +0 -0
  1374. psychopy/experiment/components/code/light/code.png +0 -0
  1375. psychopy/experiment/components/code/light/code@2x.png +0 -0
  1376. psychopy/experiment/components/dots/__init__.py +199 -0
  1377. psychopy/experiment/components/dots/classic/dots.png +0 -0
  1378. psychopy/experiment/components/dots/classic/dots@2x.png +0 -0
  1379. psychopy/experiment/components/dots/dark/dots.png +0 -0
  1380. psychopy/experiment/components/dots/dark/dots@2x.png +0 -0
  1381. psychopy/experiment/components/dots/dots.xcf +0 -0
  1382. psychopy/experiment/components/dots/light/dots.png +0 -0
  1383. psychopy/experiment/components/dots/light/dots@2x.png +0 -0
  1384. psychopy/experiment/components/eyetracker_record/__init__.py +128 -0
  1385. psychopy/experiment/components/eyetracker_record/classic/eyetracker_record.png +0 -0
  1386. psychopy/experiment/components/eyetracker_record/classic/eyetracker_record@2x.png +0 -0
  1387. psychopy/experiment/components/eyetracker_record/dark/eyetracker_record.png +0 -0
  1388. psychopy/experiment/components/eyetracker_record/dark/eyetracker_record@2x.png +0 -0
  1389. psychopy/experiment/components/eyetracker_record/light/eyetracker_record.png +0 -0
  1390. psychopy/experiment/components/eyetracker_record/light/eyetracker_record@2x.png +0 -0
  1391. psychopy/experiment/components/form/__init__.py +223 -0
  1392. psychopy/experiment/components/form/classic/form.png +0 -0
  1393. psychopy/experiment/components/form/classic/form@2x.png +0 -0
  1394. psychopy/experiment/components/form/dark/form.png +0 -0
  1395. psychopy/experiment/components/form/dark/form@2x.png +0 -0
  1396. psychopy/experiment/components/form/formItems.xltx +0 -0
  1397. psychopy/experiment/components/form/light/form.png +0 -0
  1398. psychopy/experiment/components/form/light/form@2x.png +0 -0
  1399. psychopy/experiment/components/grating/__init__.py +192 -0
  1400. psychopy/experiment/components/grating/classic/grating.png +0 -0
  1401. psychopy/experiment/components/grating/classic/grating@2x.png +0 -0
  1402. psychopy/experiment/components/grating/dark/grating.png +0 -0
  1403. psychopy/experiment/components/grating/dark/grating@2x.png +0 -0
  1404. psychopy/experiment/components/grating/light/grating.png +0 -0
  1405. psychopy/experiment/components/grating/light/grating@2x.png +0 -0
  1406. psychopy/experiment/components/image/__init__.py +184 -0
  1407. psychopy/experiment/components/image/classic/image.png +0 -0
  1408. psychopy/experiment/components/image/classic/image@2x.png +0 -0
  1409. psychopy/experiment/components/image/dark/image.png +0 -0
  1410. psychopy/experiment/components/image/dark/image@2x.png +0 -0
  1411. psychopy/experiment/components/image/light/image.png +0 -0
  1412. psychopy/experiment/components/image/light/image@2x.png +0 -0
  1413. psychopy/experiment/components/joyButtons/__init__.py +453 -0
  1414. psychopy/experiment/components/joyButtons/classic/joyButtons.png +0 -0
  1415. psychopy/experiment/components/joyButtons/classic/joybuttons@2x.png +0 -0
  1416. psychopy/experiment/components/joyButtons/dark/joyButtons.png +0 -0
  1417. psychopy/experiment/components/joyButtons/dark/joyButtons@2x.png +0 -0
  1418. psychopy/experiment/components/joyButtons/light/joyButtons.png +0 -0
  1419. psychopy/experiment/components/joyButtons/light/joyButtons@2x.png +0 -0
  1420. psychopy/experiment/components/joyButtons/virtualJoyButtons.py +34 -0
  1421. psychopy/experiment/components/joystick/__init__.py +572 -0
  1422. psychopy/experiment/components/joystick/classic/joystick.png +0 -0
  1423. psychopy/experiment/components/joystick/classic/joystick@2x.png +0 -0
  1424. psychopy/experiment/components/joystick/dark/joystick.png +0 -0
  1425. psychopy/experiment/components/joystick/dark/joystick@2x.png +0 -0
  1426. psychopy/experiment/components/joystick/light/joystick.png +0 -0
  1427. psychopy/experiment/components/joystick/light/joystick@2x.png +0 -0
  1428. psychopy/experiment/components/joystick/virtualJoystick.py +40 -0
  1429. psychopy/experiment/components/keyboard/__init__.py +587 -0
  1430. psychopy/experiment/components/keyboard/classic/keyboard.png +0 -0
  1431. psychopy/experiment/components/keyboard/classic/keyboard@2x.png +0 -0
  1432. psychopy/experiment/components/keyboard/dark/keyboard.png +0 -0
  1433. psychopy/experiment/components/keyboard/dark/keyboard@2x.png +0 -0
  1434. psychopy/experiment/components/keyboard/light/keyboard.png +0 -0
  1435. psychopy/experiment/components/keyboard/light/keyboard@2x.png +0 -0
  1436. psychopy/experiment/components/keyboard.xcf +0 -0
  1437. psychopy/experiment/components/microphone/__init__.py +664 -0
  1438. psychopy/experiment/components/microphone/classic/microphone.png +0 -0
  1439. psychopy/experiment/components/microphone/classic/microphone@2x.png +0 -0
  1440. psychopy/experiment/components/microphone/dark/microphone.png +0 -0
  1441. psychopy/experiment/components/microphone/dark/microphone@2x.png +0 -0
  1442. psychopy/experiment/components/microphone/light/microphone.png +0 -0
  1443. psychopy/experiment/components/microphone/light/microphone@2x.png +0 -0
  1444. psychopy/experiment/components/mouse/__init__.py +747 -0
  1445. psychopy/experiment/components/mouse/classic/mouse.png +0 -0
  1446. psychopy/experiment/components/mouse/classic/mouse@2x.png +0 -0
  1447. psychopy/experiment/components/mouse/dark/mouse.png +0 -0
  1448. psychopy/experiment/components/mouse/dark/mouse@2x.png +0 -0
  1449. psychopy/experiment/components/mouse/light/mouse.png +0 -0
  1450. psychopy/experiment/components/mouse/light/mouse@2x.png +0 -0
  1451. psychopy/experiment/components/movie/__init__.py +367 -0
  1452. psychopy/experiment/components/movie/classic/movie.png +0 -0
  1453. psychopy/experiment/components/movie/classic/movie@2x.png +0 -0
  1454. psychopy/experiment/components/movie/dark/movie.png +0 -0
  1455. psychopy/experiment/components/movie/dark/movie@2x.png +0 -0
  1456. psychopy/experiment/components/movie/light/movie.png +0 -0
  1457. psychopy/experiment/components/movie/light/movie@2x.png +0 -0
  1458. psychopy/experiment/components/panorama/__init__.py +456 -0
  1459. psychopy/experiment/components/panorama/classic/panorama.png +0 -0
  1460. psychopy/experiment/components/panorama/classic/panorama@2x.png +0 -0
  1461. psychopy/experiment/components/panorama/dark/panorama.png +0 -0
  1462. psychopy/experiment/components/panorama/dark/panorama@2x.png +0 -0
  1463. psychopy/experiment/components/panorama/light/panorama.png +0 -0
  1464. psychopy/experiment/components/panorama/light/panorama@2x.png +0 -0
  1465. psychopy/experiment/components/parallelOut/__init__.py +178 -0
  1466. psychopy/experiment/components/parallelOut/classic/parallel.png +0 -0
  1467. psychopy/experiment/components/parallelOut/classic/parallel@2x.png +0 -0
  1468. psychopy/experiment/components/parallelOut/dark/parallel.png +0 -0
  1469. psychopy/experiment/components/parallelOut/dark/parallel@2x.png +0 -0
  1470. psychopy/experiment/components/parallelOut/light/parallel.png +0 -0
  1471. psychopy/experiment/components/parallelOut/light/parallel@2x.png +0 -0
  1472. psychopy/experiment/components/patch/__init__.py +121 -0
  1473. psychopy/experiment/components/patch/classic/patch.png +0 -0
  1474. psychopy/experiment/components/patch/dark/patch.png +0 -0
  1475. psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
  1476. psychopy/experiment/components/patch/light/patch.png +0 -0
  1477. psychopy/experiment/components/patch/light/patch@2x.png +0 -0
  1478. psychopy/experiment/components/polygon/__init__.py +303 -0
  1479. psychopy/experiment/components/polygon/classic/polygon.png +0 -0
  1480. psychopy/experiment/components/polygon/classic/polygon@2x.png +0 -0
  1481. psychopy/experiment/components/polygon/dark/polygon.png +0 -0
  1482. psychopy/experiment/components/polygon/dark/polygon@2x.png +0 -0
  1483. psychopy/experiment/components/polygon/light/polygon.png +0 -0
  1484. psychopy/experiment/components/polygon/light/polygon@2x.png +0 -0
  1485. psychopy/experiment/components/progress/__init__.py +130 -0
  1486. psychopy/experiment/components/progress/classic/progress.png +0 -0
  1487. psychopy/experiment/components/progress/classic/progress@2x.png +0 -0
  1488. psychopy/experiment/components/progress/dark/progress.png +0 -0
  1489. psychopy/experiment/components/progress/dark/progress@2x.png +0 -0
  1490. psychopy/experiment/components/progress/light/progress.png +0 -0
  1491. psychopy/experiment/components/progress/light/progress@2x.png +0 -0
  1492. psychopy/experiment/components/ratingScale/__init__.py +337 -0
  1493. psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
  1494. psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
  1495. psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
  1496. psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
  1497. psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
  1498. psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
  1499. psychopy/experiment/components/resourceManager/__init__.py +176 -0
  1500. psychopy/experiment/components/resourceManager/classic/resource_manager.png +0 -0
  1501. psychopy/experiment/components/resourceManager/classic/resource_manager@2x.png +0 -0
  1502. psychopy/experiment/components/resourceManager/dark/resource_manager.png +0 -0
  1503. psychopy/experiment/components/resourceManager/dark/resource_manager@2x.png +0 -0
  1504. psychopy/experiment/components/resourceManager/light/resource_manager.png +0 -0
  1505. psychopy/experiment/components/resourceManager/light/resource_manager@2x.png +0 -0
  1506. psychopy/experiment/components/roi/__init__.py +311 -0
  1507. psychopy/experiment/components/roi/classic/eyetracker_roi.png +0 -0
  1508. psychopy/experiment/components/roi/classic/eyetracker_roi@2x.png +0 -0
  1509. psychopy/experiment/components/roi/dark/eyetracker_roi.png +0 -0
  1510. psychopy/experiment/components/roi/dark/eyetracker_roi@2X.png +0 -0
  1511. psychopy/experiment/components/roi/light/eyetracker_roi.png +0 -0
  1512. psychopy/experiment/components/roi/light/eyetracker_roi@2X.png +0 -0
  1513. psychopy/experiment/components/routineSettings/__init__.py +338 -0
  1514. psychopy/experiment/components/routineSettings/classic/routineSettings.png +0 -0
  1515. psychopy/experiment/components/routineSettings/classic/routineSettings@2x.png +0 -0
  1516. psychopy/experiment/components/routineSettings/dark/routineSettings.png +0 -0
  1517. psychopy/experiment/components/routineSettings/dark/routineSettings@2x.png +0 -0
  1518. psychopy/experiment/components/routineSettings/light/routineSettings.png +0 -0
  1519. psychopy/experiment/components/routineSettings/light/routineSettings@2x.png +0 -0
  1520. psychopy/experiment/components/serialOut/__init__.py +205 -0
  1521. psychopy/experiment/components/serialOut/classic/serial.png +0 -0
  1522. psychopy/experiment/components/serialOut/classic/serial@2x.png +0 -0
  1523. psychopy/experiment/components/serialOut/dark/serial.png +0 -0
  1524. psychopy/experiment/components/serialOut/dark/serial@2x.png +0 -0
  1525. psychopy/experiment/components/serialOut/light/serial.png +0 -0
  1526. psychopy/experiment/components/serialOut/light/serial@2x.png +0 -0
  1527. psychopy/experiment/components/settings/JS_htmlHeader.tmpl +23 -0
  1528. psychopy/experiment/components/settings/JS_setupExp.tmpl +28 -0
  1529. psychopy/experiment/components/settings/__init__.py +2155 -0
  1530. psychopy/experiment/components/settings/classic/settings.png +0 -0
  1531. psychopy/experiment/components/settings/classic/settings@2x.png +0 -0
  1532. psychopy/experiment/components/settings/dark/settings.png +0 -0
  1533. psychopy/experiment/components/settings/dark/settings@2x.png +0 -0
  1534. psychopy/experiment/components/settings/light/settings.png +0 -0
  1535. psychopy/experiment/components/settings/light/settings@2x.png +0 -0
  1536. psychopy/experiment/components/slider/__init__.py +410 -0
  1537. psychopy/experiment/components/slider/classic/slider.png +0 -0
  1538. psychopy/experiment/components/slider/classic/slider@2x.png +0 -0
  1539. psychopy/experiment/components/slider/dark/slider.png +0 -0
  1540. psychopy/experiment/components/slider/dark/slider@2x.png +0 -0
  1541. psychopy/experiment/components/slider/light/slider.png +0 -0
  1542. psychopy/experiment/components/slider/light/slider@2x.png +0 -0
  1543. psychopy/experiment/components/sound/__init__.py +307 -0
  1544. psychopy/experiment/components/sound/classic/sound.png +0 -0
  1545. psychopy/experiment/components/sound/classic/sound@2x.png +0 -0
  1546. psychopy/experiment/components/sound/dark/sound.png +0 -0
  1547. psychopy/experiment/components/sound/dark/sound@2x.png +0 -0
  1548. psychopy/experiment/components/sound/light/sound.png +0 -0
  1549. psychopy/experiment/components/sound/light/sound@2x.png +0 -0
  1550. psychopy/experiment/components/static/__init__.py +267 -0
  1551. psychopy/experiment/components/static/classic/static.png +0 -0
  1552. psychopy/experiment/components/static/classic/static@2x.png +0 -0
  1553. psychopy/experiment/components/static/dark/static.png +0 -0
  1554. psychopy/experiment/components/static/dark/static@2x.png +0 -0
  1555. psychopy/experiment/components/static/light/static.png +0 -0
  1556. psychopy/experiment/components/static/light/static@2x.png +0 -0
  1557. psychopy/experiment/components/text/__init__.py +169 -0
  1558. psychopy/experiment/components/text/classic/text.png +0 -0
  1559. psychopy/experiment/components/text/classic/text@2x.png +0 -0
  1560. psychopy/experiment/components/text/dark/text.png +0 -0
  1561. psychopy/experiment/components/text/dark/text@2x.png +0 -0
  1562. psychopy/experiment/components/text/light/text.png +0 -0
  1563. psychopy/experiment/components/text/light/text@2x.png +0 -0
  1564. psychopy/experiment/components/textbox/__init__.py +330 -0
  1565. psychopy/experiment/components/textbox/classic/textbox.png +0 -0
  1566. psychopy/experiment/components/textbox/classic/textbox@2x.png +0 -0
  1567. psychopy/experiment/components/textbox/dark/textbox.png +0 -0
  1568. psychopy/experiment/components/textbox/dark/textbox@2x.png +0 -0
  1569. psychopy/experiment/components/textbox/light/textbox.png +0 -0
  1570. psychopy/experiment/components/textbox/light/textbox@2x.png +0 -0
  1571. psychopy/experiment/components/unknown/__init__.py +86 -0
  1572. psychopy/experiment/components/unknown/classic/unknown.png +0 -0
  1573. psychopy/experiment/components/unknown/classic/unknown@2x.png +0 -0
  1574. psychopy/experiment/components/unknown/dark/unknown.png +0 -0
  1575. psychopy/experiment/components/unknown/dark/unknown@2x.png +0 -0
  1576. psychopy/experiment/components/unknown/light/unknown.png +0 -0
  1577. psychopy/experiment/components/unknown/light/unknown@2x.png +0 -0
  1578. psychopy/experiment/components/unknownPlugin/__init__.py +84 -0
  1579. psychopy/experiment/components/unknownPlugin/classic/unknownPlugin.png +0 -0
  1580. psychopy/experiment/components/unknownPlugin/classic/unknownPlugin@2x.png +0 -0
  1581. psychopy/experiment/components/unknownPlugin/dark/unknownPlugin.png +0 -0
  1582. psychopy/experiment/components/unknownPlugin/dark/unknownPlugin@2x.png +0 -0
  1583. psychopy/experiment/components/unknownPlugin/light/unknownPlugin.png +0 -0
  1584. psychopy/experiment/components/unknownPlugin/light/unknownPlugin@2x.png +0 -0
  1585. psychopy/experiment/components/utils.py +0 -0
  1586. psychopy/experiment/components/variable/__init__.py +184 -0
  1587. psychopy/experiment/components/variable/classic/variable.png +0 -0
  1588. psychopy/experiment/components/variable/classic/variable@2x.png +0 -0
  1589. psychopy/experiment/components/variable/dark/variable.png +0 -0
  1590. psychopy/experiment/components/variable/dark/variable@2x.png +0 -0
  1591. psychopy/experiment/components/variable/light/variable.png +0 -0
  1592. psychopy/experiment/components/variable/light/variable@2x.png +0 -0
  1593. psychopy/experiment/experiment.xsd +223 -0
  1594. psychopy/experiment/exports.py +388 -0
  1595. psychopy/experiment/flow.py +531 -0
  1596. psychopy/experiment/localization.py +11 -0
  1597. psychopy/experiment/loopTemplate.xltx +0 -0
  1598. psychopy/experiment/loops.py +952 -0
  1599. psychopy/experiment/params.py +437 -0
  1600. psychopy/experiment/plugins.py +115 -0
  1601. psychopy/experiment/py2js.py +183 -0
  1602. psychopy/experiment/py2js_transpiler.py +606 -0
  1603. psychopy/experiment/questPlusTemplate.xltx +0 -0
  1604. psychopy/experiment/questTemplate.xltx +0 -0
  1605. psychopy/experiment/routines/__init__.py +108 -0
  1606. psychopy/experiment/routines/_base.py +907 -0
  1607. psychopy/experiment/routines/counterbalance/__init__.py +315 -0
  1608. psychopy/experiment/routines/counterbalance/classic/counterbalance.png +0 -0
  1609. psychopy/experiment/routines/counterbalance/classic/counterbalance@2x.png +0 -0
  1610. psychopy/experiment/routines/counterbalance/counterbalanceItems.xltx +0 -0
  1611. psychopy/experiment/routines/counterbalance/dark/counterbalance.png +0 -0
  1612. psychopy/experiment/routines/counterbalance/dark/counterbalance@2x.png +0 -0
  1613. psychopy/experiment/routines/counterbalance/light/counterbalance.png +0 -0
  1614. psychopy/experiment/routines/counterbalance/light/counterbalance@2x.png +0 -0
  1615. psychopy/experiment/routines/eyetracker_calibrate/__init__.py +275 -0
  1616. psychopy/experiment/routines/eyetracker_calibrate/classic/eyetracker_calib.png +0 -0
  1617. psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib.png +0 -0
  1618. psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib@2x.png +0 -0
  1619. psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib.png +0 -0
  1620. psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib@2x.png +0 -0
  1621. psychopy/experiment/routines/eyetracker_validate/__init__.py +354 -0
  1622. psychopy/experiment/routines/eyetracker_validate/classic/eyetracker_valid.png +0 -0
  1623. psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid.png +0 -0
  1624. psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid@2x.png +0 -0
  1625. psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid.png +0 -0
  1626. psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid@2x.png +0 -0
  1627. psychopy/experiment/routines/pavlovia_survey/__init__.py +236 -0
  1628. psychopy/experiment/routines/pavlovia_survey/classic/survey.png +0 -0
  1629. psychopy/experiment/routines/pavlovia_survey/classic/survey@2x.png +0 -0
  1630. psychopy/experiment/routines/pavlovia_survey/dark/survey.png +0 -0
  1631. psychopy/experiment/routines/pavlovia_survey/dark/survey@2x.png +0 -0
  1632. psychopy/experiment/routines/pavlovia_survey/light/survey.png +0 -0
  1633. psychopy/experiment/routines/pavlovia_survey/light/survey@2x.png +0 -0
  1634. psychopy/experiment/routines/photodiodeValidator/__init__.py +429 -0
  1635. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
  1636. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
  1637. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
  1638. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
  1639. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
  1640. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
  1641. psychopy/experiment/routines/unknown/__init__.py +28 -0
  1642. psychopy/experiment/routines/unknown/classic/eyetracker_record.png +0 -0
  1643. psychopy/experiment/routines/unknown/classic/unknown.png +0 -0
  1644. psychopy/experiment/routines/unknown/dark/eyetracker_record.png +0 -0
  1645. psychopy/experiment/routines/unknown/dark/eyetracker_record@2x.png +0 -0
  1646. psychopy/experiment/routines/unknown/dark/unknown.png +0 -0
  1647. psychopy/experiment/routines/unknown/dark/unknown@2x.png +0 -0
  1648. psychopy/experiment/routines/unknown/light/eyetracker_record.png +0 -0
  1649. psychopy/experiment/routines/unknown/light/eyetracker_record@2x.png +0 -0
  1650. psychopy/experiment/routines/unknown/light/unknown.png +0 -0
  1651. psychopy/experiment/routines/unknown/light/unknown@2x.png +0 -0
  1652. psychopy/experiment/routines/utils.py +0 -0
  1653. psychopy/experiment/staircaseTemplate.xltx +0 -0
  1654. psychopy/experiment/utils.py +44 -0
  1655. psychopy/filters.py +11 -0
  1656. psychopy/gamma.py +9 -0
  1657. psychopy/gui/__init__.py +47 -0
  1658. psychopy/gui/qtgui.py +866 -0
  1659. psychopy/gui/util.py +78 -0
  1660. psychopy/gui/wxgui.py +414 -0
  1661. psychopy/hardware/__init__.py +216 -0
  1662. psychopy/hardware/base.py +323 -0
  1663. psychopy/hardware/bbtk/__init__.py +30 -0
  1664. psychopy/hardware/brainproducts.py +31 -0
  1665. psychopy/hardware/button.py +205 -0
  1666. psychopy/hardware/buttonbox/__init__.py +122 -0
  1667. psychopy/hardware/camera/__init__.py +2809 -0
  1668. psychopy/hardware/cedrus.py +36 -0
  1669. psychopy/hardware/crs/__init__.py +46 -0
  1670. psychopy/hardware/crs/bits.py +34 -0
  1671. psychopy/hardware/crs/colorcal.py +30 -0
  1672. psychopy/hardware/crs/optical.py +46 -0
  1673. psychopy/hardware/crs/shaders.py +21 -0
  1674. psychopy/hardware/emotiv.py +33 -0
  1675. psychopy/hardware/emulator.py +37 -0
  1676. psychopy/hardware/eyetracker.py +208 -0
  1677. psychopy/hardware/forp.py +42 -0
  1678. psychopy/hardware/gammasci.py +32 -0
  1679. psychopy/hardware/iolab.py +35 -0
  1680. psychopy/hardware/joystick/__init__.py +597 -0
  1681. psychopy/hardware/keyboard.py +880 -0
  1682. psychopy/hardware/knownDevices.json +52 -0
  1683. psychopy/hardware/labhackers.py +27 -0
  1684. psychopy/hardware/labjacks.py +30 -0
  1685. psychopy/hardware/listener.py +323 -0
  1686. psychopy/hardware/manager.py +963 -0
  1687. psychopy/hardware/microphone.py +1074 -0
  1688. psychopy/hardware/minolta.py +30 -0
  1689. psychopy/hardware/mouse/__init__.py +885 -0
  1690. psychopy/hardware/photodiode.py +639 -0
  1691. psychopy/hardware/photometer/__init__.py +176 -0
  1692. psychopy/hardware/pr.py +30 -0
  1693. psychopy/hardware/qmix.py +41 -0
  1694. psychopy/hardware/serialdevice.py +342 -0
  1695. psychopy/hardware/speaker.py +54 -0
  1696. psychopy/hardware/triggerbox/__init__.py +56 -0
  1697. psychopy/hardware/triggerbox/base.py +170 -0
  1698. psychopy/hardware/triggerbox/parallel.py +362 -0
  1699. psychopy/info.py +790 -0
  1700. psychopy/iohub/__init__.py +45 -0
  1701. psychopy/iohub/client/__init__.py +1454 -0
  1702. psychopy/iohub/client/connect.py +260 -0
  1703. psychopy/iohub/client/eyetracker/__init__.py +4 -0
  1704. psychopy/iohub/client/eyetracker/validation/__init__.py +8 -0
  1705. psychopy/iohub/client/eyetracker/validation/posgrid.py +274 -0
  1706. psychopy/iohub/client/eyetracker/validation/procedure.py +1292 -0
  1707. psychopy/iohub/client/eyetracker/validation/trigger.py +240 -0
  1708. psychopy/iohub/client/keyboard.py +508 -0
  1709. psychopy/iohub/client/wintab.py +378 -0
  1710. psychopy/iohub/constants.py +1176 -0
  1711. psychopy/iohub/datastore/__init__.py +439 -0
  1712. psychopy/iohub/datastore/default_datastore.yaml +8 -0
  1713. psychopy/iohub/datastore/util.py +868 -0
  1714. psychopy/iohub/default_config.yaml +17 -0
  1715. psychopy/iohub/devices/__init__.py +960 -0
  1716. psychopy/iohub/devices/computer.py +607 -0
  1717. psychopy/iohub/devices/default_device.yaml +15 -0
  1718. psychopy/iohub/devices/deviceConfigValidation.py +517 -0
  1719. psychopy/iohub/devices/display/__init__.py +755 -0
  1720. psychopy/iohub/devices/display/default_display.yaml +118 -0
  1721. psychopy/iohub/devices/display/supported_config_settings.yaml +69 -0
  1722. psychopy/iohub/devices/eventfilters.py +3572 -0
  1723. psychopy/iohub/devices/experiment/__init__.py +316 -0
  1724. psychopy/iohub/devices/experiment/default_experiment.yaml +63 -0
  1725. psychopy/iohub/devices/experiment/supported_config_settings.yaml +22 -0
  1726. psychopy/iohub/devices/eyetracker/__init__.py +436 -0
  1727. psychopy/iohub/devices/eyetracker/calibration/__init__.py +1 -0
  1728. psychopy/iohub/devices/eyetracker/calibration/procedure.py +409 -0
  1729. psychopy/iohub/devices/eyetracker/default_eyetracker.yaml +18 -0
  1730. psychopy/iohub/devices/eyetracker/eye_events.py +1751 -0
  1731. psychopy/iohub/devices/eyetracker/filters/__init__.py +4 -0
  1732. psychopy/iohub/devices/eyetracker/filters/parser.py +913 -0
  1733. psychopy/iohub/devices/eyetracker/hw/__init__.py +4 -0
  1734. psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +17 -0
  1735. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +28 -0
  1736. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/calibration.py +18 -0
  1737. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +21 -0
  1738. psychopy/iohub/devices/eyetracker/hw/mouse/__init__.py +8 -0
  1739. psychopy/iohub/devices/eyetracker/hw/mouse/calibration.py +10 -0
  1740. psychopy/iohub/devices/eyetracker/hw/mouse/default_eyetracker.yaml +102 -0
  1741. psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +444 -0
  1742. psychopy/iohub/devices/eyetracker/hw/mouse/supported_config_settings.yaml +110 -0
  1743. psychopy/iohub/devices/eyetracker/hw/pupil_labs/__init__.py +4 -0
  1744. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +26 -0
  1745. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/eyetracker.py +18 -0
  1746. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/__init__.py +29 -0
  1747. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/bisector.py +20 -0
  1748. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/constants.py +19 -0
  1749. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/data_parse.py +22 -0
  1750. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/eyetracker.py +18 -0
  1751. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/pupil_remote.py +18 -0
  1752. psychopy/iohub/devices/eyetracker/hw/sr_research/__init__.py +4 -0
  1753. psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/__init__.py +28 -0
  1754. psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/calibration.py +22 -0
  1755. psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/eyetracker.py +38 -0
  1756. psychopy/iohub/devices/eyetracker/hw/tobii/__init__.py +29 -0
  1757. psychopy/iohub/devices/eyetracker/hw/tobii/calibration.py +19 -0
  1758. psychopy/iohub/devices/eyetracker/hw/tobii/eyetracker.py +17 -0
  1759. psychopy/iohub/devices/eyetracker/hw/tobii/tobiiwrapper.py +19 -0
  1760. psychopy/iohub/devices/eyetracker/supported_config_settings.yaml +44 -0
  1761. psychopy/iohub/devices/keyboard/__init__.py +309 -0
  1762. psychopy/iohub/devices/keyboard/darwin.py +428 -0
  1763. psychopy/iohub/devices/keyboard/darwinkey.py +94 -0
  1764. psychopy/iohub/devices/keyboard/default_keyboard.yaml +94 -0
  1765. psychopy/iohub/devices/keyboard/linux2.py +102 -0
  1766. psychopy/iohub/devices/keyboard/supported_config_settings.yaml +39 -0
  1767. psychopy/iohub/devices/keyboard/win32.py +356 -0
  1768. psychopy/iohub/devices/mouse/__init__.py +709 -0
  1769. psychopy/iohub/devices/mouse/darwin.py +414 -0
  1770. psychopy/iohub/devices/mouse/default_mouse.yaml +92 -0
  1771. psychopy/iohub/devices/mouse/linux2.py +167 -0
  1772. psychopy/iohub/devices/mouse/supported_config_settings.yaml +39 -0
  1773. psychopy/iohub/devices/mouse/win32.py +279 -0
  1774. psychopy/iohub/devices/pyXHook.py +619 -0
  1775. psychopy/iohub/devices/serial/__init__.py +779 -0
  1776. psychopy/iohub/devices/serial/default_pstbox.yaml +108 -0
  1777. psychopy/iohub/devices/serial/default_serial.yaml +108 -0
  1778. psychopy/iohub/devices/serial/supported_config_settings.yaml +85 -0
  1779. psychopy/iohub/devices/serial/supported_config_settings_pstbox.yaml +85 -0
  1780. psychopy/iohub/devices/supported_config_settings.yaml +36 -0
  1781. psychopy/iohub/devices/wintab/__init__.py +580 -0
  1782. psychopy/iohub/devices/wintab/default_wintab.yaml +89 -0
  1783. psychopy/iohub/devices/wintab/supported_config_settings.yaml +42 -0
  1784. psychopy/iohub/devices/wintab/win32.py +722 -0
  1785. psychopy/iohub/devices/xlib.py +6795 -0
  1786. psychopy/iohub/errors.py +61 -0
  1787. psychopy/iohub/lazy_import.py +582 -0
  1788. psychopy/iohub/net.py +349 -0
  1789. psychopy/iohub/server.py +1075 -0
  1790. psychopy/iohub/start_iohub_process.py +118 -0
  1791. psychopy/iohub/util/__init__.py +841 -0
  1792. psychopy/iohub/util/visualangle.py +126 -0
  1793. psychopy/layout.py +916 -0
  1794. psychopy/liaison.py +419 -0
  1795. psychopy/locale_setup.py +31 -0
  1796. psychopy/localization/__init__.py +22 -0
  1797. psychopy/localization/_localization.py +155 -0
  1798. psychopy/localization/generateTranslationTemplate.py +139 -0
  1799. psychopy/localization/mappings.txt +170 -0
  1800. psychopy/localization/messages.pot +7516 -0
  1801. psychopy/localization/readme.txt +68 -0
  1802. psychopy/logging.py +406 -0
  1803. psychopy/microphone.py +54 -0
  1804. psychopy/misc.py +40 -0
  1805. psychopy/monitors/MonitorCenter.py +1254 -0
  1806. psychopy/monitors/__init__.py +30 -0
  1807. psychopy/monitors/calibData.py +78 -0
  1808. psychopy/monitors/calibTools.py +1300 -0
  1809. psychopy/monitors/getLumSeries.py +50 -0
  1810. psychopy/monitors/psychopy-icon.svg +395 -0
  1811. psychopy/monitors/psychopy.ico +0 -0
  1812. psychopy/parallel/__init__.py +206 -0
  1813. psychopy/parallel/_dlportio.py +150 -0
  1814. psychopy/parallel/_inpout.py +120 -0
  1815. psychopy/parallel/_linux.py +105 -0
  1816. psychopy/piloting.py +61 -0
  1817. psychopy/platform_specific/__init__.py +48 -0
  1818. psychopy/platform_specific/darwin.py +328 -0
  1819. psychopy/platform_specific/linux.py +79 -0
  1820. psychopy/platform_specific/posix.py +16 -0
  1821. psychopy/platform_specific/win32.py +99 -0
  1822. psychopy/plugins/__init__.py +1354 -0
  1823. psychopy/preferences/Darwin.spec +282 -0
  1824. psychopy/preferences/FreeBSD.spec +282 -0
  1825. psychopy/preferences/Linux.spec +282 -0
  1826. psychopy/preferences/Windows.spec +282 -0
  1827. psychopy/preferences/__init__.py +20 -0
  1828. psychopy/preferences/baseNoArch.spec +278 -0
  1829. psychopy/preferences/generateHints.py +91 -0
  1830. psychopy/preferences/generateSpec.py +80 -0
  1831. psychopy/preferences/hints.py +329 -0
  1832. psychopy/preferences/preferences.py +332 -0
  1833. psychopy/projects/__init__.py +11 -0
  1834. psychopy/projects/gitignore.py +45 -0
  1835. psychopy/projects/pavlovia.py +1566 -0
  1836. psychopy/projects/sshkeys.py +107 -0
  1837. psychopy/psychojs.zip +0 -0
  1838. psychopy/pylintrc +69 -0
  1839. psychopy/scripts/__init__.py +0 -0
  1840. psychopy/scripts/psyexpCompile.py +233 -0
  1841. psychopy/session.py +1450 -0
  1842. psychopy/sound/__init__.py +279 -0
  1843. psychopy/sound/_base.py +282 -0
  1844. psychopy/sound/audioclip.py +851 -0
  1845. psychopy/sound/audiodevice.py +857 -0
  1846. psychopy/sound/backend_ptb.py +660 -0
  1847. psychopy/sound/backend_pygame.py +309 -0
  1848. psychopy/sound/backend_pyo.py +33 -0
  1849. psychopy/sound/backend_pysound.py +341 -0
  1850. psychopy/sound/backend_sounddevice.py +32 -0
  1851. psychopy/sound/exceptions.py +115 -0
  1852. psychopy/sound/microphone.py +274 -0
  1853. psychopy/sound/transcribe.py +1248 -0
  1854. psychopy/tests/.DS_Store +0 -0
  1855. psychopy/tests/README.md +344 -0
  1856. psychopy/tests/__init__.py +47 -0
  1857. psychopy/tests/data/Electronic_Chime-KevanGC-495939803.wav +0 -0
  1858. psychopy/tests/data/TestCircle_w128h128_bottom_left.png +0 -0
  1859. psychopy/tests/data/TestCircle_w128h128_bottom_right.png +0 -0
  1860. psychopy/tests/data/TestCircle_w128h128_center_center.png +0 -0
  1861. psychopy/tests/data/TestCircle_w128h128_top_left.png +0 -0
  1862. psychopy/tests/data/TestCircle_w128h128_top_right.png +0 -0
  1863. psychopy/tests/data/TestCircle_w128h64_bottom_left.png +0 -0
  1864. psychopy/tests/data/TestCircle_w128h64_bottom_right.png +0 -0
  1865. psychopy/tests/data/TestCircle_w128h64_center_center.png +0 -0
  1866. psychopy/tests/data/TestCircle_w128h64_top_left.png +0 -0
  1867. psychopy/tests/data/TestCircle_w128h64_top_right.png +0 -0
  1868. psychopy/tests/data/TestCircle_w64h128_bottom_left.png +0 -0
  1869. psychopy/tests/data/TestCircle_w64h128_bottom_right.png +0 -0
  1870. psychopy/tests/data/TestCircle_w64h128_center_center.png +0 -0
  1871. psychopy/tests/data/TestCircle_w64h128_top_left.png +0 -0
  1872. psychopy/tests/data/TestCircle_w64h128_top_right.png +0 -0
  1873. psychopy/tests/data/TestCircle_w64h64_bottom_left.png +0 -0
  1874. psychopy/tests/data/TestCircle_w64h64_bottom_right.png +0 -0
  1875. psychopy/tests/data/TestCircle_w64h64_center_center.png +0 -0
  1876. psychopy/tests/data/TestCircle_w64h64_top_left.png +0 -0
  1877. psychopy/tests/data/TestCircle_w64h64_top_right.png +0 -0
  1878. psychopy/tests/data/TestForm_scrolling_nq10_s0.5.png +0 -0
  1879. psychopy/tests/data/TestForm_scrolling_nq10_s0.png +0 -0
  1880. psychopy/tests/data/TestForm_scrolling_nq10_s1.png +0 -0
  1881. psychopy/tests/data/TestForm_scrolling_nq1_s0.5.png +0 -0
  1882. psychopy/tests/data/TestForm_scrolling_nq1_s0.png +0 -0
  1883. psychopy/tests/data/TestForm_scrolling_nq1_s1.png +0 -0
  1884. psychopy/tests/data/TestForm_scrolling_nq3_s0.5.png +0 -0
  1885. psychopy/tests/data/TestForm_scrolling_nq3_s0.png +0 -0
  1886. psychopy/tests/data/TestForm_scrolling_nq3_s1.png +0 -0
  1887. psychopy/tests/data/TestImage_w128h128_bottom_left.png +0 -0
  1888. psychopy/tests/data/TestImage_w128h128_bottom_right.png +0 -0
  1889. psychopy/tests/data/TestImage_w128h128_center_center.png +0 -0
  1890. psychopy/tests/data/TestImage_w128h128_top_left.png +0 -0
  1891. psychopy/tests/data/TestImage_w128h128_top_right.png +0 -0
  1892. psychopy/tests/data/TestImage_w128h64_bottom_left.png +0 -0
  1893. psychopy/tests/data/TestImage_w128h64_bottom_right.png +0 -0
  1894. psychopy/tests/data/TestImage_w128h64_center_center.png +0 -0
  1895. psychopy/tests/data/TestImage_w128h64_top_left.png +0 -0
  1896. psychopy/tests/data/TestImage_w128h64_top_right.png +0 -0
  1897. psychopy/tests/data/TestImage_w64h128_bottom_left.png +0 -0
  1898. psychopy/tests/data/TestImage_w64h128_bottom_right.png +0 -0
  1899. psychopy/tests/data/TestImage_w64h128_center_center.png +0 -0
  1900. psychopy/tests/data/TestImage_w64h128_top_left.png +0 -0
  1901. psychopy/tests/data/TestImage_w64h128_top_right.png +0 -0
  1902. psychopy/tests/data/TestImage_w64h64_bottom_left.png +0 -0
  1903. psychopy/tests/data/TestImage_w64h64_bottom_right.png +0 -0
  1904. psychopy/tests/data/TestImage_w64h64_center_center.png +0 -0
  1905. psychopy/tests/data/TestImage_w64h64_top_left.png +0 -0
  1906. psychopy/tests/data/TestImage_w64h64_top_right.png +0 -0
  1907. psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.3.png +0 -0
  1908. psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.6.png +0 -0
  1909. psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.3.png +0 -0
  1910. psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.6.png +0 -0
  1911. psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.3.png +0 -0
  1912. psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.6.png +0 -0
  1913. psychopy/tests/data/TestProgress_testValue_minmax_0.png +0 -0
  1914. psychopy/tests/data/TestProgress_testValue_minmax_1.png +0 -0
  1915. psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.3.png +0 -0
  1916. psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.6.png +0 -0
  1917. psychopy/tests/data/TestProgress_testValue_vertical_center center_0.3.png +0 -0
  1918. psychopy/tests/data/TestProgress_testValue_vertical_center center_0.6.png +0 -0
  1919. psychopy/tests/data/TestProgress_testValue_vertical_top center_0.3.png +0 -0
  1920. psychopy/tests/data/TestProgress_testValue_vertical_top center_0.6.png +0 -0
  1921. psychopy/tests/data/TestProgress_w128h128_bottom_left.png +0 -0
  1922. psychopy/tests/data/TestProgress_w128h128_bottom_right.png +0 -0
  1923. psychopy/tests/data/TestProgress_w128h128_center_center.png +0 -0
  1924. psychopy/tests/data/TestProgress_w128h128_top_left.png +0 -0
  1925. psychopy/tests/data/TestProgress_w128h128_top_right.png +0 -0
  1926. psychopy/tests/data/TestProgress_w128h64_bottom_left.png +0 -0
  1927. psychopy/tests/data/TestProgress_w128h64_bottom_right.png +0 -0
  1928. psychopy/tests/data/TestProgress_w128h64_center_center.png +0 -0
  1929. psychopy/tests/data/TestProgress_w128h64_top_left.png +0 -0
  1930. psychopy/tests/data/TestProgress_w128h64_top_right.png +0 -0
  1931. psychopy/tests/data/TestProgress_w64h128_bottom_left.png +0 -0
  1932. psychopy/tests/data/TestProgress_w64h128_bottom_right.png +0 -0
  1933. psychopy/tests/data/TestProgress_w64h128_center_center.png +0 -0
  1934. psychopy/tests/data/TestProgress_w64h128_top_left.png +0 -0
  1935. psychopy/tests/data/TestProgress_w64h128_top_right.png +0 -0
  1936. psychopy/tests/data/TestProgress_w64h64_bottom_left.png +0 -0
  1937. psychopy/tests/data/TestProgress_w64h64_bottom_right.png +0 -0
  1938. psychopy/tests/data/TestProgress_w64h64_center_center.png +0 -0
  1939. psychopy/tests/data/TestProgress_w64h64_top_left.png +0 -0
  1940. psychopy/tests/data/TestProgress_w64h64_top_right.png +0 -0
  1941. psychopy/tests/data/TestROI_w128h128_bottom_left.png +0 -0
  1942. psychopy/tests/data/TestROI_w128h128_bottom_right.png +0 -0
  1943. psychopy/tests/data/TestROI_w128h128_center_center.png +0 -0
  1944. psychopy/tests/data/TestROI_w128h128_top_left.png +0 -0
  1945. psychopy/tests/data/TestROI_w128h128_top_right.png +0 -0
  1946. psychopy/tests/data/TestROI_w128h64_bottom_left.png +0 -0
  1947. psychopy/tests/data/TestROI_w128h64_bottom_right.png +0 -0
  1948. psychopy/tests/data/TestROI_w128h64_center_center.png +0 -0
  1949. psychopy/tests/data/TestROI_w128h64_top_left.png +0 -0
  1950. psychopy/tests/data/TestROI_w128h64_top_right.png +0 -0
  1951. psychopy/tests/data/TestROI_w64h128_bottom_left.png +0 -0
  1952. psychopy/tests/data/TestROI_w64h128_bottom_right.png +0 -0
  1953. psychopy/tests/data/TestROI_w64h128_center_center.png +0 -0
  1954. psychopy/tests/data/TestROI_w64h128_top_left.png +0 -0
  1955. psychopy/tests/data/TestROI_w64h128_top_right.png +0 -0
  1956. psychopy/tests/data/TestROI_w64h64_bottom_left.png +0 -0
  1957. psychopy/tests/data/TestROI_w64h64_bottom_right.png +0 -0
  1958. psychopy/tests/data/TestROI_w64h64_center_center.png +0 -0
  1959. psychopy/tests/data/TestROI_w64h64_top_left.png +0 -0
  1960. psychopy/tests/data/TestROI_w64h64_top_right.png +0 -0
  1961. psychopy/tests/data/TestSession_exp1.png +0 -0
  1962. psychopy/tests/data/TestSession_exp2.png +0 -0
  1963. psychopy/tests/data/TestShape_w128h128_bottom_left.png +0 -0
  1964. psychopy/tests/data/TestShape_w128h128_bottom_right.png +0 -0
  1965. psychopy/tests/data/TestShape_w128h128_center_center.png +0 -0
  1966. psychopy/tests/data/TestShape_w128h128_top_left.png +0 -0
  1967. psychopy/tests/data/TestShape_w128h128_top_right.png +0 -0
  1968. psychopy/tests/data/TestShape_w128h64_bottom_left.png +0 -0
  1969. psychopy/tests/data/TestShape_w128h64_bottom_right.png +0 -0
  1970. psychopy/tests/data/TestShape_w128h64_center_center.png +0 -0
  1971. psychopy/tests/data/TestShape_w128h64_top_left.png +0 -0
  1972. psychopy/tests/data/TestShape_w128h64_top_right.png +0 -0
  1973. psychopy/tests/data/TestShape_w64h128_bottom_left.png +0 -0
  1974. psychopy/tests/data/TestShape_w64h128_bottom_right.png +0 -0
  1975. psychopy/tests/data/TestShape_w64h128_center_center.png +0 -0
  1976. psychopy/tests/data/TestShape_w64h128_top_left.png +0 -0
  1977. psychopy/tests/data/TestShape_w64h128_top_right.png +0 -0
  1978. psychopy/tests/data/TestShape_w64h64_bottom_left.png +0 -0
  1979. psychopy/tests/data/TestShape_w64h64_bottom_right.png +0 -0
  1980. psychopy/tests/data/TestShape_w64h64_center_center.png +0 -0
  1981. psychopy/tests/data/TestShape_w64h64_top_left.png +0 -0
  1982. psychopy/tests/data/TestShape_w64h64_top_right.png +0 -0
  1983. psychopy/tests/data/TestTarget_w128h128_bottom_left.png +0 -0
  1984. psychopy/tests/data/TestTarget_w128h128_bottom_right.png +0 -0
  1985. psychopy/tests/data/TestTarget_w128h128_center_center.png +0 -0
  1986. psychopy/tests/data/TestTarget_w128h128_top_left.png +0 -0
  1987. psychopy/tests/data/TestTarget_w128h128_top_right.png +0 -0
  1988. psychopy/tests/data/TestTarget_w128h64_bottom_left.png +0 -0
  1989. psychopy/tests/data/TestTarget_w128h64_bottom_right.png +0 -0
  1990. psychopy/tests/data/TestTarget_w128h64_center_center.png +0 -0
  1991. psychopy/tests/data/TestTarget_w128h64_top_left.png +0 -0
  1992. psychopy/tests/data/TestTarget_w128h64_top_right.png +0 -0
  1993. psychopy/tests/data/TestTarget_w64h128_bottom_left.png +0 -0
  1994. psychopy/tests/data/TestTarget_w64h128_bottom_right.png +0 -0
  1995. psychopy/tests/data/TestTarget_w64h128_center_center.png +0 -0
  1996. psychopy/tests/data/TestTarget_w64h128_top_left.png +0 -0
  1997. psychopy/tests/data/TestTarget_w64h128_top_right.png +0 -0
  1998. psychopy/tests/data/TestTarget_w64h64_bottom_left.png +0 -0
  1999. psychopy/tests/data/TestTarget_w64h64_bottom_right.png +0 -0
  2000. psychopy/tests/data/TestTarget_w64h64_center_center.png +0 -0
  2001. psychopy/tests/data/TestTarget_w64h64_top_left.png +0 -0
  2002. psychopy/tests/data/TestTarget_w64h64_top_right.png +0 -0
  2003. psychopy/tests/data/TestTextbox_testLetterSpacing_0p6.png +0 -0
  2004. psychopy/tests/data/TestTextbox_testLetterSpacing_0p8.png +0 -0
  2005. psychopy/tests/data/TestTextbox_testLetterSpacing_1.png +0 -0
  2006. psychopy/tests/data/TestTextbox_testLetterSpacing_1p2.png +0 -0
  2007. psychopy/tests/data/TestTextbox_testLetterSpacing_1p4.png +0 -0
  2008. psychopy/tests/data/TestTextbox_testLetterSpacing_1p6.png +0 -0
  2009. psychopy/tests/data/TestTextbox_testLetterSpacing_1p8.png +0 -0
  2010. psychopy/tests/data/TestTextbox_testLetterSpacing_2p0.png +0 -0
  2011. psychopy/tests/data/TestTextbox_testLetterSpacing_None.png +0 -0
  2012. psychopy/tests/data/Test_textbox_testSpeechpoint_-3ovr8_0ovr8.png +0 -0
  2013. psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_-3ovr8.png +0 -0
  2014. psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_3ovr8.png +0 -0
  2015. psychopy/tests/data/Test_textbox_testSpeechpoint_3ovr8_0ovr8.png +0 -0
  2016. psychopy/tests/data/Test_textbox_w128h128_bottom_left.png +0 -0
  2017. psychopy/tests/data/Test_textbox_w128h128_bottom_right.png +0 -0
  2018. psychopy/tests/data/Test_textbox_w128h128_center_center.png +0 -0
  2019. psychopy/tests/data/Test_textbox_w128h128_top_left.png +0 -0
  2020. psychopy/tests/data/Test_textbox_w128h128_top_right.png +0 -0
  2021. psychopy/tests/data/Test_textbox_w128h64_bottom_left.png +0 -0
  2022. psychopy/tests/data/Test_textbox_w128h64_bottom_right.png +0 -0
  2023. psychopy/tests/data/Test_textbox_w128h64_center_center.png +0 -0
  2024. psychopy/tests/data/Test_textbox_w128h64_top_left.png +0 -0
  2025. psychopy/tests/data/Test_textbox_w128h64_top_right.png +0 -0
  2026. psychopy/tests/data/Test_textbox_w64h128_bottom_left.png +0 -0
  2027. psychopy/tests/data/Test_textbox_w64h128_bottom_right.png +0 -0
  2028. psychopy/tests/data/Test_textbox_w64h128_center_center.png +0 -0
  2029. psychopy/tests/data/Test_textbox_w64h128_top_left.png +0 -0
  2030. psychopy/tests/data/Test_textbox_w64h128_top_right.png +0 -0
  2031. psychopy/tests/data/Test_textbox_w64h64_bottom_left.png +0 -0
  2032. psychopy/tests/data/Test_textbox_w64h64_bottom_right.png +0 -0
  2033. psychopy/tests/data/Test_textbox_w64h64_center_center.png +0 -0
  2034. psychopy/tests/data/Test_textbox_w64h64_top_left.png +0 -0
  2035. psychopy/tests/data/Test_textbox_w64h64_top_right.png +0 -0
  2036. psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_left.png +0 -0
  2037. psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_right.png +0 -0
  2038. psychopy/tests/data/Test_uax14_textbox_w128h128_center_center.png +0 -0
  2039. psychopy/tests/data/Test_uax14_textbox_w128h128_top_left.png +0 -0
  2040. psychopy/tests/data/Test_uax14_textbox_w128h128_top_right.png +0 -0
  2041. psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_left.png +0 -0
  2042. psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_right.png +0 -0
  2043. psychopy/tests/data/Test_uax14_textbox_w128h64_center_center.png +0 -0
  2044. psychopy/tests/data/Test_uax14_textbox_w128h64_top_left.png +0 -0
  2045. psychopy/tests/data/Test_uax14_textbox_w128h64_top_right.png +0 -0
  2046. psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_left.png +0 -0
  2047. psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_right.png +0 -0
  2048. psychopy/tests/data/Test_uax14_textbox_w64h128_center_center.png +0 -0
  2049. psychopy/tests/data/Test_uax14_textbox_w64h128_top_left.png +0 -0
  2050. psychopy/tests/data/Test_uax14_textbox_w64h128_top_right.png +0 -0
  2051. psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_left.png +0 -0
  2052. psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_right.png +0 -0
  2053. psychopy/tests/data/Test_uax14_textbox_w64h64_center_center.png +0 -0
  2054. psychopy/tests/data/Test_uax14_textbox_w64h64_top_left.png +0 -0
  2055. psychopy/tests/data/Test_uax14_textbox_w64h64_top_right.png +0 -0
  2056. psychopy/tests/data/TextComponent_disabled.psyexp +63 -0
  2057. psychopy/tests/data/TextComponent_not_disabled.psyexp +63 -0
  2058. psychopy/tests/data/aperture1_deg.png +0 -0
  2059. psychopy/tests/data/aperture1_degFlat.png +0 -0
  2060. psychopy/tests/data/aperture1_degFlatPos.png +0 -0
  2061. psychopy/tests/data/aperture1_norm.png +0 -0
  2062. psychopy/tests/data/aperture1_normHexbackground.png +0 -0
  2063. psychopy/tests/data/aperture1_normNoShade.png +0 -0
  2064. psychopy/tests/data/aperture1_pix.png +0 -0
  2065. psychopy/tests/data/aperture1_stencil.png +0 -0
  2066. psychopy/tests/data/aperture2_deg.png +0 -0
  2067. psychopy/tests/data/aperture2_degFlat.png +0 -0
  2068. psychopy/tests/data/aperture2_degFlatPos.png +0 -0
  2069. psychopy/tests/data/aperture2_norm.png +0 -0
  2070. psychopy/tests/data/aperture2_normHexbackground.png +0 -0
  2071. psychopy/tests/data/aperture2_normNoShade.png +0 -0
  2072. psychopy/tests/data/aperture2_pix.png +0 -0
  2073. psychopy/tests/data/aperture2_stencil.png +0 -0
  2074. psychopy/tests/data/beatandrcos_cm.png +0 -0
  2075. psychopy/tests/data/beatandrcos_deg.png +0 -0
  2076. psychopy/tests/data/beatandrcos_degFlat.png +0 -0
  2077. psychopy/tests/data/beatandrcos_degFlatPos.png +0 -0
  2078. psychopy/tests/data/beatandrcos_height.png +0 -0
  2079. psychopy/tests/data/beatandrcos_norm.png +0 -0
  2080. psychopy/tests/data/beatandrcos_normAddBlend.png +0 -0
  2081. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  2082. psychopy/tests/data/beatandrcos_normHexbackground.png +0 -0
  2083. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  2084. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  2085. psychopy/tests/data/beatandrcos_pix.png +0 -0
  2086. psychopy/tests/data/beatandrcos_stencil.png +0 -0
  2087. psychopy/tests/data/blend_add_cm.png +0 -0
  2088. psychopy/tests/data/blend_add_deg.png +0 -0
  2089. psychopy/tests/data/blend_add_degFlat.png +0 -0
  2090. psychopy/tests/data/blend_add_degFlatPos.png +0 -0
  2091. psychopy/tests/data/blend_add_height.png +0 -0
  2092. psychopy/tests/data/blend_add_norm.png +0 -0
  2093. psychopy/tests/data/blend_add_normAddBlend.png +0 -0
  2094. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  2095. psychopy/tests/data/blend_add_normHexbackground.png +0 -0
  2096. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  2097. psychopy/tests/data/blend_add_normNoShade.png +0 -0
  2098. psychopy/tests/data/blend_add_norm_local.png +0 -0
  2099. psychopy/tests/data/blend_add_pix.png +0 -0
  2100. psychopy/tests/data/blend_add_stencil.png +0 -0
  2101. psychopy/tests/data/broken2020_2_5_resources/broken_resources.psyexp +84 -0
  2102. psychopy/tests/data/broken2020_2_5_resources/psychopy72.png +0 -0
  2103. psychopy/tests/data/bufferimg_gabor_cm.png +0 -0
  2104. psychopy/tests/data/bufferimg_gabor_deg.png +0 -0
  2105. psychopy/tests/data/bufferimg_gabor_degFlat.png +0 -0
  2106. psychopy/tests/data/bufferimg_gabor_degFlatPos.png +0 -0
  2107. psychopy/tests/data/bufferimg_gabor_height.png +0 -0
  2108. psychopy/tests/data/bufferimg_gabor_norm.png +0 -0
  2109. psychopy/tests/data/bufferimg_gabor_normAddBlend.png +0 -0
  2110. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  2111. psychopy/tests/data/bufferimg_gabor_normHexbackground.png +0 -0
  2112. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  2113. psychopy/tests/data/bufferimg_gabor_normNoShade.png +0 -0
  2114. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  2115. psychopy/tests/data/bufferimg_gabor_pix.png +0 -0
  2116. psychopy/tests/data/bufferimg_gabor_stencil.png +0 -0
  2117. psychopy/tests/data/circleHex_cm.png +0 -0
  2118. psychopy/tests/data/circleHex_deg.png +0 -0
  2119. psychopy/tests/data/circleHex_degFlat.png +0 -0
  2120. psychopy/tests/data/circleHex_degFlatPos.png +0 -0
  2121. psychopy/tests/data/circleHex_height.png +0 -0
  2122. psychopy/tests/data/circleHex_norm.png +0 -0
  2123. psychopy/tests/data/circleHex_normAddBlend.png +0 -0
  2124. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  2125. psychopy/tests/data/circleHex_normHexbackground.png +0 -0
  2126. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  2127. psychopy/tests/data/circleHex_normNoShade.png +0 -0
  2128. psychopy/tests/data/circleHex_norm_local.png +0 -0
  2129. psychopy/tests/data/circleHex_pix.png +0 -0
  2130. psychopy/tests/data/circleHex_stencil.png +0 -0
  2131. psychopy/tests/data/corrFullRandom.csv +16 -0
  2132. psychopy/tests/data/corrFullRandom.tsv +6 -0
  2133. psychopy/tests/data/corrFullRandomTH2.csv +16 -0
  2134. psychopy/tests/data/corrMultiKeyExpWide.csv +3 -0
  2135. psychopy/tests/data/corrMultiKeyTrials.csv +8 -0
  2136. psychopy/tests/data/corrMultiKeyTrials.xlsx +0 -0
  2137. psychopy/tests/data/corrRandom.csv +16 -0
  2138. psychopy/tests/data/corrRandom.tsv +6 -0
  2139. psychopy/tests/data/corrRandomTH2.csv +16 -0
  2140. psychopy/tests/data/corrXlsx.xlsx +0 -0
  2141. psychopy/tests/data/correctScript/js/correctCodeComponent.js +181 -0
  2142. psychopy/tests/data/correctScript/js/correctImageComponent.js +204 -0
  2143. psychopy/tests/data/correctScript/js/correctKeyboardComponent.js +225 -0
  2144. psychopy/tests/data/correctScript/js/correctMouseComponent.js +221 -0
  2145. psychopy/tests/data/correctScript/js/correctMovieComponent.js +210 -0
  2146. psychopy/tests/data/correctScript/js/correctPolygonComponent.js +205 -0
  2147. psychopy/tests/data/correctScript/js/correctSliderComponent.js +209 -0
  2148. psychopy/tests/data/correctScript/js/correctSoundComponent.js +205 -0
  2149. psychopy/tests/data/correctScript/js/correctTextComponent.js +207 -0
  2150. psychopy/tests/data/correctScript/python/correctApertureComponent.py +157 -0
  2151. psychopy/tests/data/correctScript/python/correctCodeComponent.py +135 -0
  2152. psychopy/tests/data/correctScript/python/correctDotsComponent.py +161 -0
  2153. psychopy/tests/data/correctScript/python/correctEnvGratingComponent.py +167 -0
  2154. psychopy/tests/data/correctScript/python/correctFormComponent.py +150 -0
  2155. psychopy/tests/data/correctScript/python/correctGratingComponent.py +158 -0
  2156. psychopy/tests/data/correctScript/python/correctImageComponent.py +160 -0
  2157. psychopy/tests/data/correctScript/python/correctJoyButtonsComponent.py +204 -0
  2158. psychopy/tests/data/correctScript/python/correctJoystickComponent.py +214 -0
  2159. psychopy/tests/data/correctScript/python/correctKeyboardComponent.py +169 -0
  2160. psychopy/tests/data/correctScript/python/correctMicrophoneComponent.py +163 -0
  2161. psychopy/tests/data/correctScript/python/correctMouseComponent.py +174 -0
  2162. psychopy/tests/data/correctScript/python/correctMovieComponent.py +160 -0
  2163. psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +169 -0
  2164. psychopy/tests/data/correctScript/python/correctParallelOutComponent.py +156 -0
  2165. psychopy/tests/data/correctScript/python/correctPatchComponent.py +159 -0
  2166. psychopy/tests/data/correctScript/python/correctPolygonComponent.py +159 -0
  2167. psychopy/tests/data/correctScript/python/correctQmixPumpComponent.py +174 -0
  2168. psychopy/tests/data/correctScript/python/correctRatingScaleComponent.py +152 -0
  2169. psychopy/tests/data/correctScript/python/correctSliderComponent.py +159 -0
  2170. psychopy/tests/data/correctScript/python/correctSoundComponent.py +157 -0
  2171. psychopy/tests/data/correctScript/python/correctStaticComponent.py +176 -0
  2172. psychopy/tests/data/correctScript/python/correctTextComponent.py +159 -0
  2173. psychopy/tests/data/correctScript/python/correctVariableComponent.py +139 -0
  2174. psychopy/tests/data/correctScript/python/correctcedrusButtonBoxComponent.py +199 -0
  2175. psychopy/tests/data/correctScript/python/correctioLabsButtonBoxComponent.py +187 -0
  2176. psychopy/tests/data/dataTest.xlsx +0 -0
  2177. psychopy/tests/data/dots_cm.png +0 -0
  2178. psychopy/tests/data/dots_deg.png +0 -0
  2179. psychopy/tests/data/dots_degFlat.png +0 -0
  2180. psychopy/tests/data/dots_degFlatPos.png +0 -0
  2181. psychopy/tests/data/dots_height.png +0 -0
  2182. psychopy/tests/data/dots_norm.png +0 -0
  2183. psychopy/tests/data/dots_normAddBlend.png +0 -0
  2184. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  2185. psychopy/tests/data/dots_normHexbackground.png +0 -0
  2186. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  2187. psychopy/tests/data/dots_normNoShade.png +0 -0
  2188. psychopy/tests/data/dots_norm_local.png +0 -0
  2189. psychopy/tests/data/dots_pix.png +0 -0
  2190. psychopy/tests/data/dots_stencil.png +0 -0
  2191. psychopy/tests/data/elarray1_cm.png +0 -0
  2192. psychopy/tests/data/elarray1_deg.png +0 -0
  2193. psychopy/tests/data/elarray1_degFlat.png +0 -0
  2194. psychopy/tests/data/elarray1_degFlatPos.png +0 -0
  2195. psychopy/tests/data/elarray1_height.png +0 -0
  2196. psychopy/tests/data/elarray1_norm.png +0 -0
  2197. psychopy/tests/data/elarray1_normAddBlend.png +0 -0
  2198. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  2199. psychopy/tests/data/elarray1_normHexbackground.png +0 -0
  2200. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  2201. psychopy/tests/data/elarray1_norm_local.png +0 -0
  2202. psychopy/tests/data/elarray1_pix.png +0 -0
  2203. psychopy/tests/data/elarray1_stencil.png +0 -0
  2204. psychopy/tests/data/envelopeandrcos_cm.png +0 -0
  2205. psychopy/tests/data/envelopeandrcos_deg.png +0 -0
  2206. psychopy/tests/data/envelopeandrcos_degFlat.png +0 -0
  2207. psychopy/tests/data/envelopeandrcos_degFlatPos.png +0 -0
  2208. psychopy/tests/data/envelopeandrcos_height.png +0 -0
  2209. psychopy/tests/data/envelopeandrcos_norm.png +0 -0
  2210. psychopy/tests/data/envelopeandrcos_normAddBlend.png +0 -0
  2211. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  2212. psychopy/tests/data/envelopeandrcos_normHexbackground.png +0 -0
  2213. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  2214. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  2215. psychopy/tests/data/envelopeandrcos_pix.png +0 -0
  2216. psychopy/tests/data/envelopeandrcos_stencil.png +0 -0
  2217. psychopy/tests/data/envelopepowerandrcos_cm.png +0 -0
  2218. psychopy/tests/data/envelopepowerandrcos_deg.png +0 -0
  2219. psychopy/tests/data/envelopepowerandrcos_degFlat.png +0 -0
  2220. psychopy/tests/data/envelopepowerandrcos_degFlatPos.png +0 -0
  2221. psychopy/tests/data/envelopepowerandrcos_height.png +0 -0
  2222. psychopy/tests/data/envelopepowerandrcos_norm.png +0 -0
  2223. psychopy/tests/data/envelopepowerandrcos_normAddBlend.png +0 -0
  2224. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  2225. psychopy/tests/data/envelopepowerandrcos_normHexbackground.png +0 -0
  2226. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  2227. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  2228. psychopy/tests/data/envelopepowerandrcos_pix.png +0 -0
  2229. psychopy/tests/data/envelopepowerandrcos_stencil.png +0 -0
  2230. psychopy/tests/data/filltext.png +0 -0
  2231. psychopy/tests/data/form_font_demographics.png +0 -0
  2232. psychopy/tests/data/form_font_demographics.xlsx +0 -0
  2233. psychopy/tests/data/form_font_languages.png +0 -0
  2234. psychopy/tests/data/form_font_languages.xlsx +0 -0
  2235. psychopy/tests/data/form_font_nonstandard.png +0 -0
  2236. psychopy/tests/data/futureParams.psyexp +150 -0
  2237. psychopy/tests/data/gabor1_cm.png +0 -0
  2238. psychopy/tests/data/gabor1_deg.png +0 -0
  2239. psychopy/tests/data/gabor1_degFlat.png +0 -0
  2240. psychopy/tests/data/gabor1_degFlatPos.png +0 -0
  2241. psychopy/tests/data/gabor1_height.png +0 -0
  2242. psychopy/tests/data/gabor1_norm.png +0 -0
  2243. psychopy/tests/data/gabor1_normAddBlend.png +0 -0
  2244. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  2245. psychopy/tests/data/gabor1_normHexbackground.png +0 -0
  2246. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  2247. psychopy/tests/data/gabor1_normNoShade.png +0 -0
  2248. psychopy/tests/data/gabor1_norm_local.png +0 -0
  2249. psychopy/tests/data/gabor1_pix.png +0 -0
  2250. psychopy/tests/data/gabor1_stencil.png +0 -0
  2251. psychopy/tests/data/gabor2_cm.png +0 -0
  2252. psychopy/tests/data/gabor2_deg.png +0 -0
  2253. psychopy/tests/data/gabor2_degFlat.png +0 -0
  2254. psychopy/tests/data/gabor2_degFlatPos.png +0 -0
  2255. psychopy/tests/data/gabor2_height.png +0 -0
  2256. psychopy/tests/data/gabor2_norm.png +0 -0
  2257. psychopy/tests/data/gabor2_normAddBlend.png +0 -0
  2258. psychopy/tests/data/gabor2_normHexbackground.png +0 -0
  2259. psychopy/tests/data/gabor2_normNoShade.png +0 -0
  2260. psychopy/tests/data/gabor2_pix.png +0 -0
  2261. psychopy/tests/data/gabor2_stencil.png +0 -0
  2262. psychopy/tests/data/ghost_stroop.psyexp +131 -0
  2263. psychopy/tests/data/ghost_trialTypes.xlsx +0 -0
  2264. psychopy/tests/data/green_48000.flac.dist +0 -0
  2265. psychopy/tests/data/greyscale.jpg +0 -0
  2266. psychopy/tests/data/greyscale2.png +0 -0
  2267. psychopy/tests/data/greyscale2_cm.png +0 -0
  2268. psychopy/tests/data/greyscale2_deg.png +0 -0
  2269. psychopy/tests/data/greyscale2_degFlat.png +0 -0
  2270. psychopy/tests/data/greyscale2_degFlatPos.png +0 -0
  2271. psychopy/tests/data/greyscale2_height.png +0 -0
  2272. psychopy/tests/data/greyscale2_norm.png +0 -0
  2273. psychopy/tests/data/greyscale2_normAddBlend.png +0 -0
  2274. psychopy/tests/data/greyscale2_normHexbackground.png +0 -0
  2275. psychopy/tests/data/greyscale2_normNoShade.png +0 -0
  2276. psychopy/tests/data/greyscale2_pix.png +0 -0
  2277. psychopy/tests/data/greyscale2_stencil.png +0 -0
  2278. psychopy/tests/data/greyscaleLowContr_cm.png +0 -0
  2279. psychopy/tests/data/greyscaleLowContr_deg.png +0 -0
  2280. psychopy/tests/data/greyscaleLowContr_degFlat.png +0 -0
  2281. psychopy/tests/data/greyscaleLowContr_degFlatPos.png +0 -0
  2282. psychopy/tests/data/greyscaleLowContr_height.png +0 -0
  2283. psychopy/tests/data/greyscaleLowContr_norm.png +0 -0
  2284. psychopy/tests/data/greyscaleLowContr_normAddBlend.png +0 -0
  2285. psychopy/tests/data/greyscaleLowContr_normHexbackground.png +0 -0
  2286. psychopy/tests/data/greyscaleLowContr_normNoShade.png +0 -0
  2287. psychopy/tests/data/greyscaleLowContr_pix.png +0 -0
  2288. psychopy/tests/data/greyscaleLowContr_stencil.png +0 -0
  2289. psychopy/tests/data/greyscale_cm.png +0 -0
  2290. psychopy/tests/data/greyscale_deg.png +0 -0
  2291. psychopy/tests/data/greyscale_degFlat.png +0 -0
  2292. psychopy/tests/data/greyscale_degFlatPos.png +0 -0
  2293. psychopy/tests/data/greyscale_height.png +0 -0
  2294. psychopy/tests/data/greyscale_norm.png +0 -0
  2295. psychopy/tests/data/greyscale_normAddBlend.png +0 -0
  2296. psychopy/tests/data/greyscale_normHexbackground.png +0 -0
  2297. psychopy/tests/data/greyscale_normNoShade.png +0 -0
  2298. psychopy/tests/data/greyscale_pix.png +0 -0
  2299. psychopy/tests/data/greyscale_stencil.png +0 -0
  2300. psychopy/tests/data/imageAndGauss_cm.png +0 -0
  2301. psychopy/tests/data/imageAndGauss_deg.png +0 -0
  2302. psychopy/tests/data/imageAndGauss_degFlat.png +0 -0
  2303. psychopy/tests/data/imageAndGauss_degFlatPos.png +0 -0
  2304. psychopy/tests/data/imageAndGauss_height.png +0 -0
  2305. psychopy/tests/data/imageAndGauss_norm.png +0 -0
  2306. psychopy/tests/data/imageAndGauss_normAddBlend.png +0 -0
  2307. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  2308. psychopy/tests/data/imageAndGauss_normHexbackground.png +0 -0
  2309. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  2310. psychopy/tests/data/imageAndGauss_normNoShade.png +0 -0
  2311. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  2312. psychopy/tests/data/imageAndGauss_pix.png +0 -0
  2313. psychopy/tests/data/imageAndGauss_stencil.png +0 -0
  2314. psychopy/tests/data/movFrame1_cm.png +0 -0
  2315. psychopy/tests/data/movFrame1_deg.png +0 -0
  2316. psychopy/tests/data/movFrame1_degFlat.png +0 -0
  2317. psychopy/tests/data/movFrame1_degFlatPos.png +0 -0
  2318. psychopy/tests/data/movFrame1_height.png +0 -0
  2319. psychopy/tests/data/movFrame1_norm.png +0 -0
  2320. psychopy/tests/data/movFrame1_normAddBlend.png +0 -0
  2321. psychopy/tests/data/movFrame1_normHexbackground.png +0 -0
  2322. psychopy/tests/data/movFrame1_normNoShade.png +0 -0
  2323. psychopy/tests/data/movFrame1_pix.png +0 -0
  2324. psychopy/tests/data/movFrame1_stencil.png +0 -0
  2325. psychopy/tests/data/multiKeypressExperiment.psydat +357 -0
  2326. psychopy/tests/data/multiKeypressTrialhandler.psydat +252 -0
  2327. psychopy/tests/data/multiStairConds.xlsx +0 -0
  2328. psychopy/tests/data/multiStairQuestPlus.xlsx +0 -0
  2329. psychopy/tests/data/newstyle.psydat +6155 -0
  2330. psychopy/tests/data/noiseAndRcos_cm.png +0 -0
  2331. psychopy/tests/data/noiseAndRcos_deg.png +0 -0
  2332. psychopy/tests/data/noiseAndRcos_degFlat.png +0 -0
  2333. psychopy/tests/data/noiseAndRcos_degFlatPos.png +0 -0
  2334. psychopy/tests/data/noiseAndRcos_height.png +0 -0
  2335. psychopy/tests/data/noiseAndRcos_norm.png +0 -0
  2336. psychopy/tests/data/noiseAndRcos_normAddBlend.png +0 -0
  2337. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  2338. psychopy/tests/data/noiseAndRcos_normHexbackground.png +0 -0
  2339. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  2340. psychopy/tests/data/noiseAndRcos_normNoShade.png +0 -0
  2341. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  2342. psychopy/tests/data/noiseAndRcos_pix.png +0 -0
  2343. psychopy/tests/data/noiseAndRcos_stencil.png +0 -0
  2344. psychopy/tests/data/noiseFiltersAndRcos_cm.png +0 -0
  2345. psychopy/tests/data/noiseFiltersAndRcos_deg.png +0 -0
  2346. psychopy/tests/data/noiseFiltersAndRcos_degFlat.png +0 -0
  2347. psychopy/tests/data/noiseFiltersAndRcos_degFlatPos.png +0 -0
  2348. psychopy/tests/data/noiseFiltersAndRcos_height.png +0 -0
  2349. psychopy/tests/data/noiseFiltersAndRcos_norm.png +0 -0
  2350. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend.png +0 -0
  2351. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  2352. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground.png +0 -0
  2353. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  2354. psychopy/tests/data/noiseFiltersAndRcos_normNoShade.png +0 -0
  2355. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  2356. psychopy/tests/data/noiseFiltersAndRcos_pix.png +0 -0
  2357. psychopy/tests/data/noiseFiltersAndRcos_stencil.png +0 -0
  2358. psychopy/tests/data/numpyImage_cm.png +0 -0
  2359. psychopy/tests/data/numpyImage_deg.png +0 -0
  2360. psychopy/tests/data/numpyImage_degFlat.png +0 -0
  2361. psychopy/tests/data/numpyImage_degFlatPos.png +0 -0
  2362. psychopy/tests/data/numpyImage_height.png +0 -0
  2363. psychopy/tests/data/numpyImage_norm.png +0 -0
  2364. psychopy/tests/data/numpyImage_normAddBlend.png +0 -0
  2365. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  2366. psychopy/tests/data/numpyImage_normHexbackground.png +0 -0
  2367. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  2368. psychopy/tests/data/numpyImage_normNoShade.png +0 -0
  2369. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  2370. psychopy/tests/data/numpyImage_pix.png +0 -0
  2371. psychopy/tests/data/numpyImage_stencil.png +0 -0
  2372. psychopy/tests/data/numpyLowContr_cm.png +0 -0
  2373. psychopy/tests/data/numpyLowContr_deg.png +0 -0
  2374. psychopy/tests/data/numpyLowContr_degFlat.png +0 -0
  2375. psychopy/tests/data/numpyLowContr_degFlatPos.png +0 -0
  2376. psychopy/tests/data/numpyLowContr_height.png +0 -0
  2377. psychopy/tests/data/numpyLowContr_norm.png +0 -0
  2378. psychopy/tests/data/numpyLowContr_normAddBlend.png +0 -0
  2379. psychopy/tests/data/numpyLowContr_normHexbackground.png +0 -0
  2380. psychopy/tests/data/numpyLowContr_normNoShade.png +0 -0
  2381. psychopy/tests/data/numpyLowContr_pix.png +0 -0
  2382. psychopy/tests/data/numpyLowContr_stencil.png +0 -0
  2383. psychopy/tests/data/oldstyle.psydat +1534 -0
  2384. psychopy/tests/data/oldstyle_stair.psydat +263 -0
  2385. psychopy/tests/data/ratingscale1_cm.png +0 -0
  2386. psychopy/tests/data/ratingscale1_deg.png +0 -0
  2387. psychopy/tests/data/ratingscale1_degFlat.png +0 -0
  2388. psychopy/tests/data/ratingscale1_degFlatPos.png +0 -0
  2389. psychopy/tests/data/ratingscale1_height.png +0 -0
  2390. psychopy/tests/data/ratingscale1_norm.png +0 -0
  2391. psychopy/tests/data/ratingscale1_normAddBlend.png +0 -0
  2392. psychopy/tests/data/ratingscale1_normHexbackground.png +0 -0
  2393. psychopy/tests/data/ratingscale1_normNoShade.png +0 -0
  2394. psychopy/tests/data/ratingscale1_pix.png +0 -0
  2395. psychopy/tests/data/ratingscale1_stencil.png +0 -0
  2396. psychopy/tests/data/red_16000.flac.dist +0 -0
  2397. psychopy/tests/data/retroListParam.psyexp +82 -0
  2398. psychopy/tests/data/right_to_left_unidcode.xlsx +0 -0
  2399. psychopy/tests/data/sample.meshwarp.data +11522 -0
  2400. psychopy/tests/data/shape2_1_cm.png +0 -0
  2401. psychopy/tests/data/shape2_1_deg.png +0 -0
  2402. psychopy/tests/data/shape2_1_degFlat.png +0 -0
  2403. psychopy/tests/data/shape2_1_degFlatPos.png +0 -0
  2404. psychopy/tests/data/shape2_1_height.png +0 -0
  2405. psychopy/tests/data/shape2_1_norm.png +0 -0
  2406. psychopy/tests/data/shape2_1_normAddBlend.png +0 -0
  2407. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  2408. psychopy/tests/data/shape2_1_normHexbackground.png +0 -0
  2409. psychopy/tests/data/shape2_1_normNoShade.png +0 -0
  2410. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  2411. psychopy/tests/data/shape2_1_pix.png +0 -0
  2412. psychopy/tests/data/shape2_1_stencil.png +0 -0
  2413. psychopy/tests/data/shape2_2_cm.png +0 -0
  2414. psychopy/tests/data/shape2_2_deg.png +0 -0
  2415. psychopy/tests/data/shape2_2_degFlat.png +0 -0
  2416. psychopy/tests/data/shape2_2_degFlatPos.png +0 -0
  2417. psychopy/tests/data/shape2_2_height.png +0 -0
  2418. psychopy/tests/data/shape2_2_norm.png +0 -0
  2419. psychopy/tests/data/shape2_2_normAddBlend.png +0 -0
  2420. psychopy/tests/data/shape2_2_normHexbackground.png +0 -0
  2421. psychopy/tests/data/shape2_2_normNoShade.png +0 -0
  2422. psychopy/tests/data/shape2_2_pix.png +0 -0
  2423. psychopy/tests/data/shape2_2_stencil.png +0 -0
  2424. psychopy/tests/data/simpleimage1_cm.png +0 -0
  2425. psychopy/tests/data/simpleimage1_deg.png +0 -0
  2426. psychopy/tests/data/simpleimage1_degFlat.png +0 -0
  2427. psychopy/tests/data/simpleimage1_degFlatPos.png +0 -0
  2428. psychopy/tests/data/simpleimage1_height.png +0 -0
  2429. psychopy/tests/data/simpleimage1_norm.png +0 -0
  2430. psychopy/tests/data/simpleimage1_normAddBlend.png +0 -0
  2431. psychopy/tests/data/simpleimage1_normHexbackground.png +0 -0
  2432. psychopy/tests/data/simpleimage1_normNoShade.png +0 -0
  2433. psychopy/tests/data/simpleimage1_pix.png +0 -0
  2434. psychopy/tests/data/simpleimage1_stencil.png +0 -0
  2435. psychopy/tests/data/test001EntryImporting.psyexp +66 -0
  2436. psychopy/tests/data/testMovie.mp4 +0 -0
  2437. psychopy/tests/data/test_circle_radius_.1height.png +0 -0
  2438. psychopy/tests/data/test_circle_radius_.2height.png +0 -0
  2439. psychopy/tests/data/test_circle_radius_10pix.png +0 -0
  2440. psychopy/tests/data/test_circle_radius_20pix.png +0 -0
  2441. psychopy/tests/data/test_form_combinations_choice_bigItem.png +0 -0
  2442. psychopy/tests/data/test_form_combinations_choice_bigItemOverflow.png +0 -0
  2443. psychopy/tests/data/test_form_combinations_choice_bigResp.png +0 -0
  2444. psychopy/tests/data/test_form_combinations_choice_bigRespOverflow.png +0 -0
  2445. psychopy/tests/data/test_form_combinations_description_bigItem.png +0 -0
  2446. psychopy/tests/data/test_form_combinations_description_bigItemOverflow.png +0 -0
  2447. psychopy/tests/data/test_form_combinations_description_bigResp.png +0 -0
  2448. psychopy/tests/data/test_form_combinations_description_bigRespOverflow.png +0 -0
  2449. psychopy/tests/data/test_form_combinations_free text_bigItem.png +0 -0
  2450. psychopy/tests/data/test_form_combinations_free text_bigItemOverflow.png +0 -0
  2451. psychopy/tests/data/test_form_combinations_free text_bigResp.png +0 -0
  2452. psychopy/tests/data/test_form_combinations_free text_bigRespOverflow.png +0 -0
  2453. psychopy/tests/data/test_form_combinations_heading_bigItem.png +0 -0
  2454. psychopy/tests/data/test_form_combinations_heading_bigItemOverflow.png +0 -0
  2455. psychopy/tests/data/test_form_combinations_heading_bigResp.png +0 -0
  2456. psychopy/tests/data/test_form_combinations_heading_bigRespOverflow.png +0 -0
  2457. psychopy/tests/data/test_form_combinations_radio_bigItem.png +0 -0
  2458. psychopy/tests/data/test_form_combinations_radio_bigItemOverflow.png +0 -0
  2459. psychopy/tests/data/test_form_combinations_radio_bigResp.png +0 -0
  2460. psychopy/tests/data/test_form_combinations_radio_bigRespOverflow.png +0 -0
  2461. psychopy/tests/data/test_form_combinations_rating_bigItem.png +0 -0
  2462. psychopy/tests/data/test_form_combinations_rating_bigItemOverflow.png +0 -0
  2463. psychopy/tests/data/test_form_combinations_rating_bigResp.png +0 -0
  2464. psychopy/tests/data/test_form_combinations_rating_bigRespOverflow.png +0 -0
  2465. psychopy/tests/data/test_form_combinations_slider_bigItem.png +0 -0
  2466. psychopy/tests/data/test_form_combinations_slider_bigItemOverflow.png +0 -0
  2467. psychopy/tests/data/test_form_combinations_slider_bigResp.png +0 -0
  2468. psychopy/tests/data/test_form_combinations_slider_bigRespOverflow.png +0 -0
  2469. psychopy/tests/data/test_get_resources/blue.png +0 -0
  2470. psychopy/tests/data/test_get_resources/groupA.csv +3 -0
  2471. psychopy/tests/data/test_get_resources/groupB.csv +3 -0
  2472. psychopy/tests/data/test_get_resources/groups.csv +3 -0
  2473. psychopy/tests/data/test_get_resources/handledbyrm_constrloop.psyexp +143 -0
  2474. psychopy/tests/data/test_get_resources/handledbyrm_noloop.psyexp +114 -0
  2475. psychopy/tests/data/test_get_resources/handledbyrm_recurloop.psyexp +138 -0
  2476. psychopy/tests/data/test_get_resources/handledbyrm_strloop.psyexp +126 -0
  2477. psychopy/tests/data/test_get_resources/handledbystatic_constrloop.psyexp +141 -0
  2478. psychopy/tests/data/test_get_resources/handledbystatic_noloop.psyexp +112 -0
  2479. psychopy/tests/data/test_get_resources/handledbystatic_recurloop.psyexp +136 -0
  2480. psychopy/tests/data/test_get_resources/handledbystatic_strloop.psyexp +124 -0
  2481. psychopy/tests/data/test_get_resources/unhandled_constrloop.psyexp +128 -0
  2482. psychopy/tests/data/test_get_resources/unhandled_noloop.psyexp +99 -0
  2483. psychopy/tests/data/test_get_resources/unhandled_recurloop.psyexp +123 -0
  2484. psychopy/tests/data/test_get_resources/unhandled_strloop.psyexp +111 -0
  2485. psychopy/tests/data/test_get_resources/white.png +0 -0
  2486. psychopy/tests/data/test_get_resources/yellow.png +0 -0
  2487. psychopy/tests/data/test_image_aspect_default_None.png +0 -0
  2488. psychopy/tests/data/test_image_aspect_default_xFull_yNone.png +0 -0
  2489. psychopy/tests/data/test_image_aspect_default_xNone_yFull.png +0 -0
  2490. psychopy/tests/data/test_image_aspect_default_xNone_yNone.png +0 -0
  2491. psychopy/tests/data/test_image_flip_anchor_horiz.png +0 -0
  2492. psychopy/tests/data/test_image_flip_anchor_vert.png +0 -0
  2493. psychopy/tests/data/test_loops/testLoopsBlocks.psyexp +161 -0
  2494. psychopy/tests/data/test_loops/testStaircase.psyexp +105 -0
  2495. psychopy/tests/data/test_loops/test_current_loop_attr.psyexp +185 -0
  2496. psychopy/tests/data/test_panorama/panoramaTestImage.png +0 -0
  2497. psychopy/tests/data/test_panorama/panoramaTestImage.svg +1 -0
  2498. psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_-0.3.png +0 -0
  2499. psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_0.3.png +0 -0
  2500. psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_-0.3.png +0 -0
  2501. psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_0.3.png +0 -0
  2502. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_-1.0.png +0 -0
  2503. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_1.0.png +0 -0
  2504. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_-0.3.png +0 -0
  2505. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_0.3.png +0 -0
  2506. psychopy/tests/data/test_resources.psyexp +491 -0
  2507. psychopy/tests/data/test_session/outside_root/externalExp.psyexp +116 -0
  2508. psychopy/tests/data/test_session/root/annotation/annotation.psyexp +161 -0
  2509. psychopy/tests/data/test_session/root/error/error.psyexp +93 -0
  2510. psychopy/tests/data/test_session/root/exp1/exp1.psyexp +133 -0
  2511. psychopy/tests/data/test_session/root/exp2/exp2.psyexp +133 -0
  2512. psychopy/tests/data/test_session/root/frameRate/frameRate.psyexp +114 -0
  2513. psychopy/tests/data/test_session/root/invUseVersion/invUseVersion.psyexp +133 -0
  2514. psychopy/tests/data/test_session/root/testClockFormat/testClockFormat.psyexp +122 -0
  2515. psychopy/tests/data/test_session/root/testCtrls/testCtrls.psyexp +115 -0
  2516. psychopy/tests/data/test_session/root/testEditExpInfo/testEditExpInfo.psyexp +135 -0
  2517. psychopy/tests/data/test_session/root/testNamedButtonBox/testNamedButtonBox.psyexp +145 -0
  2518. psychopy/tests/data/test_slider_horiz_accute_horiz.png +0 -0
  2519. psychopy/tests/data/test_slider_horiz_accute_vert.png +0 -0
  2520. psychopy/tests/data/test_slider_horiz_horiz.png +0 -0
  2521. psychopy/tests/data/test_slider_horiz_obtuse_horiz.png +0 -0
  2522. psychopy/tests/data/test_slider_horiz_obtuse_vert.png +0 -0
  2523. psychopy/tests/data/test_slider_horiz_vert.png +0 -0
  2524. psychopy/tests/data/test_slider_ticklabelloc_blanks.png +0 -0
  2525. psychopy/tests/data/test_slider_ticklabelloc_clustered.png +0 -0
  2526. psychopy/tests/data/test_slider_ticklabelloc_morelabels.png +0 -0
  2527. psychopy/tests/data/test_slider_ticklabelloc_morelabelsclustered.png +0 -0
  2528. psychopy/tests/data/test_slider_ticklabelloc_moreticks.png +0 -0
  2529. psychopy/tests/data/test_slider_ticklabelloc_moreticksclustered.png +0 -0
  2530. psychopy/tests/data/test_slider_ticklabelloc_nolabels.png +0 -0
  2531. psychopy/tests/data/test_slider_ticklabelloc_noticks.png +0 -0
  2532. psychopy/tests/data/test_slider_ticklabelloc_simple.png +0 -0
  2533. psychopy/tests/data/test_slider_triangle_horiz_False_flip_False.png +0 -0
  2534. psychopy/tests/data/test_slider_triangle_horiz_False_flip_True.png +0 -0
  2535. psychopy/tests/data/test_slider_triangle_horiz_True_flip_False.png +0 -0
  2536. psychopy/tests/data/test_slider_triangle_horiz_True_flip_True.png +0 -0
  2537. psychopy/tests/data/test_static_component_script.psyexp +76 -0
  2538. psychopy/tests/data/test_win_bg_large_256_default.png +0 -0
  2539. psychopy/tests/data/test_win_bg_large_500_default.png +0 -0
  2540. psychopy/tests/data/test_win_bg_small_200_default.png +0 -0
  2541. psychopy/tests/data/test_win_bg_small_256_default.png +0 -0
  2542. psychopy/tests/data/test_win_bg_tall_200_default.png +0 -0
  2543. psychopy/tests/data/test_win_bg_tall_256_default.png +0 -0
  2544. psychopy/tests/data/test_win_bg_tall_500_default.png +0 -0
  2545. psychopy/tests/data/test_win_bg_tall_fill_default.png +0 -0
  2546. psychopy/tests/data/test_win_bg_wide_200_default.png +0 -0
  2547. psychopy/tests/data/test_win_bg_wide_256_default.png +0 -0
  2548. psychopy/tests/data/test_win_bg_wide_500_default.png +0 -0
  2549. psychopy/tests/data/test_win_bg_wide_fill_default.png +0 -0
  2550. psychopy/tests/data/test_win_bgcolor_blue.png +0 -0
  2551. psychopy/tests/data/test_win_bgcolor_green.png +0 -0
  2552. psychopy/tests/data/test_win_bgcolor_red.png +0 -0
  2553. psychopy/tests/data/testimage.jpg +0 -0
  2554. psychopy/tests/data/testimagegray.jpg +0 -0
  2555. psychopy/tests/data/testpixels.png +0 -0
  2556. psychopy/tests/data/testwedges.png +0 -0
  2557. psychopy/tests/data/text1_cm.png +0 -0
  2558. psychopy/tests/data/text1_deg.png +0 -0
  2559. psychopy/tests/data/text1_degFlat.png +0 -0
  2560. psychopy/tests/data/text1_degFlatPos.png +0 -0
  2561. psychopy/tests/data/text1_height.png +0 -0
  2562. psychopy/tests/data/text1_norm.png +0 -0
  2563. psychopy/tests/data/text1_normAddBlend.png +0 -0
  2564. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  2565. psychopy/tests/data/text1_normHexbackground.png +0 -0
  2566. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  2567. psychopy/tests/data/text1_normNoShade.png +0 -0
  2568. psychopy/tests/data/text1_norm_local.png +0 -0
  2569. psychopy/tests/data/text1_pix.png +0 -0
  2570. psychopy/tests/data/text1_stencil.png +0 -0
  2571. psychopy/tests/data/text2_cm.png +0 -0
  2572. psychopy/tests/data/text2_deg.png +0 -0
  2573. psychopy/tests/data/text2_degFlat.png +0 -0
  2574. psychopy/tests/data/text2_degFlatPos.png +0 -0
  2575. psychopy/tests/data/text2_height.png +0 -0
  2576. psychopy/tests/data/text2_norm.png +0 -0
  2577. psychopy/tests/data/text2_normNoShade.png +0 -0
  2578. psychopy/tests/data/text2_pix.png +0 -0
  2579. psychopy/tests/data/text2_stencil.png +0 -0
  2580. psychopy/tests/data/textbox_charcolors_default_roygbiv.png +0 -0
  2581. psychopy/tests/data/textbox_charcolors_default_white_hello_black_there.png +0 -0
  2582. psychopy/tests/data/textbox_default_align_bottom_center.png +0 -0
  2583. psychopy/tests/data/textbox_default_align_bottom_left.png +0 -0
  2584. psychopy/tests/data/textbox_default_align_bottom_right.png +0 -0
  2585. psychopy/tests/data/textbox_default_align_center.png +0 -0
  2586. psychopy/tests/data/textbox_default_align_center_center.png +0 -0
  2587. psychopy/tests/data/textbox_default_align_center_left.png +0 -0
  2588. psychopy/tests/data/textbox_default_align_center_right.png +0 -0
  2589. psychopy/tests/data/textbox_default_align_centre.png +0 -0
  2590. psychopy/tests/data/textbox_default_align_centre_centre.png +0 -0
  2591. psychopy/tests/data/textbox_default_align_more_than_two_words.png +0 -0
  2592. psychopy/tests/data/textbox_default_align_someword.png +0 -0
  2593. psychopy/tests/data/textbox_default_align_top_center.png +0 -0
  2594. psychopy/tests/data/textbox_default_align_top_left.png +0 -0
  2595. psychopy/tests/data/textbox_default_align_top_right.png +0 -0
  2596. psychopy/tests/data/textbox_default_colors_WOB.png +0 -0
  2597. psychopy/tests/data/textbox_default_colors_exemplar1.png +0 -0
  2598. psychopy/tests/data/textbox_default_colors_exemplar2.png +0 -0
  2599. psychopy/tests/data/textbox_default_colors_exemplar3.png +0 -0
  2600. psychopy/tests/data/textbox_default_colors_tyke1.png +0 -0
  2601. psychopy/tests/data/textbox_default_colors_tyke2.png +0 -0
  2602. psychopy/tests/data/textbox_default_colors_tyke3.png +0 -0
  2603. psychopy/tests/data/textbox_default_cutoff_top.png +0 -0
  2604. psychopy/tests/data/textbox_default_exemplar_1.png +0 -0
  2605. psychopy/tests/data/textbox_default_exemplar_2.png +0 -0
  2606. psychopy/tests/data/textbox_default_exemplar_3.png +0 -0
  2607. psychopy/tests/data/textbox_default_exemplar_4.png +0 -0
  2608. psychopy/tests/data/textbox_default_tyke_1.png +0 -0
  2609. psychopy/tests/data/textbox_default_tyke_2.png +0 -0
  2610. psychopy/tests/data/textbox_typing_blank.png +0 -0
  2611. psychopy/tests/data/textbox_typing_longKoeran.png +0 -0
  2612. psychopy/tests/data/textbox_typing_longWord.png +0 -0
  2613. psychopy/tests/data/textbox_typing_navDel.png +0 -0
  2614. psychopy/tests/data/textbox_typing_navLR.png +0 -0
  2615. psychopy/tests/data/textbox_typing_newline.png +0 -0
  2616. psychopy/tests/data/textbox_typing_pangram.png +0 -0
  2617. psychopy/tests/data/textbox_uax14_align_bottom_center.png +0 -0
  2618. psychopy/tests/data/textbox_uax14_align_bottom_left.png +0 -0
  2619. psychopy/tests/data/textbox_uax14_align_bottom_right.png +0 -0
  2620. psychopy/tests/data/textbox_uax14_align_center.png +0 -0
  2621. psychopy/tests/data/textbox_uax14_align_center_center.png +0 -0
  2622. psychopy/tests/data/textbox_uax14_align_center_left.png +0 -0
  2623. psychopy/tests/data/textbox_uax14_align_center_right.png +0 -0
  2624. psychopy/tests/data/textbox_uax14_align_centre.png +0 -0
  2625. psychopy/tests/data/textbox_uax14_align_centre_centre.png +0 -0
  2626. psychopy/tests/data/textbox_uax14_align_more_than_two_words.png +0 -0
  2627. psychopy/tests/data/textbox_uax14_align_someword.png +0 -0
  2628. psychopy/tests/data/textbox_uax14_align_top_center.png +0 -0
  2629. psychopy/tests/data/textbox_uax14_align_top_left.png +0 -0
  2630. psychopy/tests/data/textbox_uax14_align_top_right.png +0 -0
  2631. psychopy/tests/data/textbox_uax14_colors_WOB.png +0 -0
  2632. psychopy/tests/data/textbox_uax14_colors_exemplar1.png +0 -0
  2633. psychopy/tests/data/textbox_uax14_colors_exemplar2.png +0 -0
  2634. psychopy/tests/data/textbox_uax14_colors_exemplar3.png +0 -0
  2635. psychopy/tests/data/textbox_uax14_colors_tyke1.png +0 -0
  2636. psychopy/tests/data/textbox_uax14_colors_tyke2.png +0 -0
  2637. psychopy/tests/data/textbox_uax14_colors_tyke3.png +0 -0
  2638. psychopy/tests/data/textbox_uax14_cutoff_top.png +0 -0
  2639. psychopy/tests/data/textbox_uax14_exemplar_1.png +0 -0
  2640. psychopy/tests/data/textbox_uax14_exemplar_2.png +0 -0
  2641. psychopy/tests/data/textbox_uax14_exemplar_3.png +0 -0
  2642. psychopy/tests/data/textbox_uax14_exemplar_4.png +0 -0
  2643. psychopy/tests/data/textbox_uax14_tyke_1.png +0 -0
  2644. psychopy/tests/data/textbox_uax14_tyke_2.png +0 -0
  2645. psychopy/tests/data/trialTypes.csv +1 -0
  2646. psychopy/tests/data/trialTypes.docx +0 -0
  2647. psychopy/tests/data/trialTypes.pkl +0 -0
  2648. psychopy/tests/data/trialTypes.tsv +7 -0
  2649. psychopy/tests/data/trialTypes.xls +0 -0
  2650. psychopy/tests/data/trialTypes.xlsx +0 -0
  2651. psychopy/tests/data/trialTypes_eu.csv +7 -0
  2652. psychopy/tests/data/trialsBlankCols.xlsx +0 -0
  2653. psychopy/tests/data/wedge1_cm.png +0 -0
  2654. psychopy/tests/data/wedge1_deg.png +0 -0
  2655. psychopy/tests/data/wedge1_degFlat.png +0 -0
  2656. psychopy/tests/data/wedge1_degFlatPos.png +0 -0
  2657. psychopy/tests/data/wedge1_height.png +0 -0
  2658. psychopy/tests/data/wedge1_norm.png +0 -0
  2659. psychopy/tests/data/wedge1_normAddBlend.png +0 -0
  2660. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  2661. psychopy/tests/data/wedge1_normHexbackground.png +0 -0
  2662. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  2663. psychopy/tests/data/wedge1_normNoShade.png +0 -0
  2664. psychopy/tests/data/wedge1_norm_local.png +0 -0
  2665. psychopy/tests/data/wedge1_pix.png +0 -0
  2666. psychopy/tests/data/wedge1_stencil.png +0 -0
  2667. psychopy/tests/data/wedge2_cm.png +0 -0
  2668. psychopy/tests/data/wedge2_deg.png +0 -0
  2669. psychopy/tests/data/wedge2_degFlat.png +0 -0
  2670. psychopy/tests/data/wedge2_degFlatPos.png +0 -0
  2671. psychopy/tests/data/wedge2_height.png +0 -0
  2672. psychopy/tests/data/wedge2_norm.png +0 -0
  2673. psychopy/tests/data/wedge2_normAddBlend.png +0 -0
  2674. psychopy/tests/data/wedge2_normHexbackground.png +0 -0
  2675. psychopy/tests/data/wedge2_normNoShade.png +0 -0
  2676. psychopy/tests/data/wedge2_pix.png +0 -0
  2677. psychopy/tests/data/wedge2_stencil.png +0 -0
  2678. psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos-0.4_0.png +0 -0
  2679. psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos0_0.png +0 -0
  2680. psychopy/tests/data/winScalePos_ori0_scale-1_1_pos-0.4_0.png +0 -0
  2681. psychopy/tests/data/winScalePos_ori0_scale-1_1_pos0_0.png +0 -0
  2682. psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos-0.4_0.png +0 -0
  2683. psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos0_0.png +0 -0
  2684. psychopy/tests/data/winScalePos_ori0_scale-2_2_pos-0.4_0.png +0 -0
  2685. psychopy/tests/data/winScalePos_ori0_scale-2_2_pos0_0.png +0 -0
  2686. psychopy/tests/data/winScalePos_ori0_scale1_-1_pos-0.4_0.png +0 -0
  2687. psychopy/tests/data/winScalePos_ori0_scale1_-1_pos0_0.png +0 -0
  2688. psychopy/tests/data/winScalePos_ori0_scale1_1_pos-0.4_0.png +0 -0
  2689. psychopy/tests/data/winScalePos_ori0_scale1_1_pos0_0.png +0 -0
  2690. psychopy/tests/data/winScalePos_ori0_scale2_-2_pos-0.4_0.png +0 -0
  2691. psychopy/tests/data/winScalePos_ori0_scale2_-2_pos0_0.png +0 -0
  2692. psychopy/tests/data/winScalePos_ori0_scale2_2_pos-0.4_0.png +0 -0
  2693. psychopy/tests/data/winScalePos_ori0_scale2_2_pos0_0.png +0 -0
  2694. psychopy/tests/data/winScalePos_ori45_scale-1_-1_pos0_0.png +0 -0
  2695. psychopy/tests/data/winScalePos_ori45_scale-1_1_pos0_0.png +0 -0
  2696. psychopy/tests/data/winScalePos_ori45_scale-2_-2_pos0_0.png +0 -0
  2697. psychopy/tests/data/winScalePos_ori45_scale-2_2_pos0_0.png +0 -0
  2698. psychopy/tests/data/winScalePos_ori45_scale1_-1_pos0_0.png +0 -0
  2699. psychopy/tests/data/winScalePos_ori45_scale1_1_pos0_0.png +0 -0
  2700. psychopy/tests/data/winScalePos_ori45_scale2_-2_pos0_0.png +0 -0
  2701. psychopy/tests/data/winScalePos_ori45_scale2_2_pos0_0.png +0 -0
  2702. psychopy/tests/doc/run_btn.png +0 -0
  2703. psychopy/tests/doc/test-suite-bugs.jpg +0 -0
  2704. psychopy/tests/doc/user-bugs.jpg +0 -0
  2705. psychopy/tests/dummy_xorg.conf +21 -0
  2706. psychopy/tests/run.py +50 -0
  2707. psychopy/tests/test_Installation.py +38 -0
  2708. psychopy/tests/test_alerts/test_alerts.py +37 -0
  2709. psychopy/tests/test_alerts/test_alerttools.py +131 -0
  2710. psychopy/tests/test_app/__init__.py +0 -0
  2711. psychopy/tests/test_app/conftest.py +41 -0
  2712. psychopy/tests/test_app/test_builder/__init__.py +0 -0
  2713. psychopy/tests/test_app/test_builder/test_BuilderFrame.py +151 -0
  2714. psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +135 -0
  2715. psychopy/tests/test_app/test_builder/test_ComponentDialogs.py +98 -0
  2716. psychopy/tests/test_app/test_runner/__init__.py +0 -0
  2717. psychopy/tests/test_app/test_runner/test_RunnerFrame.py +166 -0
  2718. psychopy/tests/test_app/test_speed.py +144 -0
  2719. psychopy/tests/test_app/test_themes/test_icons.py +79 -0
  2720. psychopy/tests/test_codecov.py +29 -0
  2721. psychopy/tests/test_colors/test_Color.py +41 -0
  2722. psychopy/tests/test_data/dataPrev.xlsx +0 -0
  2723. psychopy/tests/test_data/test_ExperimentHandler.py +171 -0
  2724. psychopy/tests/test_data/test_MultiStairHandler.py +174 -0
  2725. psychopy/tests/test_data/test_StairHandlers.py +1241 -0
  2726. psychopy/tests/test_data/test_TrialHandler.py +335 -0
  2727. psychopy/tests/test_data/test_TrialHandler2.py +408 -0
  2728. psychopy/tests/test_data/test_TrialHandlerExt.py +359 -0
  2729. psychopy/tests/test_data/test_fitFunctions.py +101 -0
  2730. psychopy/tests/test_data/test_utils.py +169 -0
  2731. psychopy/tests/test_data/test_xlsx.py +92 -0
  2732. psychopy/tests/test_demos/test_builder_demos.py +52 -0
  2733. psychopy/tests/test_experiment/__init__.py +0 -0
  2734. psychopy/tests/test_experiment/known_py_diffs.txt +47 -0
  2735. psychopy/tests/test_experiment/needs_wx/__init__.py +0 -0
  2736. psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +13730 -0
  2737. psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +130 -0
  2738. psychopy/tests/test_experiment/needs_wx/test_Experiment.py +406 -0
  2739. psychopy/tests/test_experiment/needs_wx/test_components.py +170 -0
  2740. psychopy/tests/test_experiment/test_component_compile_js.py +59 -0
  2741. psychopy/tests/test_experiment/test_component_compile_python.py +165 -0
  2742. psychopy/tests/test_experiment/test_components/__init__.py +1 -0
  2743. psychopy/tests/test_experiment/test_components/test_ButtonBox.py +216 -0
  2744. psychopy/tests/test_experiment/test_components/test_Code.py +82 -0
  2745. psychopy/tests/test_experiment/test_components/test_Image.py +24 -0
  2746. psychopy/tests/test_experiment/test_components/test_Mouse.py +149 -0
  2747. psychopy/tests/test_experiment/test_components/test_Polygon.py +81 -0
  2748. psychopy/tests/test_experiment/test_components/test_ResourceManager.py +60 -0
  2749. psychopy/tests/test_experiment/test_components/test_Settings.py +82 -0
  2750. psychopy/tests/test_experiment/test_components/test_Static.py +60 -0
  2751. psychopy/tests/test_experiment/test_components/test_all_components.py +162 -0
  2752. psychopy/tests/test_experiment/test_components/test_base_components.py +323 -0
  2753. psychopy/tests/test_experiment/test_experiment.py +103 -0
  2754. psychopy/tests/test_experiment/test_loops.py +95 -0
  2755. psychopy/tests/test_experiment/test_params.py +350 -0
  2756. psychopy/tests/test_experiment/test_py2js.py +230 -0
  2757. psychopy/tests/test_experiment/test_routines/__init__.py +1 -0
  2758. psychopy/tests/test_experiment/test_routines/test_EyetrackerCalibrationRoutine.py +9 -0
  2759. psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +9 -0
  2760. psychopy/tests/test_experiment/test_routines/test_all_routines.py +23 -0
  2761. psychopy/tests/test_experiment/test_routines/test_base_routine.py +154 -0
  2762. psychopy/tests/test_experiment/test_routines/test_standalone_routines.py +36 -0
  2763. psychopy/tests/test_gui/test_DlgFromDictQt.py +82 -0
  2764. psychopy/tests/test_gui/test_DlgFromDictWx.py +82 -0
  2765. psychopy/tests/test_hardware/__init__.py +0 -0
  2766. psychopy/tests/test_hardware/test_CRS_BitsSharp.py +67 -0
  2767. psychopy/tests/test_hardware/test_CRS_bitsShaders.py +110 -0
  2768. psychopy/tests/test_hardware/test_device_manager.py +36 -0
  2769. psychopy/tests/test_hardware/test_emulator.py +106 -0
  2770. psychopy/tests/test_hardware/test_gammasci.py +35 -0
  2771. psychopy/tests/test_hardware/test_keyboard.py +73 -0
  2772. psychopy/tests/test_hardware/test_keyboard_events.py +362 -0
  2773. psychopy/tests/test_hardware/test_ports.py +151 -0
  2774. psychopy/tests/test_iohub/__init__.py +1 -0
  2775. psychopy/tests/test_iohub/test_computer.py +124 -0
  2776. psychopy/tests/test_iohub/test_event_get_and_clear.py +94 -0
  2777. psychopy/tests/test_iohub/test_keyboard.py +91 -0
  2778. psychopy/tests/test_iohub/test_launch.py +19 -0
  2779. psychopy/tests/test_iohub/testutil.py +54 -0
  2780. psychopy/tests/test_liaison/test_Liaison.py +228 -0
  2781. psychopy/tests/test_misc/__init__.py +0 -0
  2782. psychopy/tests/test_misc/memory_usage.py +164 -0
  2783. psychopy/tests/test_misc/test_GammaFun.py +15 -0
  2784. psychopy/tests/test_misc/test_clock.py +61 -0
  2785. psychopy/tests/test_misc/test_color.py +203 -0
  2786. psychopy/tests/test_misc/test_core.py +446 -0
  2787. psychopy/tests/test_misc/test_event.py +307 -0
  2788. psychopy/tests/test_misc/test_info.py +18 -0
  2789. psychopy/tests/test_misc/test_layout.py +49 -0
  2790. psychopy/tests/test_misc/test_locale.py +38 -0
  2791. psychopy/tests/test_misc/test_web.py +22 -0
  2792. psychopy/tests/test_monitors/test_monitors.py +91 -0
  2793. psychopy/tests/test_preferences/__init__.py +0 -0
  2794. psychopy/tests/test_preferences/test_prefs.py +28 -0
  2795. psychopy/tests/test_session/test_Session.py +253 -0
  2796. psychopy/tests/test_sound/__init__.py +0 -0
  2797. psychopy/tests/test_sound/test_audioclip.py +331 -0
  2798. psychopy/tests/test_sound/test_hamming.py +45 -0
  2799. psychopy/tests/test_sound/test_microphone.py +217 -0
  2800. psychopy/tests/test_sound/test_sound.py +67 -0
  2801. psychopy/tests/test_sound/test_sound_pygame.py +67 -0
  2802. psychopy/tests/test_tools/test_animationtools.py +51 -0
  2803. psychopy/tests/test_tools/test_arraytools.py +130 -0
  2804. psychopy/tests/test_tools/test_attributetools.py +257 -0
  2805. psychopy/tests/test_tools/test_colorspacetools.py +149 -0
  2806. psychopy/tests/test_tools/test_environmenttools.py +52 -0
  2807. psychopy/tests/test_tools/test_fileerrortools.py +97 -0
  2808. psychopy/tests/test_tools/test_filetools.py +104 -0
  2809. psychopy/tests/test_tools/test_imagetools.py +57 -0
  2810. psychopy/tests/test_tools/test_mathtools.py +688 -0
  2811. psychopy/tests/test_tools/test_stringtools.py +143 -0
  2812. psychopy/tests/test_tools/test_versionchooser.py +178 -0
  2813. psychopy/tests/test_tools/test_viewtools.py +67 -0
  2814. psychopy/tests/test_visual/__init__.py +0 -0
  2815. psychopy/tests/test_visual/measure_parity.py +243 -0
  2816. psychopy/tests/test_visual/test_all_stimuli.py +752 -0
  2817. psychopy/tests/test_visual/test_basevisual.py +534 -0
  2818. psychopy/tests/test_visual/test_brush.py +68 -0
  2819. psychopy/tests/test_visual/test_button.py +15 -0
  2820. psychopy/tests/test_visual/test_circle.py +66 -0
  2821. psychopy/tests/test_visual/test_contains_overlaps.py +242 -0
  2822. psychopy/tests/test_visual/test_custommouse.py +47 -0
  2823. psychopy/tests/test_visual/test_dots.py +155 -0
  2824. psychopy/tests/test_visual/test_form.py +414 -0
  2825. psychopy/tests/test_visual/test_framepacking.py +41 -0
  2826. psychopy/tests/test_visual/test_gamma.py +152 -0
  2827. psychopy/tests/test_visual/test_glfw_backend.py +14 -0
  2828. psychopy/tests/test_visual/test_image.py +218 -0
  2829. psychopy/tests/test_visual/test_panorama.py +41 -0
  2830. psychopy/tests/test_visual/test_progress.py +96 -0
  2831. psychopy/tests/test_visual/test_projections.py +215 -0
  2832. psychopy/tests/test_visual/test_projections_interactive.py +163 -0
  2833. psychopy/tests/test_visual/test_ratingScale.py +299 -0
  2834. psychopy/tests/test_visual/test_roi.py +99 -0
  2835. psychopy/tests/test_visual/test_shape.py +23 -0
  2836. psychopy/tests/test_visual/test_slider.py +328 -0
  2837. psychopy/tests/test_visual/test_target.py +35 -0
  2838. psychopy/tests/test_visual/test_textbox.py +474 -0
  2839. psychopy/tests/test_visual/test_winFlipTiming.py +95 -0
  2840. psychopy/tests/test_visual/test_winScalePos.py +77 -0
  2841. psychopy/tests/test_visual/test_window.py +107 -0
  2842. psychopy/tests/utils.py +318 -0
  2843. psychopy/tools/LineBreak.txt +3597 -0
  2844. psychopy/tools/__init__.py +9 -0
  2845. psychopy/tools/animationtools.py +49 -0
  2846. psychopy/tools/apptools.py +32 -0
  2847. psychopy/tools/arraytools.py +514 -0
  2848. psychopy/tools/attributetools.py +205 -0
  2849. psychopy/tools/audiotools.py +358 -0
  2850. psychopy/tools/colorspacetools.py +715 -0
  2851. psychopy/tools/coordinatetools.py +104 -0
  2852. psychopy/tools/environmenttools.py +62 -0
  2853. psychopy/tools/fileerrortools.py +54 -0
  2854. psychopy/tools/filetools.py +406 -0
  2855. psychopy/tools/fontmanager.py +1041 -0
  2856. psychopy/tools/gltools.py +4959 -0
  2857. psychopy/tools/imagetools.py +65 -0
  2858. psychopy/tools/linebreak.py +322 -0
  2859. psychopy/tools/mathtools.py +4040 -0
  2860. psychopy/tools/monitorunittools.py +270 -0
  2861. psychopy/tools/movietools.py +1071 -0
  2862. psychopy/tools/pkgtools.py +601 -0
  2863. psychopy/tools/plottools.py +25 -0
  2864. psychopy/tools/rifttools.py +76 -0
  2865. psychopy/tools/stereotools.py +9 -0
  2866. psychopy/tools/stimulustools.py +28 -0
  2867. psychopy/tools/stringtools.py +421 -0
  2868. psychopy/tools/systemtools.py +1331 -0
  2869. psychopy/tools/typetools.py +52 -0
  2870. psychopy/tools/unittools.py +16 -0
  2871. psychopy/tools/versionchooser.py +602 -0
  2872. psychopy/tools/viewtools.py +1084 -0
  2873. psychopy/tools/wizard.py +804 -0
  2874. psychopy/visual/__init__.py +124 -0
  2875. psychopy/visual/aperture.py +330 -0
  2876. psychopy/visual/backends/__init__.py +77 -0
  2877. psychopy/visual/backends/_base.py +481 -0
  2878. psychopy/visual/backends/gamma.py +349 -0
  2879. psychopy/visual/backends/glfwbackend.py +28 -0
  2880. psychopy/visual/backends/pygamebackend.py +343 -0
  2881. psychopy/visual/backends/pygletbackend.py +920 -0
  2882. psychopy/visual/basevisual.py +1952 -0
  2883. psychopy/visual/brush.py +204 -0
  2884. psychopy/visual/bufferimage.py +231 -0
  2885. psychopy/visual/button.py +206 -0
  2886. psychopy/visual/circle.py +173 -0
  2887. psychopy/visual/custommouse.py +263 -0
  2888. psychopy/visual/dot.py +668 -0
  2889. psychopy/visual/dropdown.py +165 -0
  2890. psychopy/visual/elementarray.py +728 -0
  2891. psychopy/visual/filters.py +419 -0
  2892. psychopy/visual/form.py +1180 -0
  2893. psychopy/visual/globalVars.py +24 -0
  2894. psychopy/visual/grating.py +501 -0
  2895. psychopy/visual/helpers.py +334 -0
  2896. psychopy/visual/image.py +440 -0
  2897. psychopy/visual/line.py +238 -0
  2898. psychopy/visual/movie.py +12 -0
  2899. psychopy/visual/movie2.py +829 -0
  2900. psychopy/visual/movie3.py +599 -0
  2901. psychopy/visual/movies/__init__.py +850 -0
  2902. psychopy/visual/movies/frame.py +255 -0
  2903. psychopy/visual/movies/metadata.py +242 -0
  2904. psychopy/visual/movies/players/__init__.py +62 -0
  2905. psychopy/visual/movies/players/_base.py +364 -0
  2906. psychopy/visual/movies/players/ffpyplayer_player.py +1399 -0
  2907. psychopy/visual/nnlvs.py +827 -0
  2908. psychopy/visual/noise.py +34 -0
  2909. psychopy/visual/panorama.py +313 -0
  2910. psychopy/visual/patch.py +29 -0
  2911. psychopy/visual/pie.py +248 -0
  2912. psychopy/visual/polygon.py +229 -0
  2913. psychopy/visual/progress.py +313 -0
  2914. psychopy/visual/radial.py +33 -0
  2915. psychopy/visual/ratingscale.py +1424 -0
  2916. psychopy/visual/rect.py +204 -0
  2917. psychopy/visual/rift.py +2654 -0
  2918. psychopy/visual/roi.py +141 -0
  2919. psychopy/visual/secondorder.py +29 -0
  2920. psychopy/visual/shaders.py +453 -0
  2921. psychopy/visual/shape.py +701 -0
  2922. psychopy/visual/simpleimage.py +303 -0
  2923. psychopy/visual/slider.py +1169 -0
  2924. psychopy/visual/stim3d.py +2712 -0
  2925. psychopy/visual/target.py +278 -0
  2926. psychopy/visual/text.py +759 -0
  2927. psychopy/visual/textbox/__init__.py +1280 -0
  2928. psychopy/visual/textbox/fontmanager.py +574 -0
  2929. psychopy/visual/textbox/parsedtext.py +317 -0
  2930. psychopy/visual/textbox/textgrid.py +278 -0
  2931. psychopy/visual/textbox/textureatlas.py +248 -0
  2932. psychopy/visual/textbox2/__init__.py +4 -0
  2933. psychopy/visual/textbox2/textbox2.py +1817 -0
  2934. psychopy/visual/vlcmoviestim.py +1294 -0
  2935. psychopy/visual/window.py +3706 -0
  2936. psychopy/visual/windowframepack.py +86 -0
  2937. psychopy/visual/windowwarp.py +457 -0
  2938. psychopy/voicekey/__init__.py +684 -0
  2939. psychopy/voicekey/demo_vks.py +12 -0
  2940. psychopy/voicekey/labjack_vks.py +50 -0
  2941. psychopy/voicekey/parallel_vks.py +44 -0
  2942. psychopy/voicekey/signal.py +42 -0
  2943. psychopy/voicekey/vk_tools.py +280 -0
  2944. psychopy/web.py +286 -0
  2945. psychopy-2024.1.0.dist-info/METADATA +154 -0
  2946. psychopy-2024.1.0.dist-info/RECORD +2950 -0
  2947. psychopy-2024.1.0.dist-info/WHEEL +4 -0
  2948. psychopy-2024.1.0.dist-info/entry_points.txt +3 -0
  2949. psychopy-2024.1.0.dist-info/licenses/AUTHORS.md +138 -0
  2950. psychopy-2024.1.0.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,3706 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """A class representing a window for displaying one or more stimuli"""
5
+
6
+ # Part of the PsychoPy library
7
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
8
+ # Distributed under the terms of the GNU General Public License (GPL).
9
+
10
+
11
+
12
+
13
+ import ctypes
14
+ import os
15
+ import sys
16
+ import weakref
17
+ import atexit
18
+ from itertools import product
19
+ from collections import deque
20
+
21
+ from psychopy.contrib.lazy_import import lazy_import
22
+ from psychopy import colors, event
23
+ from psychopy.localization import _translate
24
+ from psychopy.tools.systemtools import getCurrentPID, registerPID
25
+ import math
26
+ # from psychopy.clock import monotonicClock
27
+
28
+ # try to find avbin (we'll overload pyglet's load_library tool and then
29
+ # add some paths)
30
+ from ..colors import Color, colorSpaces
31
+ from .textbox2 import TextBox2
32
+
33
+
34
+ haveAvbin = False
35
+
36
+ # on windows try to load avbin now (other libs can interfere)
37
+ if sys.platform == 'win32':
38
+ # make sure we also check in SysWOW64 if on 64-bit windows
39
+ if 'C:\\Windows\\SysWOW64' not in os.environ['PATH']:
40
+ os.environ['PATH'] += ';C:\\Windows\\SysWOW64'
41
+
42
+ try:
43
+ from pyglet.media import avbin
44
+ haveAvbin = True
45
+ except ImportError:
46
+ haveAvbin = False
47
+ # either avbin isn't installed or scipy.stats has been imported
48
+ # (prevents avbin loading)
49
+ except AttributeError:
50
+ # avbin is not found, causing exception in pyglet 1.2??
51
+ # (running psychopy 1.81 standalone on windows 7):
52
+ #
53
+ # File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\
54
+ # pyglet\media\avbin.py", line 158, in <module>
55
+ # av.avbin_get_version.restype = ctypes.c_int
56
+ # AttributeError: 'NoneType' object has no attribute
57
+ # 'avbin_get_version'
58
+ haveAvbin = False
59
+ except Exception:
60
+ # WindowsError on some systems
61
+ # AttributeError if using avbin5 from pyglet 1.2?
62
+ haveAvbin = False
63
+
64
+ # for pyglet 1.3
65
+ if not haveAvbin:
66
+ try:
67
+ from pyglet.media.sources import avbin
68
+ haveAvbin = True
69
+ except ImportError:
70
+ haveAvbin = False
71
+ except AttributeError:
72
+ haveAvbin = False
73
+ except Exception:
74
+ haveAvbin = False
75
+
76
+ import psychopy # so we can get the __path__
77
+ from psychopy import core, platform_specific, logging, prefs, monitors
78
+ import psychopy.event
79
+ from . import backends, image
80
+
81
+ # tools must only be imported *after* event or MovieStim breaks on win32
82
+ # (JWP has no idea why!)
83
+ from psychopy.tools.attributetools import attributeSetter, setAttribute
84
+ from psychopy.tools.arraytools import val2array
85
+ from psychopy.tools.monitorunittools import convertToPix
86
+ import psychopy.tools.viewtools as viewtools
87
+ import psychopy.tools.gltools as gltools
88
+ from .text import TextStim
89
+ from .grating import GratingStim
90
+ from .helpers import setColor
91
+ from . import globalVars
92
+
93
+ try:
94
+ from PIL import Image
95
+ except ImportError:
96
+ import Image
97
+
98
+ import numpy
99
+
100
+ from psychopy.core import rush
101
+
102
+ reportNDroppedFrames = 5 # stop raising warning after this
103
+
104
+ # import pyglet.gl, pyglet.window, pyglet.image, pyglet.font, pyglet.event
105
+ from . import shaders as _shaders
106
+ try:
107
+ from pyglet import media
108
+ havePygletMedia = True
109
+ except Exception:
110
+ havePygletMedia = False
111
+
112
+ # lazy_import puts pygame into the namespace but delays import until needed
113
+ lazy_import(globals(), "import pygame")
114
+
115
+ DEBUG = False
116
+ IOHUB_ACTIVE = False
117
+ retinaContext = None # only needed for retina-ready displays
118
+
119
+
120
+ class OpenWinList(list):
121
+ """Class to keep keep track of windows that have been opened.
122
+
123
+ Uses a list of weak references so that we don't stop the window
124
+ being deleted.
125
+
126
+ """
127
+ def append(self, item):
128
+ list.append(self, weakref.ref(item))
129
+
130
+ def remove(self, item):
131
+ for ref in self:
132
+ obj = ref()
133
+ if obj is None or item == obj:
134
+ list.remove(self, ref)
135
+
136
+
137
+ openWindows = core.openWindows = OpenWinList() # core needs this for wait()
138
+
139
+
140
+ class Window():
141
+ """Used to set up a context in which to draw objects,
142
+ using either `pyglet <http://www.pyglet.org>`_,
143
+ `pygame <http://www.pygame.org>`_, or `glfw <https://www.glfw.org>`_.
144
+
145
+ The pyglet backend allows multiple windows to be created, allows the user
146
+ to specify which screen to use (if more than one is available, duh!) and
147
+ allows movies to be rendered.
148
+
149
+ The GLFW backend is a new addition which provides most of the same features
150
+ as pyglet, but provides greater flexibility for complex display
151
+ configurations.
152
+
153
+ Pygame may still work for you but it's officially deprecated in this
154
+ project (we won't be fixing pygame-specific bugs).
155
+
156
+ """
157
+ def __init__(self,
158
+ size=(800, 600),
159
+ pos=None,
160
+ color=(0, 0, 0),
161
+ colorSpace='rgb',
162
+ backgroundImage=None,
163
+ backgroundFit="cover",
164
+ rgb=None,
165
+ dkl=None,
166
+ lms=None,
167
+ fullscr=None,
168
+ allowGUI=None,
169
+ monitor=None,
170
+ bitsMode=None,
171
+ winType=None,
172
+ units=None,
173
+ gamma=None,
174
+ blendMode='avg',
175
+ screen=0,
176
+ viewScale=None,
177
+ viewPos=None,
178
+ viewOri=0.0,
179
+ waitBlanking=True,
180
+ allowStencil=False,
181
+ multiSample=False,
182
+ numSamples=2,
183
+ stereo=False,
184
+ name='window1',
185
+ title="PsychoPy",
186
+ checkTiming=True,
187
+ useFBO=False,
188
+ useRetina=True,
189
+ autoLog=True,
190
+ gammaErrorPolicy='raise',
191
+ bpc=(8, 8, 8),
192
+ depthBits=8,
193
+ stencilBits=8,
194
+ backendConf=None,
195
+ infoMsg=None):
196
+ """
197
+ These attributes can only be set at initialization. See further down
198
+ for a list of attributes which can be changed after initialization
199
+ of the Window, e.g. color, colorSpace, gamma etc.
200
+
201
+ Parameters
202
+ ----------
203
+ size : array-like of int
204
+ Size of the window in pixels [x, y].
205
+ pos : array-like of int
206
+ Location of the top-left corner of the window on the screen [x, y].
207
+ color : array-like of float
208
+ Color of background as [r, g, b] list or single value. Each gun can
209
+ take values between -1.0 and 1.0.
210
+ fullscr : bool or None
211
+ Create a window in 'full-screen' mode. Better timing can be achieved
212
+ in full-screen mode.
213
+ allowGUI : bool or None
214
+ If set to False, window will be drawn with no frame and no buttons
215
+ to close etc., use `None` for value from preferences.
216
+ winType : str or None
217
+ Set the window type or back-end to use. If `None` then PsychoPy will
218
+ revert to user/site preferences.
219
+ monitor : :class:`~psychopy.monitors.Monitor` or None
220
+ The monitor to be used during the experiment. If `None` a default
221
+ monitor profile will be used.
222
+ units : str or None
223
+ Defines the default units of stimuli drawn in the window (can be
224
+ overridden by each stimulus). Values can be *None*, 'height' (of the
225
+ window), 'norm' (normalised), 'deg', 'cm', 'pix'. See :ref:`units`
226
+ for explanation of options.
227
+ screen : int
228
+ Specifies the physical screen that stimuli will appear on ('pyglet'
229
+ and 'glfw' `winType` only). Values can be >0 if more than one screen
230
+ is present.
231
+ viewScale : array-like of float or None
232
+ Scaling factors [x, y] to apply custom scaling to the current units
233
+ of the :class:`~psychopy.visual.Window` instance.
234
+ viewPos : array-like of float or None
235
+ If not `None`, redefines the origin within the window, in the units
236
+ of the window. Values outside the borders will be clamped to lie on
237
+ the border.
238
+ viewOri : float
239
+ A single value determining the orientation of the view in degrees.
240
+ waitBlanking : bool or None
241
+ After a call to :py:attr:`~Window.flip()` should we wait for the
242
+ blank before the script continues.
243
+ bitsMode : bool
244
+ DEPRECATED in 1.80.02. Use BitsSharp class from pycrsltd
245
+ instead.
246
+ checkTiming : bool
247
+ Whether to calculate frame duration on initialization. Estimated
248
+ duration is saved in :py:attr:`~Window.monitorFramePeriod`. The
249
+ message displayed on the screen can be set with the `infoMsg`
250
+ argument.
251
+ allowStencil : bool
252
+ When set to `True`, this allows operations that use the OpenGL
253
+ stencil buffer (notably, allowing the
254
+ :class:`~psychopy.visual.Aperture` to be used).
255
+ multiSample : bool
256
+ If `True` and your graphics driver supports multisample buffers,
257
+ multiple color samples will be taken per-pixel, providing an
258
+ anti-aliased image through spatial filtering. This setting cannot
259
+ be changed after opening a window. Only works with 'pyglet' and
260
+ 'glfw' `winTypes`, and `useFBO` is `False`.
261
+ numSamples : int
262
+ A single value specifying the number of samples per pixel if
263
+ multisample is enabled. The higher the number, the better the
264
+ image quality, but can delay frame flipping. The largest number of
265
+ samples is determined by ``GL_MAX_SAMPLES``, usually 16 or 32 on
266
+ newer hardware, will crash if number is invalid.
267
+ stereo : bool
268
+ If `True` and your graphics card supports quad buffers then
269
+ this will be enabled. You can switch between left and right-eye
270
+ scenes for drawing operations using
271
+ :py:attr:`~psychopy.visual.Window.setBuffer()`.
272
+ title : str
273
+ Name of the Window according to your Operating System. This is
274
+ the text which appears on the title sash.
275
+ useRetina : bool
276
+ In PsychoPy >1.85.3 this should always be `True` as pyglet
277
+ (or Apple) no longer allows us to create a non-retina display.
278
+ NB when you use Retina display the initial win size
279
+ request will be in the larger pixels but subsequent use of
280
+ ``units='pix'`` should refer to the tiny Retina pixels. Window.size
281
+ will give the actual size of the screen in Retina pixels.
282
+ gammaErrorPolicy: str
283
+ If `raise`, an error is raised if the gamma table is unable to be
284
+ retrieved or set. If `warn`, a warning is raised instead. If
285
+ `ignore`, neither an error nor a warning are raised.
286
+ bpc : array_like or int
287
+ Bits per color (BPC) for the back buffer as a tuple to specify
288
+ bit depths for each color channel separately (red, green, blue), or
289
+ a single value to set all of them to the same value. Valid values
290
+ depend on the output color depth of the display (screen) the window
291
+ is set to use and the system graphics configuration. By default, it
292
+ is assumed the display has 8-bits per color (8, 8, 8). Behaviour may
293
+ be undefined for non-fullscreen windows, or if multiple screens are
294
+ attached with varying color output depths.
295
+ depthBits : int
296
+ Back buffer depth bits. Default is 8, but can be set higher (eg. 24)
297
+ if drawing 3D stimuli to minimize artifacts such a 'Z-fighting'.
298
+ stencilBits : int
299
+ Back buffer stencil bits. Default is 8.
300
+ backendConf : dict or None
301
+ Additional options to pass to the backend specified by `winType`.
302
+ Each backend may provide unique functionality which may not be
303
+ available across all of them. This allows you to pass special
304
+ configuration options to a specific backend to configure the
305
+ feature.
306
+ infoMsg : str or None
307
+ Message to display during frame rate measurement (i.e., when
308
+ ``checkTiming=True``). Default is None, which means that a default
309
+ message is displayed. If you want to hide the message, pass an
310
+ empty string.
311
+
312
+ Notes
313
+ -----
314
+ * Some parameters (e.g. units) can now be given default values in the
315
+ user/site preferences and these will be used if `None` is given here.
316
+ If you do specify a value here it will take precedence over
317
+ preferences.
318
+
319
+ Attributes
320
+ ----------
321
+ size : array-like (float)
322
+ Dimensions of the window's drawing area/buffer in pixels [w, h].
323
+ monitorFramePeriod : float
324
+ Refresh rate of the display if ``checkTiming=True`` on window
325
+ instantiation.
326
+
327
+ """
328
+ # what local vars are defined (these are the init params) for use by
329
+ # __repr__
330
+ self._initParams = dir()
331
+ self._closed = False
332
+ self.backend = None # this will be set later
333
+ for unecess in ['self', 'checkTiming', 'rgb', 'dkl', ]:
334
+ self._initParams.remove(unecess)
335
+
336
+ # Check autoLog value
337
+ if autoLog not in (True, False):
338
+ raise ValueError(
339
+ 'autoLog must be either True or False for visual.Window')
340
+
341
+ self.autoLog = False # to suppress log msg during init
342
+ self.name = name
343
+ self.clientSize = numpy.array(size, int) # size of window, not buffer
344
+ # size of the window when restored (not fullscreen)
345
+ self._windowedSize = self.clientSize.copy()
346
+
347
+ self.pos = pos
348
+ # this will get overridden once the window is created
349
+ self.winHandle = None
350
+ self.useFBO = useFBO
351
+ self.useRetina = useRetina and sys.platform == 'darwin'
352
+
353
+ if gammaErrorPolicy not in ['raise', 'warn', 'ignore']:
354
+ raise ValueError('Unexpected `gammaErrorPolicy`')
355
+ self.gammaErrorPolicy = gammaErrorPolicy
356
+
357
+ self._toLog = []
358
+ self._toCall = []
359
+ # settings for the monitor: local settings (if available) override
360
+ # monitor
361
+ # if we have a monitors.Monitor object (psychopy 0.54 onwards)
362
+ # convert to a Monitor object
363
+ if not monitor:
364
+ self.monitor = monitors.Monitor('__blank__', autoLog=autoLog)
365
+ elif isinstance(monitor, str):
366
+ self.monitor = monitors.Monitor(monitor, autoLog=autoLog)
367
+ elif hasattr(monitor, 'keys'):
368
+ # convert into a monitor object
369
+ self.monitor = monitors.Monitor('temp', currentCalib=monitor,
370
+ verbose=False, autoLog=autoLog)
371
+ else:
372
+ self.monitor = monitor
373
+
374
+ # otherwise monitor will just be a dict
375
+ self.scrWidthCM = self.monitor.getWidth()
376
+ self.scrDistCM = self.monitor.getDistance()
377
+
378
+ scrSize = self.monitor.getSizePix()
379
+ if scrSize is None:
380
+ self.scrWidthPIX = None
381
+ else:
382
+ self.scrWidthPIX = scrSize[0]
383
+
384
+ # if fullscreen not specified, get from prefs
385
+ if fullscr is None:
386
+ fullscr = prefs.general['fullscr']
387
+ self._isFullScr = fullscr
388
+
389
+ self.units = units
390
+
391
+ if allowGUI is None:
392
+ allowGUI = prefs.general['allowGUI']
393
+ self.allowGUI = allowGUI
394
+
395
+ self.screen = screen
396
+ self.stereo = stereo # use quad buffer if requested (and if possible)
397
+
398
+ # enable multisampling
399
+ self.multiSample = multiSample
400
+ self.numSamples = numSamples
401
+
402
+ # load color conversion matrices
403
+ self.dkl_rgb = self.monitor.getDKL_RGB()
404
+ self.lms_rgb = self.monitor.getLMS_RGB()
405
+
406
+ # Projection and view matrices, these can be lists if multiple views are
407
+ # being used.
408
+ # NB - attribute checks needed for Rift compatibility
409
+ if not hasattr(self, '_viewMatrix'):
410
+ self._viewMatrix = numpy.identity(4, dtype=numpy.float32)
411
+
412
+ if not hasattr(self, '_projectionMatrix'):
413
+ self._projectionMatrix = viewtools.orthoProjectionMatrix(
414
+ -1, 1, -1, 1, -1, 1, dtype=numpy.float32)
415
+
416
+ # set screen color
417
+ self.__dict__['colorSpace'] = colorSpace
418
+ if rgb is not None:
419
+ logging.warning("Use of rgb arguments to stimuli are deprecated. "
420
+ "Please use color and colorSpace args instead")
421
+ color = rgb
422
+ colorSpace = 'rgb'
423
+ elif dkl is not None:
424
+ logging.warning("Use of dkl arguments to stimuli are deprecated. "
425
+ "Please use color and colorSpace args instead")
426
+ color = dkl
427
+ colorSpace = 'dkl'
428
+ elif lms is not None:
429
+ logging.warning("Use of lms arguments to stimuli are deprecated. "
430
+ "Please use color and colorSpace args instead")
431
+ color = lms
432
+ colorSpace = 'lms'
433
+ self.setColor(color, colorSpace=colorSpace, log=False)
434
+
435
+ self.allowStencil = allowStencil
436
+ # check whether FBOs are supported
437
+ if blendMode == 'add' and not self.useFBO:
438
+ logging.warning('User requested a blendmode of "add" but '
439
+ 'window requires useFBO=True')
440
+ # resort to the simpler blending without float rendering
441
+ self.__dict__['blendMode'] = 'avg'
442
+ else:
443
+ self.__dict__['blendMode'] = blendMode
444
+ # then set up gl context and then call self.setBlendMode
445
+
446
+ # setup context and openGL()
447
+ if winType is None: # choose the default windowing
448
+ winType = "pyglet"
449
+ self.winType = winType
450
+
451
+ # setup the context
452
+
453
+ # backend specific options are passed as a dictionary
454
+ backendConf = backendConf if backendConf is not None else {}
455
+
456
+ # Here we make sure all the open windows use the same `winType` and have
457
+ # context sharing enabled. The context to share is passed as an option
458
+ # to `backendConf`.
459
+ if openWindows:
460
+ primaryWindow = openWindows[0]() # resolve ref
461
+ if primaryWindow.winType != self.winType:
462
+ raise ValueError(
463
+ "Only one kind of `winType` can be used per session.")
464
+
465
+ # Allow for context sharing, only used by the GLFW backend, Pyglet
466
+ # uses `shadow_window` by default here so we don't need to worry
467
+ # about it.
468
+ backendConf['share'] = self
469
+
470
+ if not isinstance(backendConf, dict): # type check on options
471
+ raise TypeError(
472
+ 'Object passed to `backendConf` must be type `dict`.')
473
+
474
+ # augment settings with dedicated attributes
475
+ backendConf['bpc'] = bpc
476
+ backendConf['depthBits'] = depthBits
477
+ backendConf['stencilBits'] = stencilBits
478
+
479
+ # get the backend, pass the options to it
480
+ self.backend = backends.getBackend(win=self, backendConf=backendConf)
481
+
482
+ self.winHandle = self.backend.winHandle
483
+ global GL
484
+ GL = self.backend.GL
485
+
486
+ # check whether shaders are supported
487
+ # also will need to check for ARB_float extension,
488
+ # but that should be done after context is created
489
+ self._haveShaders = self.backend.shadersSupported
490
+
491
+ self._setupGL()
492
+
493
+ self.blendMode = self.blendMode
494
+
495
+ # now that we have a window handle, set title
496
+ self.title = title
497
+
498
+ # parameters for transforming the overall view
499
+ self.viewScale = val2array(viewScale)
500
+ if self.viewPos is not None and self.units is None:
501
+ raise ValueError('You must define the window units to use viewPos')
502
+ self.viewPos = val2array(viewPos, withScalar=False)
503
+ self.viewOri = float(viewOri)
504
+ if self.viewOri != 0. and self.viewPos is not None:
505
+ msg = "Window: viewPos & viewOri are currently incompatible"
506
+ raise NotImplementedError(msg)
507
+
508
+ # scaling factor for HiDPI displays, `None` until initialized
509
+ self._contentScaleFactor = None
510
+
511
+ # Code to allow iohub to know id of any psychopy windows created
512
+ # so kb and mouse event filtering by window id can be supported.
513
+ #
514
+ # If an iohubConnection is active, give this window os handle to
515
+ # to the ioHub server. If windows were already created before the
516
+ # iohub was active, also send them to iohub.
517
+ #
518
+ if IOHUB_ACTIVE:
519
+ from psychopy.iohub.client import ioHubConnection as ioconn
520
+ if ioconn.ACTIVE_CONNECTION:
521
+ from psychopy.iohub.client import windowInfoDict
522
+ win_infos = []
523
+ win_handles = []
524
+ for w in openWindows:
525
+ winfo = windowInfoDict(w())
526
+ win_infos.append(winfo)
527
+ win_handles.append(w()._hw_handle)
528
+
529
+ if self._hw_handle not in win_handles:
530
+ winfo = windowInfoDict(self)
531
+ win_infos.append(winfo)
532
+ win_handles.append(self._hw_handle)
533
+ ioconn.ACTIVE_CONNECTION.registerWindowHandles(*win_infos)
534
+ self.backend.onMoveCallback = ioconn.ACTIVE_CONNECTION.updateWindowPos
535
+
536
+ # near and far clipping planes
537
+ self._nearClip = 0.1
538
+ self._farClip = 100.0
539
+
540
+ # 3D rendering related attributes
541
+ self.frontFace = 'ccw'
542
+ self.depthFunc = 'less'
543
+ self.depthMask = False
544
+ self.cullFace = False
545
+ self.cullFaceMode = 'back'
546
+ self.draw3d = False
547
+
548
+ # gl viewport and scissor
549
+ self._viewport = self._scissor = None # set later
550
+
551
+ # scene light sources
552
+ self._lights = []
553
+ self._useLights = False
554
+ self._nLights = 0
555
+ self._ambientLight = numpy.array([0.0, 0.0, 0.0, 1.0],
556
+ dtype=numpy.float32)
557
+
558
+ # stereo rendering settings, set later by the user
559
+ self._eyeOffset = 0.0
560
+ self._convergeOffset = 0.0
561
+
562
+ # gamma
563
+ self.bits = None # this may change in a few lines time!
564
+ self.__dict__['gamma'] = gamma
565
+ self._setupGamma(gamma)
566
+
567
+ # setup bits++ if needed. NB The new preferred method is for this
568
+ # to be handled by the bits class instead. (we pass the Window to
569
+ # bits not passing bits to the window)
570
+ if bitsMode is not None:
571
+ logging.warn("Use of Window(bitsMode=******) is deprecated. See "
572
+ "the Coder>Demos>Hardware demo for new methods")
573
+ self.bitsMode = bitsMode # could be [None, 'fast', 'slow']
574
+ logging.warn("calling Window(...,bitsMode='fast') is deprecated."
575
+ " XXX provide further info")
576
+ from psychopy.hardware.crs.bits import BitsPlusPlus
577
+ self.bits = self.interface = BitsPlusPlus(self)
578
+ self.haveBits = True
579
+ if (hasattr(self.monitor, 'linearizeLums') or
580
+ hasattr(self.monitor, 'lineariseLums')):
581
+ # rather than a gamma value we could use bits++ and provide a
582
+ # complete linearised lookup table using
583
+ # monitor.linearizeLums(lumLevels)
584
+ self.__dict__['gamma'] = None
585
+
586
+ self.frameClock = core.Clock() # from psycho/core
587
+ self.frames = 0 # frames since last fps calc
588
+ self.movieFrames = [] # list of captured frames (Image objects)
589
+
590
+ self.recordFrameIntervals = False
591
+ # Be able to omit the long timegap that follows each time turn it off
592
+ self.recordFrameIntervalsJustTurnedOn = False
593
+ self.nDroppedFrames = 0
594
+ self.frameIntervals = []
595
+ self._frameTimes = deque(maxlen=1000) # 1000 keeps overhead low
596
+
597
+ self._toDraw = []
598
+ self._heldDraw = []
599
+ self._toDrawDepths = []
600
+ self._eventDispatchers = []
601
+
602
+ # dict of stimulus:validator pairs
603
+ self.validators = {}
604
+
605
+ self.lastFrameT = core.getTime()
606
+ self.waitBlanking = waitBlanking
607
+
608
+ # set the swap interval if using GLFW
609
+ if self.winType == 'glfw':
610
+ self.backend.setSwapInterval(int(waitBlanking))
611
+
612
+ self.refreshThreshold = 1.0 # initial val needed by flip()
613
+
614
+ # store editable stimuli
615
+ self._editableChildren = []
616
+ self._currentEditableRef = None
617
+ # store draggable stimuli
618
+ self.currentDraggable = None
619
+
620
+ # splash screen
621
+ self._splashTextbox = None # created on first use
622
+ self._showSplash = False
623
+ self.resetViewport() # set viewport to full window size
624
+
625
+ # piloting indicator
626
+ self._pilotingIndicator = None
627
+ self._showPilotingIndicator = False
628
+
629
+ # over several frames with no drawing
630
+ self._monitorFrameRate = None
631
+ # for testing when to stop drawing a stim:
632
+ self.monitorFramePeriod = 0.0
633
+ if checkTiming:
634
+ self._monitorFrameRate = self.getActualFrameRate(infoMsg=infoMsg)
635
+
636
+ if self._monitorFrameRate is not None:
637
+ self.monitorFramePeriod = 1.0 / self._monitorFrameRate
638
+ else:
639
+ self.monitorFramePeriod = 1.0 / 60 # assume a flat panel?
640
+ self.refreshThreshold = self.monitorFramePeriod * 1.2
641
+ openWindows.append(self)
642
+
643
+ self.autoLog = autoLog
644
+ if self.autoLog:
645
+ logging.exp("Created %s = %s" % (self.name, str(self)))
646
+
647
+ # Make sure this window's close method is called when exiting, even in
648
+ # the event of an error we should be able to restore the original gamma
649
+ # table. Note that a reference to this window object will live in this
650
+ # function, preventing it from being garbage collected.
651
+ def close_on_exit():
652
+ if self._closed is False:
653
+ self.close()
654
+
655
+ atexit.register(close_on_exit)
656
+
657
+ self._mouse = event.Mouse(win=self)
658
+ self.backgroundImage = backgroundImage
659
+ self.backgroundFit = backgroundFit
660
+ if hasattr(self.backgroundImage, "draw"):
661
+ self.backgroundImage.draw()
662
+
663
+ def __del__(self):
664
+ if self._closed is False:
665
+ self.close()
666
+
667
+ def __enter__(self):
668
+ return self
669
+
670
+ def __exit__(self, exc_type, exc_value, traceback):
671
+ if not self._closed:
672
+ self.close()
673
+
674
+ def __str__(self):
675
+ className = 'Window'
676
+ paramStrings = []
677
+ for param in self._initParams:
678
+ if hasattr(self, param):
679
+ paramStrings.append("%s=%s" %
680
+ (param, repr(getattr(self, param))))
681
+ else:
682
+ paramStrings.append("%s=UNKNOWN" % (param))
683
+ # paramStrings = ["%s=%s" %(param, getattr(self, param))
684
+ # for param in self._initParams]
685
+ params = ", ".join(paramStrings)
686
+ s = "%s(%s)" % (className, params)
687
+ return s
688
+
689
+ @attributeSetter
690
+ def title(self, value):
691
+ self.__dict__['title'] = value
692
+ if hasattr(self.winHandle, "set_caption"):
693
+ # Pyglet backend
694
+ self.winHandle.set_caption(value)
695
+ elif hasattr(self.winHandle, "SetWindowTitle"):
696
+ # GLFW backend
697
+ self.winHandle.SetWindowTitle(value)
698
+ else:
699
+ # Unknown backend
700
+ logging.warning(f"Cannot set Window title in backend {self.winType}")
701
+
702
+ @attributeSetter
703
+ def units(self, value):
704
+ """*None*, 'height' (of the window), 'norm', 'deg', 'cm', 'pix'
705
+ Defines the default units of stimuli initialized in the window.
706
+ I.e. if you change units, already initialized stimuli won't change
707
+ their units.
708
+
709
+ Can be overridden by each stimulus, if units is specified on
710
+ initialization.
711
+
712
+ See :ref:`units` for explanation of options.
713
+
714
+ """
715
+ if value is None:
716
+ value = prefs.general['units']
717
+ self.__dict__['units'] = value
718
+
719
+ def setUnits(self, value, log=True):
720
+ setAttribute(self, 'units', value, log=log)
721
+
722
+ @attributeSetter
723
+ def viewPos(self, value):
724
+ """The origin of the window onto which stimulus-objects are drawn.
725
+
726
+ The value should be given in the units defined for the window. NB:
727
+ Never change a single component (x or y) of the origin, instead replace
728
+ the viewPos-attribute in one shot, e.g.::
729
+
730
+ win.viewPos = [new_xval, new_yval] # This is the way to do it
731
+ win.viewPos[0] = new_xval # DO NOT DO THIS! Errors will result.
732
+
733
+ """
734
+ self.__dict__['viewPos'] = value
735
+ if value is not None:
736
+ # let setter take care of normalisation
737
+ setattr(self, '_viewPosNorm', value)
738
+
739
+ @attributeSetter
740
+ def _viewPosNorm(self, value):
741
+ """Normalised value of viewPos, hidden from user view."""
742
+ # first convert to pixels, then normalise to window units
743
+ viewPos_pix = convertToPix([0, 0], list(value),
744
+ units=self.units, win=self)[:2]
745
+ viewPos_norm = viewPos_pix / (self.size / 2.0)
746
+ # Clip to +/- 1; should going out-of-window raise an exception?
747
+ viewPos_norm = numpy.clip(viewPos_norm, a_min=-1., a_max=1.)
748
+ self.__dict__['_viewPosNorm'] = viewPos_norm
749
+
750
+ def setViewPos(self, value, log=True):
751
+ setAttribute(self, 'viewPos', value, log=log)
752
+
753
+ @attributeSetter
754
+ def fullscr(self, value):
755
+ """Set whether fullscreen mode is `True` or `False` (not all backends
756
+ can toggle an open window).
757
+ """
758
+ self.backend.setFullScr(value)
759
+ self.__dict__['fullscr'] = value
760
+ self._isFullScr = value
761
+
762
+ @attributeSetter
763
+ def waitBlanking(self, value):
764
+ """After a call to :py:attr:`~Window.flip()` should we wait for the
765
+ blank before the script continues.
766
+
767
+ """
768
+ self.__dict__['waitBlanking'] = value
769
+
770
+ @attributeSetter
771
+ def recordFrameIntervals(self, value):
772
+ """Record time elapsed per frame.
773
+
774
+ Provides accurate measures of frame intervals to determine
775
+ whether frames are being dropped. The intervals are the times between
776
+ calls to :py:attr:`~Window.flip()`. Set to `True` only during the
777
+ time-critical parts of the script. Set this to `False` while the screen
778
+ is not being updated, i.e., during any slow, non-frame-time-critical
779
+ sections of your code, including inter-trial-intervals,
780
+ ``event.waitkeys()``, ``core.wait()``, or ``image.setImage()``.
781
+
782
+ Examples
783
+ --------
784
+ Enable frame interval recording, successive frame intervals will be
785
+ stored::
786
+
787
+ win.recordFrameIntervals = True
788
+
789
+ Frame intervals can be saved by calling the
790
+ :py:attr:`~Window.saveFrameIntervals` method::
791
+
792
+ win.saveFrameIntervals()
793
+
794
+ """
795
+ # was off, and now turning it on
796
+ self.recordFrameIntervalsJustTurnedOn = bool(
797
+ not self.recordFrameIntervals and value)
798
+ self.__dict__['recordFrameIntervals'] = value
799
+ self.frameClock.reset()
800
+
801
+ def setRecordFrameIntervals(self, value=True, log=None):
802
+ """Usually you can use 'stim.attribute = value' syntax instead,
803
+ but use this method if you need to suppress the log message.
804
+ """
805
+ setAttribute(self, 'recordFrameIntervals', value, log)
806
+
807
+ def saveFrameIntervals(self, fileName=None, clear=True):
808
+ """Save recorded screen frame intervals to disk, as comma-separated
809
+ values.
810
+
811
+ Parameters
812
+ ----------
813
+ fileName : *None* or str
814
+ *None* or the filename (including path if necessary) in which to
815
+ store the data. If None then 'lastFrameIntervals.log' will be used.
816
+ clear : bool
817
+ Clear buffer frames intervals were stored after saving. Default is
818
+ `True`.
819
+
820
+ """
821
+ if not fileName:
822
+ fileName = 'lastFrameIntervals.log'
823
+ if len(self.frameIntervals):
824
+ intervalStr = str(self.frameIntervals)[1:-1]
825
+ f = open(fileName, 'w')
826
+ f.write(intervalStr)
827
+ f.close()
828
+ if clear:
829
+ self.frameIntervals = []
830
+ self.frameClock.reset()
831
+
832
+ def _setCurrent(self):
833
+ """Make this window's OpenGL context current.
834
+
835
+ If called on a window whose context is current, the function will return
836
+ immediately. This reduces the number of redundant calls if no context
837
+ switch is required. If ``useFBO=True``, the framebuffer is bound after
838
+ the context switch.
839
+
840
+ """
841
+ # don't configure if we haven't changed context
842
+ if not self.backend.setCurrent():
843
+ return
844
+
845
+ # if we are using an FBO, bind it
846
+ if hasattr(self, 'frameBuffer'):
847
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT,
848
+ self.frameBuffer)
849
+ GL.glReadBuffer(GL.GL_COLOR_ATTACHMENT0_EXT)
850
+ GL.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT)
851
+
852
+ # NB - check if we need these
853
+ GL.glActiveTexture(GL.GL_TEXTURE0)
854
+ GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
855
+
856
+ # set these to match the current window or buffer's settings
857
+ fbw, fbh = self.frameBufferSize
858
+ self.viewport = self.scissor = [0, 0, fbw, fbh]
859
+ self.scissorTest = True
860
+
861
+ # apply the view transforms for this window
862
+ #self.applyEyeTransform()
863
+
864
+ def onResize(self, width, height):
865
+ """A default resize event handler.
866
+
867
+ This default handler updates the GL viewport to cover the entire
868
+ window and sets the ``GL_PROJECTION`` matrix to be orthogonal in
869
+ window space. The bottom-left corner is (0, 0) and the top-right
870
+ corner is the width and height of the :class:`~psychopy.visual.Window`
871
+ in pixels.
872
+
873
+ Override this event handler with your own to create another
874
+ projection, for example in perspective.
875
+ """
876
+ # this has to be external so that pyglet can use it too without
877
+ # circular referencing
878
+ self.backend.onResize(width, height)
879
+
880
+ def logOnFlip(self, msg, level, obj=None):
881
+ """Send a log message that should be time-stamped at the next
882
+ :py:attr:`~Window.flip()` command.
883
+
884
+ Parameters
885
+ ----------
886
+ msg : str
887
+ The message to be logged.
888
+ level : int
889
+ The level of importance for the message.
890
+ obj : object, optional
891
+ The python object that might be associated with this message if
892
+ desired.
893
+
894
+ """
895
+ self._toLog.append({'msg': msg, 'level': level, 'obj': repr(obj)})
896
+
897
+ def callOnFlip(self, function, *args, **kwargs):
898
+ """Call a function immediately after the next :py:attr:`~Window.flip()`
899
+ command.
900
+
901
+ The first argument should be the function to call, the following args
902
+ should be used exactly as you would for your normal call to the
903
+ function (can use ordered arguments or keyword arguments as normal).
904
+
905
+ e.g. If you have a function that you would normally call like this::
906
+
907
+ pingMyDevice(portToPing, channel=2, level=0)
908
+
909
+ then you could call :py:attr:`~Window.callOnFlip()` to have the function
910
+ call synchronized with the frame flip like this::
911
+
912
+ win.callOnFlip(pingMyDevice, portToPing, channel=2, level=0)
913
+
914
+ """
915
+ self._toCall.append({'function': function,
916
+ 'args': args,
917
+ 'kwargs': kwargs})
918
+
919
+ def timeOnFlip(self, obj, attrib, format=float):
920
+ """Retrieves the time on the next flip and assigns it to the `attrib`
921
+ for this `obj`.
922
+
923
+ Parameters
924
+ ----------
925
+ obj : dict or object
926
+ A mutable object (usually a dict of class instance).
927
+ attrib : str
928
+ Key or attribute of `obj` to assign the flip time to.
929
+ format : str, class or None
930
+ Format in which to return time, see clock.Timestamp.resolve() for more info. Defaults to `float`.
931
+
932
+ Examples
933
+ --------
934
+ Assign time on flip to the ``tStartRefresh`` key of ``myTimingDict``::
935
+
936
+ win.getTimeOnFlip(myTimingDict, 'tStartRefresh')
937
+
938
+ """
939
+ self.callOnFlip(self._assignFlipTime, obj, attrib, format)
940
+
941
+ def getFutureFlipTime(self, targetTime=0, clock=None):
942
+ """The expected time of the next screen refresh. This is currently
943
+ calculated as win._lastFrameTime + refreshInterval
944
+
945
+ Parameters
946
+ -----------
947
+ targetTime: float
948
+ The delay *from now* for which you want the flip time. 0 will give the
949
+ because that the earliest we can achieve. 0.15 will give the schedule
950
+ flip time that gets as close to 150 ms as possible
951
+ clock : None, 'ptb', 'now' or any Clock object
952
+ If True then the time returned is compatible with ptb.GetSecs()
953
+ verbose: bool
954
+ Set to True to view the calculations along the way
955
+ """
956
+ baseClock = logging.defaultClock
957
+ if not self.monitorFramePeriod:
958
+ raise AttributeError("Cannot calculate nextFlipTime due to unknown "
959
+ "monitorFramePeriod")
960
+ lastFlip = self._frameTimes[-1] # unlike win.lastFrameTime this is always on
961
+ timeNext = lastFlip + self.monitorFramePeriod
962
+ now = baseClock.getTime()
963
+ if (now + targetTime) > timeNext: # target is more than 1 frame in future
964
+ extraFrames = math.ceil((now + targetTime - timeNext)/self.monitorFramePeriod)
965
+ thisT = timeNext + extraFrames*self.monitorFramePeriod
966
+ else:
967
+ thisT = timeNext
968
+ # convert back to target clock timebase
969
+ if clock=='ptb': # add back the lastResetTime (that's the clock difference)
970
+ output = thisT + baseClock.getLastResetTime()
971
+ elif clock=='now': # time from now is easy!
972
+ output = thisT - now
973
+ elif clock:
974
+ output = thisT + baseClock.getLastResetTime() - clock.getLastResetTime()
975
+ else:
976
+ output = thisT
977
+
978
+ return output
979
+
980
+ def _assignFlipTime(self, obj, attrib, format=float):
981
+ """Helper function to assign the time of last flip to the obj.attrib
982
+
983
+ Parameters
984
+ ----------
985
+ obj : dict or object
986
+ A mutable object (usually a dict of class instance).
987
+ attrib : str
988
+ Key or attribute of ``obj`` to assign the flip time to.
989
+ format : str, class or None
990
+ Format in which to return time, see clock.Timestamp.resolve() for more info. Defaults to `float`.
991
+
992
+ """
993
+ frameTime = self._frameTime.resolve(format=format)
994
+ if hasattr(obj, attrib):
995
+ setattr(obj, attrib, frameTime)
996
+ elif isinstance(obj, dict):
997
+ obj[attrib] = frameTime
998
+ else:
999
+ raise TypeError("Window.getTimeOnFlip() should be called with an "
1000
+ "object and its attribute or a dict and its key. "
1001
+ "In this case it was called with obj={}"
1002
+ .format(repr(obj)))
1003
+
1004
+ def _cleanEditables(self):
1005
+ """
1006
+ Make sure there are no dead refs in the editables list
1007
+ """
1008
+ for ref in self._editableChildren:
1009
+ obj = ref()
1010
+ if obj is None:
1011
+ self._editableChildren.remove(ref)
1012
+
1013
+ @property
1014
+ def currentEditable(self):
1015
+ """The editable (Text?) object that currently has key focus"""
1016
+ if self._currentEditableRef:
1017
+ return self._currentEditableRef()
1018
+
1019
+ @currentEditable.setter
1020
+ def currentEditable(self, editable):
1021
+ """Keeps the current editable stored as a weak ref"""
1022
+ # Ensure that item is added to editables list
1023
+ self.addEditable(editable)
1024
+
1025
+ # Set the editable as the current editable stim in the window
1026
+ eRef = None
1027
+ for ref in weakref.getweakrefs(editable):
1028
+ if ref in self._editableChildren:
1029
+ eRef = ref
1030
+ break
1031
+ if eRef:
1032
+ self._currentEditableRef = eRef
1033
+
1034
+ def addEditable(self, editable):
1035
+ """Adds an editable element to the screen (something to which
1036
+ characters can be sent with meaning from the keyboard).
1037
+
1038
+ The current editable object receiving chars is Window.currentEditable
1039
+
1040
+ :param editable:
1041
+ :return:
1042
+ """
1043
+ # Ignore if object is not editable
1044
+ if not hasattr(editable, "editable"):
1045
+ return
1046
+ if not editable.editable:
1047
+ return
1048
+ # If editable is already present do nothing
1049
+ eRef = False
1050
+ for ref in weakref.getweakrefs(editable):
1051
+ if ref in self._editableChildren:
1052
+ eRef = ref
1053
+ break
1054
+
1055
+ if eRef is False:
1056
+ eRef = weakref.ref(editable)
1057
+ # If editable is not already present, add it to the editables list
1058
+ self._editableChildren.append(eRef)
1059
+
1060
+ # If this is the first editable obj then make it the current
1061
+ if len(self._editableChildren) == 1:
1062
+ self._currentEditableRef = eRef
1063
+ # Clean editables list
1064
+ self._cleanEditables()
1065
+
1066
+ def removeEditable(self, editable):
1067
+ # If editable is present, remove it from editables list
1068
+ for ref in weakref.getweakrefs(editable):
1069
+ if ref in self._editableChildren:
1070
+ # If editable was current, move on to next current
1071
+ if self.currentEditable == editable:
1072
+ self.nextEditable()
1073
+ self._editableChildren.remove(ref)
1074
+ return True
1075
+ else:
1076
+ logging.warning(f"Request to remove editable object {editable} could not be completed as weakref "
1077
+ f"to this object could not be found in window.")
1078
+ # Clean editables list
1079
+ self._cleanEditables()
1080
+
1081
+ return False
1082
+
1083
+ def nextEditable(self):
1084
+ """Moves focus of the cursor to the next editable window"""
1085
+ # Clean editables list
1086
+ self._cleanEditables()
1087
+ # Progress
1088
+ if self.currentEditable is None:
1089
+ if len(self._editableChildren):
1090
+ self._currentEditableRef = self._editableChildren[0]
1091
+ else:
1092
+ for ref in weakref.getweakrefs(self.currentEditable):
1093
+ if ref in self._editableChildren:
1094
+ cei = self._editableChildren.index(ref)
1095
+ nei = cei+1
1096
+ if nei >= len(self._editableChildren):
1097
+ nei=0
1098
+ self._currentEditableRef = self._editableChildren[nei]
1099
+ return self.currentEditable
1100
+
1101
+ @classmethod
1102
+ def dispatchAllWindowEvents(cls):
1103
+ """
1104
+ Dispatches events for all pyglet windows. Used by iohub 2.0
1105
+ psychopy kb event integration.
1106
+ """
1107
+ Window.backend.dispatchEvents()
1108
+
1109
+ def clearAutoDraw(self):
1110
+ """
1111
+ Remove all autoDraw components, meaning they get autoDraw set to False and are not
1112
+ added to any list (as in .stashAutoDraw)
1113
+ """
1114
+ for thisStim in self._toDraw.copy():
1115
+ # set autoDraw to False
1116
+ thisStim.autoDraw = False
1117
+
1118
+ def stashAutoDraw(self):
1119
+ """
1120
+ Put autoDraw components on 'hold', meaning they get autoDraw set to False but
1121
+ are added to an internal list to be 'released' when .releaseAutoDraw is called.
1122
+ """
1123
+ for thisStim in self._toDraw.copy():
1124
+ # set autoDraw to False
1125
+ thisStim.autoDraw = False
1126
+ # add stim to held list
1127
+ self._heldDraw.append(thisStim)
1128
+
1129
+ def retrieveAutoDraw(self):
1130
+ """
1131
+ Add all stimuli which are on 'hold' back into the autoDraw list, and clear the
1132
+ hold list.
1133
+ """
1134
+ for thisStim in self._heldDraw:
1135
+ # set autoDraw to True
1136
+ thisStim.autoDraw = True
1137
+ # clear list
1138
+ self._heldDraw = []
1139
+
1140
+ def flip(self, clearBuffer=True):
1141
+ """Flip the front and back buffers after drawing everything for your
1142
+ frame. (This replaces the :py:attr:`~Window.update()` method, better
1143
+ reflecting what is happening underneath).
1144
+
1145
+ Parameters
1146
+ ----------
1147
+ clearBuffer : bool, optional
1148
+ Clear the draw buffer after flipping. Default is `True`.
1149
+
1150
+ Returns
1151
+ -------
1152
+ float or None
1153
+ Wall-clock time in seconds the flip completed. Returns `None` if
1154
+ :py:attr:`~Window.waitBlanking` is `False`.
1155
+
1156
+ Notes
1157
+ -----
1158
+ * The time returned when :py:attr:`~Window.waitBlanking` is `True`
1159
+ corresponds to when the graphics driver releases the draw buffer to
1160
+ accept draw commands again. This time is usually close to the vertical
1161
+ sync signal of the display.
1162
+
1163
+ Examples
1164
+ --------
1165
+
1166
+ Results in a clear screen after flipping::
1167
+
1168
+ win.flip(clearBuffer=True)
1169
+
1170
+ The screen is not cleared (so represent the previous screen)::
1171
+
1172
+ win.flip(clearBuffer=False)
1173
+
1174
+ """
1175
+ # draw message/splash if needed
1176
+ if self._showSplash:
1177
+ self._splashTextbox.draw()
1178
+
1179
+ if self._toDraw:
1180
+ for thisStim in self._toDraw:
1181
+ # draw
1182
+ thisStim.draw()
1183
+ # draw validation rect if needed
1184
+ if thisStim in self.validators:
1185
+ self.validators[thisStim].draw()
1186
+ # handle dragging
1187
+ if getattr(thisStim, "draggable", False):
1188
+ thisStim.doDragging()
1189
+ else:
1190
+ self.backend.setCurrent()
1191
+
1192
+ # set these to match the current window or buffer's settings
1193
+ self.viewport = self.scissor = \
1194
+ (0, 0, self.frameBufferSize[0], self.frameBufferSize[1])
1195
+ if not self.scissorTest:
1196
+ self.scissorTest = True
1197
+
1198
+ # clear the projection and modelview matrix for FBO blit
1199
+ GL.glMatrixMode(GL.GL_PROJECTION)
1200
+ GL.glLoadIdentity()
1201
+ GL.glOrtho(-1, 1, -1, 1, -1, 1)
1202
+ GL.glMatrixMode(GL.GL_MODELVIEW)
1203
+ GL.glLoadIdentity()
1204
+
1205
+ # disable lighting
1206
+ self.useLights = False
1207
+
1208
+ # Check for mouse clicks on editables
1209
+ if hasattr(self, '_editableChildren'):
1210
+ # Make sure _editableChildren has actually been created
1211
+ editablesOnScreen = []
1212
+ for thisObj in self._editableChildren:
1213
+ # Iterate through editables and decide which one should have focus
1214
+ if isinstance(thisObj, weakref.ref):
1215
+ # Solidify weakref if necessary
1216
+ thisObj = thisObj()
1217
+ if thisObj is None:
1218
+ continue
1219
+ if isinstance(thisObj.autoDraw, (bool, int, float)):
1220
+ # Store whether this editable is on screen
1221
+ editablesOnScreen.append(thisObj.autoDraw)
1222
+ else:
1223
+ editablesOnScreen.append(False)
1224
+ if self._mouse.isPressedIn(thisObj):
1225
+ # If editable was clicked on, give it focus
1226
+ self.currentEditable = thisObj
1227
+ # If there is only one editable on screen, make sure it starts off with focus
1228
+ if sum(editablesOnScreen) == 1:
1229
+ self.currentEditable = self._editableChildren[editablesOnScreen.index(True)]()
1230
+
1231
+ flipThisFrame = self._startOfFlip()
1232
+ if self.useFBO and flipThisFrame:
1233
+ self.draw3d = False # disable 3d drawing
1234
+ self._prepareFBOrender()
1235
+ # need blit the framebuffer object to the actual back buffer
1236
+
1237
+ # unbind the framebuffer as the render target
1238
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0)
1239
+ GL.glDisable(GL.GL_BLEND)
1240
+ stencilOn = self.stencilTest
1241
+ self.stencilTest = False
1242
+
1243
+ if self.bits is not None:
1244
+ self.bits._prepareFBOrender()
1245
+
1246
+ # before flipping need to copy the renderBuffer to the
1247
+ # frameBuffer
1248
+ GL.glActiveTexture(GL.GL_TEXTURE0)
1249
+ GL.glEnable(GL.GL_TEXTURE_2D)
1250
+ GL.glBindTexture(GL.GL_TEXTURE_2D, self.frameTexture)
1251
+ GL.glColor3f(1.0, 1.0, 1.0) # glColor multiplies with texture
1252
+ GL.glColorMask(True, True, True, True)
1253
+
1254
+ self._renderFBO()
1255
+
1256
+ GL.glEnable(GL.GL_BLEND)
1257
+ self._finishFBOrender()
1258
+
1259
+ # call this before flip() whether FBO was used or not
1260
+ self._afterFBOrender()
1261
+
1262
+ self.backend.swapBuffers(flipThisFrame)
1263
+
1264
+ if self.useFBO and flipThisFrame:
1265
+ # set rendering back to the framebuffer object
1266
+ GL.glBindFramebufferEXT(
1267
+ GL.GL_FRAMEBUFFER_EXT, self.frameBuffer)
1268
+ GL.glReadBuffer(GL.GL_COLOR_ATTACHMENT0_EXT)
1269
+ GL.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT)
1270
+ # set to no active rendering texture
1271
+ GL.glActiveTexture(GL.GL_TEXTURE0)
1272
+ GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
1273
+ if stencilOn:
1274
+ self.stencilTest = True
1275
+
1276
+ # rescale, reposition, & rotate
1277
+ GL.glMatrixMode(GL.GL_MODELVIEW)
1278
+ GL.glLoadIdentity()
1279
+ if self.viewScale is not None:
1280
+ GL.glScalef(self.viewScale[0], self.viewScale[1], 1)
1281
+ absScaleX = abs(self.viewScale[0])
1282
+ absScaleY = abs(self.viewScale[1])
1283
+ else:
1284
+ absScaleX, absScaleY = 1, 1
1285
+
1286
+ if self.viewPos is not None:
1287
+ # here we must use normalised units in _viewPosNorm,
1288
+ # see the corresponding attributeSetter above
1289
+ normRfPosX = self._viewPosNorm[0] / absScaleX
1290
+ normRfPosY = self._viewPosNorm[1] / absScaleY
1291
+
1292
+ GL.glTranslatef(normRfPosX, normRfPosY, 0.0)
1293
+
1294
+ if self.viewOri: # float
1295
+ # the logic below for flip is partially correct, but does not
1296
+ # handle a nonzero viewPos
1297
+ flip = 1
1298
+ if self.viewScale is not None:
1299
+ _f = self.viewScale[0] * self.viewScale[1]
1300
+ if _f < 0:
1301
+ flip = -1
1302
+ GL.glRotatef(flip * self.viewOri, 0.0, 0.0, -1.0)
1303
+
1304
+ # reset returned buffer for next frame
1305
+ self._endOfFlip(clearBuffer)
1306
+
1307
+ # waitBlanking
1308
+ if self.waitBlanking and flipThisFrame:
1309
+ GL.glBegin(GL.GL_POINTS)
1310
+ GL.glColor4f(0, 0, 0, 0)
1311
+ if sys.platform == 'win32' and self.glVendor.startswith('ati'):
1312
+ pass
1313
+ else:
1314
+ # this corrupts text rendering on win with some ATI cards :-(
1315
+ GL.glVertex2i(10, 10)
1316
+ GL.glEnd()
1317
+ GL.glFinish()
1318
+
1319
+ # get timestamp
1320
+ self._frameTime = now = logging.defaultClock.getTime()
1321
+ self._frameTimes.append(self._frameTime)
1322
+
1323
+ # run other functions immediately after flip completes
1324
+ for callEntry in self._toCall:
1325
+ callEntry['function'](*callEntry['args'], **callEntry['kwargs'])
1326
+ del self._toCall[:]
1327
+
1328
+ # do bookkeeping
1329
+ if self.recordFrameIntervals:
1330
+ self.frames += 1
1331
+ deltaT = now - self.lastFrameT
1332
+ self.lastFrameT = now
1333
+
1334
+ if self.recordFrameIntervalsJustTurnedOn: # don't do anything
1335
+ self.recordFrameIntervalsJustTurnedOn = False
1336
+ else: # past the first frame since turned on
1337
+ self.frameIntervals.append(deltaT)
1338
+ if deltaT > self.refreshThreshold:
1339
+ self.nDroppedFrames += 1
1340
+ if self.nDroppedFrames < reportNDroppedFrames:
1341
+ txt = 't of last frame was %.2fms (=1/%i)'
1342
+ msg = txt % (deltaT * 1000, 1 / deltaT)
1343
+ logging.warning(msg, t=now)
1344
+ elif self.nDroppedFrames == reportNDroppedFrames:
1345
+ logging.warning("Multiple dropped frames have "
1346
+ "occurred - I'll stop bothering you "
1347
+ "about them!")
1348
+
1349
+ # log events
1350
+ for logEntry in self._toLog:
1351
+ # {'msg':msg, 'level':level, 'obj':copy.copy(obj)}
1352
+ logging.log(msg=logEntry['msg'],
1353
+ level=logEntry['level'],
1354
+ t=now,
1355
+ obj=logEntry['obj'])
1356
+ del self._toLog[:]
1357
+
1358
+ # keep the system awake (prevent screen-saver or sleep)
1359
+ platform_specific.sendStayAwake()
1360
+
1361
+ # draw background (if present) for next frame
1362
+ if hasattr(self.backgroundImage, "draw"):
1363
+ self.backgroundImage.draw()
1364
+
1365
+ # draw piloting indicator (if piloting) for next frame
1366
+ if self._showPilotingIndicator:
1367
+ self._pilotingIndicator.draw()
1368
+
1369
+ # If self.waitBlanking is True, then return the time that
1370
+ # GL.glFinish() returned, set as the 'now' variable. Otherwise
1371
+ # return None as before
1372
+ #
1373
+ if self.waitBlanking is True:
1374
+ return now
1375
+
1376
+ def update(self):
1377
+ """Deprecated: use Window.flip() instead
1378
+ """
1379
+ # clearBuffer was the original behaviour for win.update()
1380
+ self.flip(clearBuffer=True)
1381
+
1382
+ def multiFlip(self, flips=1, clearBuffer=True):
1383
+ """Flip multiple times while maintaining the display constant.
1384
+ Use this method for precise timing.
1385
+
1386
+ **WARNING:** This function should not be used. See the `Notes` section
1387
+ for details.
1388
+
1389
+ Parameters
1390
+ ----------
1391
+ flips : int, optional
1392
+ The number of monitor frames to flip. Floats will be
1393
+ rounded to integers, and a warning will be emitted.
1394
+ ``Window.multiFlip(flips=1)`` is equivalent to ``Window.flip()``.
1395
+ Defaults to `1`.
1396
+ clearBuffer : bool, optional
1397
+ Whether to clear the screen after the last flip.
1398
+ Defaults to `True`.
1399
+
1400
+ Notes
1401
+ -----
1402
+ - This function can behave unpredictably, and the PsychoPy authors
1403
+ recommend against using it. See
1404
+ https://github.com/psychopy/psychopy/issues/867 for more information.
1405
+
1406
+ Examples
1407
+ --------
1408
+ Example of using ``multiFlip``::
1409
+
1410
+ # Draws myStim1 to buffer
1411
+ myStim1.draw()
1412
+ # Show stimulus for 4 frames (90 ms at 60Hz)
1413
+ myWin.multiFlip(clearBuffer=False, flips=6)
1414
+ # Draw myStim2 "on top of" myStim1
1415
+ # (because buffer was not cleared above)
1416
+ myStim2.draw()
1417
+ # Show this for 2 frames (30 ms at 60Hz)
1418
+ myWin.multiFlip(flips=2)
1419
+ # Show blank screen for 3 frames (buffer was cleared above)
1420
+ myWin.multiFlip(flips=3)
1421
+
1422
+ """
1423
+ if flips < 1:
1424
+ logging.error("flips argument for multiFlip should be "
1425
+ "a positive integer")
1426
+
1427
+ if flips != int(flips):
1428
+ flips = int(round(flips))
1429
+ logging.warning("Number of flips was not an integer; "
1430
+ "rounding to the next integer. Will flip "
1431
+ "%i times." % flips)
1432
+
1433
+ if flips > 1 and not self.waitBlanking:
1434
+ logging.warning("Call to Window.multiFlip() with flips > 1 is "
1435
+ "unnecessary because Window.waitBlanking=False")
1436
+
1437
+ # Do the flipping with last flip as special case
1438
+ for _ in range(flips - 1):
1439
+ self.flip(clearBuffer=False)
1440
+ self.flip(clearBuffer=clearBuffer)
1441
+
1442
+
1443
+
1444
+ def setBuffer(self, buffer, clear=True):
1445
+ """Choose which buffer to draw to ('left' or 'right').
1446
+
1447
+ Requires the Window to be initialised with stereo=True and requires a
1448
+ graphics card that supports quad buffering (e,g nVidia Quadro series)
1449
+
1450
+ PsychoPy always draws to the back buffers, so 'left' will use
1451
+ ``GL_BACK_LEFT`` This then needs to be flipped once both eye's buffers
1452
+ have been rendered.
1453
+
1454
+ Parameters
1455
+ ----------
1456
+ buffer : str
1457
+ Buffer to draw to. Can either be 'left' or 'right'.
1458
+ clear : bool, optional
1459
+ Clear the buffer before drawing. Default is ``True``.
1460
+
1461
+ Examples
1462
+ --------
1463
+ Stereoscopic rendering example using quad-buffers::
1464
+
1465
+ win = visual.Window(...., stereo=True)
1466
+ while True:
1467
+ # clear may not actually be needed
1468
+ win.setBuffer('left', clear=True)
1469
+ # do drawing for left eye
1470
+ win.setBuffer('right', clear=True)
1471
+ # do drawing for right eye
1472
+ win.flip()
1473
+
1474
+ """
1475
+ if buffer == 'left':
1476
+ GL.glDrawBuffer(GL.GL_BACK_LEFT)
1477
+ elif buffer == 'right':
1478
+ GL.glDrawBuffer(GL.GL_BACK_RIGHT)
1479
+ else:
1480
+ raise "Unknown buffer '%s' requested in Window.setBuffer" % buffer
1481
+ if clear:
1482
+ self.clearBuffer()
1483
+
1484
+ def clearBuffer(self, color=True, depth=False, stencil=False):
1485
+ """Clear the present buffer (to which you are currently drawing) without
1486
+ flipping the window.
1487
+
1488
+ Useful if you want to generate movie sequences from the back buffer
1489
+ without actually taking the time to flip the window.
1490
+
1491
+ Set `color` prior to clearing to set the color to clear the color buffer
1492
+ to. By default, the depth buffer is cleared to a value of 1.0.
1493
+
1494
+ Parameters
1495
+ ----------
1496
+ color, depth, stencil : bool
1497
+ Buffers to clear.
1498
+
1499
+ Examples
1500
+ --------
1501
+ Clear the color buffer to a specified color::
1502
+
1503
+ win.color = (1, 0, 0)
1504
+ win.clearBuffer(color=True)
1505
+
1506
+ Clear only the depth buffer, `depthMask` must be `True` or else this
1507
+ will have no effect. Depth mask is usually `True` by default, but
1508
+ may change::
1509
+
1510
+ win.depthMask = True
1511
+ win.clearBuffer(color=False, depth=True, stencil=False)
1512
+
1513
+ """
1514
+ clearBufferBits = GL.GL_NONE
1515
+
1516
+ if color:
1517
+ clearBufferBits |= GL.GL_COLOR_BUFFER_BIT
1518
+
1519
+ if depth:
1520
+ clearBufferBits |= GL.GL_DEPTH_BUFFER_BIT
1521
+
1522
+ if stencil:
1523
+ clearBufferBits |= GL.GL_STENCIL_BUFFER_BIT
1524
+
1525
+ # reset returned buffer for next frame
1526
+ GL.glClear(clearBufferBits)
1527
+
1528
+ @property
1529
+ def size(self):
1530
+ """Size of the drawable area in pixels (w, h)."""
1531
+ # report clientSize until we get framebuffer size from
1532
+ # the backend, needs to be done properly in the future
1533
+ if self.backend is not None:
1534
+ return self.viewport[2:]
1535
+ else:
1536
+ return self.clientSize
1537
+
1538
+ @property
1539
+ def frameBufferSize(self):
1540
+ """Size of the framebuffer in pixels (w, h)."""
1541
+ # Dimensions should match window size unless using a retina display
1542
+ return self.backend.frameBufferSize
1543
+
1544
+ @property
1545
+ def windowedSize(self):
1546
+ """Size of the window to use when not fullscreen (w, h)."""
1547
+ return self._windowedSize
1548
+
1549
+ @windowedSize.setter
1550
+ def windowedSize(self, value):
1551
+ """Size of the window to use when not fullscreen (w, h)."""
1552
+ self._windowedSize[:] = value
1553
+
1554
+ def getContentScaleFactor(self):
1555
+ """Get the scaling factor required for scaling correctly on high-DPI
1556
+ displays.
1557
+
1558
+ If the returned value is 1.0, no scaling needs to be applied to objects
1559
+ drawn on the backbuffer. A value >1.0 indicates that the backbuffer is
1560
+ larger than the reported client area, requiring points to be scaled to
1561
+ maintain constant size across similarly sized displays. In other words,
1562
+ the scaling required to convert framebuffer to client coordinates.
1563
+
1564
+ Returns
1565
+ -------
1566
+ float
1567
+ Scaling factor to be applied along both horizontal and vertical
1568
+ dimensions.
1569
+
1570
+ Examples
1571
+ --------
1572
+ Get the size of the client area::
1573
+
1574
+ clientSize = win.frameBufferSize / win.getContentScaleFactor()
1575
+
1576
+ Get the framebuffer size from the client size::
1577
+
1578
+ frameBufferSize = win.clientSize * win.getContentScaleFactor()
1579
+
1580
+ Convert client (window) to framebuffer pixel coordinates (eg., a mouse
1581
+ coordinate, vertices, etc.)::
1582
+
1583
+ # `mousePosXY` is an array ...
1584
+ frameBufferXY = mousePosXY * win.getContentScaleFactor()
1585
+ # you can also use the attribute ...
1586
+ frameBufferXY = mousePosXY * win.contentScaleFactor
1587
+
1588
+ Notes
1589
+ -----
1590
+ * This value is only valid after the window has been fully realized.
1591
+
1592
+ """
1593
+ # this might be accessed at lots of points, probably shouldn't compute
1594
+ # this all the time
1595
+ if self._contentScaleFactor is not None:
1596
+ return self._contentScaleFactor
1597
+
1598
+ sx = self.frameBufferSize[0] / float(self.clientSize[0])
1599
+ sy = self.frameBufferSize[1] / float(self.clientSize[1])
1600
+
1601
+ if sx != sy: # messed up DPI settings return 1.0 and show warning
1602
+ self._contentScaleFactor = 1.0
1603
+ else:
1604
+ self._contentScaleFactor = sx
1605
+
1606
+ return self._contentScaleFactor
1607
+
1608
+ @property
1609
+ def contentScaleFactor(self):
1610
+ """Scaling factor (`float`) to use when drawing to the backbuffer to
1611
+ convert framebuffer to client coordinates.
1612
+
1613
+ See Also
1614
+ --------
1615
+ getContentScaleFactor
1616
+
1617
+ """
1618
+ return self.getContentScaleFactor()
1619
+
1620
+ @property
1621
+ def aspect(self):
1622
+ """Aspect ratio of the current viewport (width / height)."""
1623
+ return self._viewport[2] / float(self._viewport[3])
1624
+
1625
+ @property
1626
+ def ambientLight(self):
1627
+ """Ambient light color for the scene [r, g, b, a]. Values range from 0.0
1628
+ to 1.0. Only applicable if `useLights` is `True`.
1629
+
1630
+ Examples
1631
+ --------
1632
+ Setting the ambient light color::
1633
+
1634
+ win.ambientLight = [0.5, 0.5, 0.5]
1635
+
1636
+ # don't do this!!!
1637
+ win.ambientLight[0] = 0.5
1638
+ win.ambientLight[1] = 0.5
1639
+ win.ambientLight[2] = 0.5
1640
+
1641
+ """
1642
+ # TODO - use signed color and colorspace instead
1643
+ return self._ambientLight[:3]
1644
+
1645
+ @ambientLight.setter
1646
+ def ambientLight(self, value):
1647
+ self._ambientLight[:3] = value
1648
+ GL.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT,
1649
+ numpy.ctypeslib.as_ctypes(self._ambientLight))
1650
+
1651
+ @property
1652
+ def lights(self):
1653
+ """Scene lights.
1654
+
1655
+ This is specified as an array of `~psychopy.visual.LightSource`
1656
+ objects. If a single value is given, it will be converted to a `list`
1657
+ before setting. Set `useLights` to `True` before rendering to enable
1658
+ lighting/shading on subsequent objects. If `lights` is `None` or an
1659
+ empty `list`, no lights will be enabled if `useLights=True`, however,
1660
+ the scene ambient light set with `ambientLight` will be still be used.
1661
+
1662
+ Examples
1663
+ --------
1664
+ Create a directional light source and add it to scene lights::
1665
+
1666
+ dirLight = gltools.LightSource((0., 1., 0.), lightType='directional')
1667
+ win.lights = dirLight # `win.lights` will be a list when accessed!
1668
+
1669
+ Multiple lights can be specified by passing values as a list::
1670
+
1671
+ myLights = [gltools.LightSource((0., 5., 0.)),
1672
+ gltools.LightSource((-2., -2., 0.))
1673
+ win.lights = myLights
1674
+
1675
+ """
1676
+ return self._lights
1677
+
1678
+ @lights.setter
1679
+ def lights(self, value):
1680
+ # if None or empty list, disable all lights
1681
+ if value is None or not value:
1682
+ for index in range(self._nLights):
1683
+ GL.glDisable(GL.GL_LIGHT0 + index)
1684
+
1685
+ self._nLights = 0 # set number of lights to zero
1686
+ self._lights = value
1687
+
1688
+ return
1689
+
1690
+ # set the lights and make sure it's a list if a single value was passed
1691
+ self._lights = value if isinstance(value, (list, tuple,)) else [value]
1692
+
1693
+ # disable excess lights if less lights were specified this time
1694
+ oldNumLights = self._nLights
1695
+ self._nLights = len(self._lights) # number of lights enabled
1696
+ if oldNumLights > self._nLights:
1697
+ for index in range(self._nLights, oldNumLights):
1698
+ GL.glDisable(GL.GL_LIGHT0 + index)
1699
+
1700
+ # Setup legacy lights, new spec shader programs should access the
1701
+ # `lights` attribute directly to setup lighting uniforms.
1702
+ # The index of the lights is defined by the order it appears in
1703
+ # `self._lights`.
1704
+ for index, light in enumerate(self._lights):
1705
+ enumLight = GL.GL_LIGHT0 + index
1706
+
1707
+ # convert data in light class to ctypes
1708
+ #pos = numpy.ctypeslib.as_ctypes(light.pos)
1709
+ diffuse = numpy.ctypeslib.as_ctypes(light._diffuseRGB)
1710
+ specular = numpy.ctypeslib.as_ctypes(light._specularRGB)
1711
+ ambient = numpy.ctypeslib.as_ctypes(light._ambientRGB)
1712
+
1713
+ # pass values to OpenGL
1714
+ #GL.glLightfv(enumLight, GL.GL_POSITION, pos)
1715
+ GL.glLightfv(enumLight, GL.GL_DIFFUSE, diffuse)
1716
+ GL.glLightfv(enumLight, GL.GL_SPECULAR, specular)
1717
+ GL.glLightfv(enumLight, GL.GL_AMBIENT, ambient)
1718
+
1719
+ constant, linear, quadratic = light._kAttenuation
1720
+ GL.glLightf(enumLight, GL.GL_CONSTANT_ATTENUATION, constant)
1721
+ GL.glLightf(enumLight, GL.GL_LINEAR_ATTENUATION, linear)
1722
+ GL.glLightf(enumLight, GL.GL_QUADRATIC_ATTENUATION, quadratic)
1723
+
1724
+ # enable the light
1725
+ GL.glEnable(enumLight)
1726
+
1727
+ @property
1728
+ def useLights(self):
1729
+ """Enable scene lighting.
1730
+
1731
+ Lights will be enabled if using legacy OpenGL lighting. Stimuli using
1732
+ shaders for lighting should check if `useLights` is `True` since this
1733
+ will have no effect on them, and disable or use a no lighting shader
1734
+ instead. Lights will be transformed to the current view matrix upon
1735
+ setting to `True`.
1736
+
1737
+ Lights are transformed by the present `GL_MODELVIEW` matrix. Setting
1738
+ `useLights` will result in their positions being transformed by it.
1739
+ If you want lights to appear at the specified positions in world space,
1740
+ make sure the current matrix defines the view/eye transformation when
1741
+ setting `useLights=True`.
1742
+
1743
+ This flag is reset to `False` at the beginning of each frame. Should be
1744
+ `False` if rendering 2D stimuli or else the colors will be incorrect.
1745
+ """
1746
+ return self._useLights
1747
+
1748
+ @useLights.setter
1749
+ def useLights(self, value):
1750
+ self._useLights = value
1751
+
1752
+ # Setup legacy lights, new spec shader programs should access the
1753
+ # `lights` attribute directly to setup lighting uniforms.
1754
+ if self._useLights and self._lights:
1755
+ GL.glEnable(GL.GL_LIGHTING)
1756
+ # make sure specular lights are computed relative to eye position,
1757
+ # this is more realistic than the default. Does not affect shaders.
1758
+ GL.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_TRUE)
1759
+
1760
+ # update light positions for current model matrix
1761
+ for index, light in enumerate(self._lights):
1762
+ enumLight = GL.GL_LIGHT0 + index
1763
+ pos = numpy.ctypeslib.as_ctypes(light.pos)
1764
+ GL.glLightfv(enumLight, GL.GL_POSITION, pos)
1765
+ else:
1766
+ # disable lights
1767
+ GL.glDisable(GL.GL_LIGHTING)
1768
+
1769
+ def updateLights(self, index=None):
1770
+ """Explicitly update scene lights if they were modified.
1771
+
1772
+ This is required if modifications to objects referenced in `lights` have
1773
+ been changed since assignment. If you removed or added items of `lights`
1774
+ you must refresh all of them.
1775
+
1776
+ Parameters
1777
+ ----------
1778
+ index : int, optional
1779
+ Index of light source in `lights` to update. If `None`, all lights
1780
+ will be refreshed.
1781
+
1782
+ Examples
1783
+ --------
1784
+ Call `updateLights` if you modified lights directly like this::
1785
+
1786
+ win.lights[1].diffuseColor = [1., 0., 0.]
1787
+ win.updateLights(1)
1788
+
1789
+ """
1790
+ if self._lights is None:
1791
+ return # nop if there are no lights
1792
+
1793
+ if index is None:
1794
+ self.lights = self._lights
1795
+ else:
1796
+ if index > len(self._lights) - 1:
1797
+ raise IndexError('Invalid index for `lights`.')
1798
+
1799
+ enumLight = GL.GL_LIGHT0 + index
1800
+
1801
+ # light object to modify
1802
+ light = self._lights[index]
1803
+
1804
+ # convert data in light class to ctypes
1805
+ # pos = numpy.ctypeslib.as_ctypes(light.pos)
1806
+ diffuse = numpy.ctypeslib.as_ctypes(light.diffuse)
1807
+ specular = numpy.ctypeslib.as_ctypes(light.specular)
1808
+ ambient = numpy.ctypeslib.as_ctypes(light.ambient)
1809
+
1810
+ # pass values to OpenGL
1811
+ # GL.glLightfv(enumLight, GL.GL_POSITION, pos)
1812
+ GL.glLightfv(enumLight, GL.GL_DIFFUSE, diffuse)
1813
+ GL.glLightfv(enumLight, GL.GL_SPECULAR, specular)
1814
+ GL.glLightfv(enumLight, GL.GL_AMBIENT, ambient)
1815
+
1816
+ def resetViewport(self):
1817
+ """Reset the viewport to cover the whole framebuffer.
1818
+
1819
+ Set the viewport to match the dimensions of the back buffer or
1820
+ framebuffer (if `useFBO=True`). The scissor rectangle is also set to
1821
+ match the dimensions of the viewport.
1822
+
1823
+ """
1824
+ # use the framebuffer size here, not the window size (hi-dpi compat)
1825
+ bufferWidth, bufferHeight = self.frameBufferSize
1826
+ self.scissor = self.viewport = [0, 0, bufferWidth, bufferHeight]
1827
+
1828
+ @property
1829
+ def viewport(self):
1830
+ """Viewport rectangle (x, y, w, h) for the current draw buffer.
1831
+
1832
+ Values `x` and `y` define the origin, and `w` and `h` the size of the
1833
+ rectangle in pixels.
1834
+
1835
+ This is typically set to cover the whole buffer, however it can be
1836
+ changed for applications like multi-view rendering. Stimuli will draw
1837
+ according to the new shape of the viewport, for instance and stimulus
1838
+ with position (0, 0) will be drawn at the center of the viewport, not
1839
+ the window.
1840
+
1841
+ Examples
1842
+ --------
1843
+ Constrain drawing to the left and right halves of the screen, where
1844
+ stimuli will be drawn centered on the new rectangle. Note that you need
1845
+ to set both the `viewport` and the `scissor` rectangle::
1846
+
1847
+ x, y, w, h = win.frameBufferSize # size of the framebuffer
1848
+ win.viewport = win.scissor = [x, y, w / 2.0, h]
1849
+ # draw left stimuli ...
1850
+
1851
+ win.viewport = win.scissor = [x + (w / 2.0), y, w / 2.0, h]
1852
+ # draw right stimuli ...
1853
+
1854
+ # restore drawing to the whole screen
1855
+ win.viewport = win.scissor = [x, y, w, h]
1856
+
1857
+ """
1858
+ return self._viewport
1859
+
1860
+ @viewport.setter
1861
+ def viewport(self, value):
1862
+ self._viewport = numpy.array(value, int)
1863
+ GL.glViewport(*self._viewport)
1864
+
1865
+ @property
1866
+ def scissor(self):
1867
+ """Scissor rectangle (x, y, w, h) for the current draw buffer.
1868
+
1869
+ Values `x` and `y` define the origin, and `w` and `h` the size
1870
+ of the rectangle in pixels. The scissor operation is only active
1871
+ if `scissorTest=True`.
1872
+
1873
+ Usually, the scissor and viewport are set to the same rectangle
1874
+ to prevent drawing operations from `spilling` into other regions
1875
+ of the screen. For instance, calling `clearBuffer` will only
1876
+ clear within the scissor rectangle.
1877
+
1878
+ Setting the scissor rectangle but not the viewport will restrict
1879
+ drawing within the defined region (like a rectangular aperture),
1880
+ not changing the positions of stimuli.
1881
+
1882
+ """
1883
+ return self._scissor
1884
+
1885
+ @scissor.setter
1886
+ def scissor(self, value):
1887
+ self._scissor = numpy.array(value, int)
1888
+ GL.glScissor(*self._scissor)
1889
+
1890
+ @property
1891
+ def scissorTest(self):
1892
+ """`True` if scissor testing is enabled."""
1893
+ return self._scissorTest
1894
+
1895
+ @scissorTest.setter
1896
+ def scissorTest(self, value):
1897
+ if value is True:
1898
+ GL.glEnable(GL.GL_SCISSOR_TEST)
1899
+ elif value is False:
1900
+ GL.glDisable(GL.GL_SCISSOR_TEST)
1901
+ else:
1902
+ raise TypeError("Value must be boolean.")
1903
+
1904
+ self._scissorTest = value
1905
+
1906
+ @property
1907
+ def stencilTest(self):
1908
+ """`True` if stencil testing is enabled."""
1909
+ return self._stencilTest
1910
+
1911
+ @stencilTest.setter
1912
+ def stencilTest(self, value):
1913
+ if value is True:
1914
+ GL.glEnable(GL.GL_STENCIL_TEST)
1915
+ elif value is False:
1916
+ GL.glDisable(GL.GL_STENCIL_TEST)
1917
+ else:
1918
+ raise TypeError("Value must be boolean.")
1919
+
1920
+ self._stencilTest = value
1921
+
1922
+ @property
1923
+ def nearClip(self):
1924
+ """Distance to the near clipping plane in meters."""
1925
+ return self._nearClip
1926
+
1927
+ @nearClip.setter
1928
+ def nearClip(self, value):
1929
+ self._nearClip = value
1930
+
1931
+ @property
1932
+ def farClip(self):
1933
+ """Distance to the far clipping plane in meters."""
1934
+ return self._farClip
1935
+
1936
+ @farClip.setter
1937
+ def farClip(self, value):
1938
+ self._farClip = value
1939
+
1940
+ @property
1941
+ def projectionMatrix(self):
1942
+ """Projection matrix defined as a 4x4 numpy array."""
1943
+ return self._projectionMatrix
1944
+
1945
+ @projectionMatrix.setter
1946
+ def projectionMatrix(self, value):
1947
+ self._projectionMatrix = numpy.asarray(value, numpy.float32)
1948
+ assert self._projectionMatrix.shape == (4, 4)
1949
+
1950
+ @property
1951
+ def viewMatrix(self):
1952
+ """View matrix defined as a 4x4 numpy array."""
1953
+ return self._viewMatrix
1954
+
1955
+ @viewMatrix.setter
1956
+ def viewMatrix(self, value):
1957
+ self._viewMatrix = numpy.asarray(value, numpy.float32)
1958
+ assert self._viewMatrix.shape == (4, 4)
1959
+
1960
+ @property
1961
+ def eyeOffset(self):
1962
+ """Eye offset in centimeters.
1963
+
1964
+ This value is used by `setPerspectiveView` to apply a lateral
1965
+ offset to the view, therefore it must be set prior to calling it. Use a
1966
+ positive offset for the right eye, and a negative one for the left.
1967
+ Offsets should be the distance to from the middle of the face to the
1968
+ center of the eye, or half the inter-ocular distance.
1969
+
1970
+ """
1971
+ return self._eyeOffset * 100.0
1972
+
1973
+ @eyeOffset.setter
1974
+ def eyeOffset(self, value):
1975
+ self._eyeOffset = value / 100.0
1976
+
1977
+ @property
1978
+ def convergeOffset(self):
1979
+ """Convergence offset from monitor in centimeters.
1980
+
1981
+ This is value corresponds to the offset from screen plane to set the
1982
+ convergence plane (or point for `toe-in` projections). Positive offsets
1983
+ move the plane farther away from the viewer, while negative offsets
1984
+ nearer. This value is used by `setPerspectiveView` and should be set
1985
+ before calling it to take effect.
1986
+
1987
+ Notes
1988
+ -----
1989
+ * This value is only applicable for `setToeIn` and `setOffAxisView`.
1990
+
1991
+ """
1992
+ return self._convergeOffset * 100.0
1993
+
1994
+ @convergeOffset.setter
1995
+ def convergeOffset(self, value):
1996
+ self._convergeOffset = value / 100.0
1997
+
1998
+ def setOffAxisView(self, applyTransform=True, clearDepth=True):
1999
+ """Set an off-axis projection.
2000
+
2001
+ Create an off-axis projection for subsequent rendering calls. Sets the
2002
+ `viewMatrix` and `projectionMatrix` accordingly so the scene origin is
2003
+ on the screen plane. If `eyeOffset` is correct and the view distance and
2004
+ screen size is defined in the monitor configuration, the resulting view
2005
+ will approximate `ortho-stereo` viewing.
2006
+
2007
+ The convergence plane can be adjusted by setting `convergeOffset`. By
2008
+ default, the convergence plane is set to the screen plane. Any points
2009
+ on the screen plane will have zero disparity.
2010
+
2011
+ Parameters
2012
+ ----------
2013
+ applyTransform : bool
2014
+ Apply transformations after computing them in immediate mode. Same
2015
+ as calling :py:attr:`~Window.applyEyeTransform()` afterwards.
2016
+ clearDepth : bool, optional
2017
+ Clear the depth buffer.
2018
+
2019
+ """
2020
+ scrDistM = 0.5 if self.scrDistCM is None else self.scrDistCM / 100.0
2021
+ scrWidthM = 0.5 if self.scrWidthCM is None else self.scrWidthCM / 100.0
2022
+
2023
+ # Not in full screen mode? Need to compute the dimensions of the display
2024
+ # area to ensure disparities are correct even when in windowed-mode.
2025
+ aspect = self.size[0] / self.size[1]
2026
+ if not self._isFullScr:
2027
+ scrWidthM = (self.size[0] / self.scrWidthPIX) * scrWidthM
2028
+
2029
+ frustum = viewtools.computeFrustum(
2030
+ scrWidthM, # width of screen
2031
+ aspect, # aspect ratio
2032
+ scrDistM, # distance to screen
2033
+ eyeOffset=self._eyeOffset,
2034
+ convergeOffset=self._convergeOffset,
2035
+ nearClip=self._nearClip,
2036
+ farClip=self._farClip)
2037
+
2038
+ self._projectionMatrix = viewtools.perspectiveProjectionMatrix(*frustum)
2039
+
2040
+ # translate away from screen
2041
+ self._viewMatrix = numpy.identity(4, dtype=numpy.float32)
2042
+ self._viewMatrix[0, 3] = -self._eyeOffset # apply eye offset
2043
+ self._viewMatrix[2, 3] = -scrDistM # displace scene away from viewer
2044
+
2045
+ if applyTransform:
2046
+ self.applyEyeTransform(clearDepth=clearDepth)
2047
+
2048
+ def setToeInView(self, applyTransform=True, clearDepth=True):
2049
+ """Set toe-in projection.
2050
+
2051
+ Create a toe-in projection for subsequent rendering calls. Sets the
2052
+ `viewMatrix` and `projectionMatrix` accordingly so the scene origin is
2053
+ on the screen plane. The value of `convergeOffset` will define the
2054
+ convergence point of the view, which is offset perpendicular to the
2055
+ center of the screen plane. Points falling on a vertical line at the
2056
+ convergence point will have zero disparity.
2057
+
2058
+ Parameters
2059
+ ----------
2060
+ applyTransform : bool
2061
+ Apply transformations after computing them in immediate mode. Same
2062
+ as calling :py:attr:`~Window.applyEyeTransform()` afterwards.
2063
+ clearDepth : bool, optional
2064
+ Clear the depth buffer.
2065
+
2066
+ Notes
2067
+ -----
2068
+ * This projection mode is only 'correct' if the viewer's eyes are
2069
+ converged at the convergence point. Due to perspective, this
2070
+ projection introduces vertical disparities which increase in magnitude
2071
+ with eccentricity. Use `setOffAxisView` if you want to display
2072
+ something the viewer can look around the screen comfortably.
2073
+
2074
+ """
2075
+ scrDistM = 0.5 if self.scrDistCM is None else self.scrDistCM / 100.0
2076
+ scrWidthM = 0.5 if self.scrWidthCM is None else self.scrWidthCM / 100.0
2077
+
2078
+ # Not in full screen mode? Need to compute the dimensions of the display
2079
+ # area to ensure disparities are correct even when in windowed-mode.
2080
+ aspect = self.size[0] / self.size[1]
2081
+ if not self._isFullScr:
2082
+ scrWidthM = (self.size[0] / self.scrWidthPIX) * scrWidthM
2083
+
2084
+ frustum = viewtools.computeFrustum(
2085
+ scrWidthM, # width of screen
2086
+ aspect, # aspect ratio
2087
+ scrDistM, # distance to screen
2088
+ nearClip=self._nearClip,
2089
+ farClip=self._farClip)
2090
+
2091
+ self._projectionMatrix = viewtools.perspectiveProjectionMatrix(*frustum)
2092
+
2093
+ # translate away from screen
2094
+ eyePos = (self._eyeOffset, 0.0, scrDistM)
2095
+ convergePoint = (0.0, 0.0, self.convergeOffset)
2096
+ self._viewMatrix = viewtools.lookAt(eyePos, convergePoint)
2097
+
2098
+ if applyTransform:
2099
+ self.applyEyeTransform(clearDepth=clearDepth)
2100
+
2101
+ def setPerspectiveView(self, applyTransform=True, clearDepth=True):
2102
+ """Set the projection and view matrix to render with perspective.
2103
+
2104
+ Matrices are computed using values specified in the monitor
2105
+ configuration with the scene origin on the screen plane. Calculations
2106
+ assume units are in meters. If `eyeOffset != 0`, the view will be
2107
+ transformed laterally, however the frustum shape will remain the
2108
+ same.
2109
+
2110
+ Note that the values of :py:attr:`~Window.projectionMatrix` and
2111
+ :py:attr:`~Window.viewMatrix` will be replaced when calling this
2112
+ function.
2113
+
2114
+ Parameters
2115
+ ----------
2116
+ applyTransform : bool
2117
+ Apply transformations after computing them in immediate mode. Same
2118
+ as calling :py:attr:`~Window.applyEyeTransform()` afterwards if
2119
+ `False`.
2120
+ clearDepth : bool, optional
2121
+ Clear the depth buffer.
2122
+
2123
+ """
2124
+ # NB - we should eventually compute these matrices lazily since they may
2125
+ # not change over the course of an experiment under most circumstances.
2126
+ #
2127
+ scrDistM = 0.5 if self.scrDistCM is None else self.scrDistCM / 100.0
2128
+ scrWidthM = 0.5 if self.scrWidthCM is None else self.scrWidthCM / 100.0
2129
+
2130
+ # Not in full screen mode? Need to compute the dimensions of the display
2131
+ # area to ensure disparities are correct even when in windowed-mode.
2132
+ aspect = self.size[0] / self.size[1]
2133
+ if not self._isFullScr:
2134
+ scrWidthM = (self.size[0] / self.scrWidthPIX) * scrWidthM
2135
+
2136
+ frustum = viewtools.computeFrustum(
2137
+ scrWidthM, # width of screen
2138
+ aspect, # aspect ratio
2139
+ scrDistM, # distance to screen
2140
+ nearClip=self._nearClip,
2141
+ farClip=self._farClip)
2142
+
2143
+ self._projectionMatrix = \
2144
+ viewtools.perspectiveProjectionMatrix(*frustum, dtype=numpy.float32)
2145
+
2146
+ # translate away from screen
2147
+ self._viewMatrix = numpy.identity(4, dtype=numpy.float32)
2148
+ self._viewMatrix[0, 3] = -self._eyeOffset # apply eye offset
2149
+ self._viewMatrix[2, 3] = -scrDistM # displace scene away from viewer
2150
+
2151
+ if applyTransform:
2152
+ self.applyEyeTransform(clearDepth=clearDepth)
2153
+
2154
+ def applyEyeTransform(self, clearDepth=True):
2155
+ """Apply the current view and projection matrices.
2156
+
2157
+ Matrices specified by attributes :py:attr:`~Window.viewMatrix` and
2158
+ :py:attr:`~Window.projectionMatrix` are applied using 'immediate mode'
2159
+ OpenGL functions. Subsequent drawing operations will be affected until
2160
+ :py:attr:`~Window.flip()` is called.
2161
+
2162
+ All transformations in ``GL_PROJECTION`` and ``GL_MODELVIEW`` matrix
2163
+ stacks will be cleared (set to identity) prior to applying.
2164
+
2165
+ Parameters
2166
+ ----------
2167
+ clearDepth : bool
2168
+ Clear the depth buffer. This may be required prior to rendering 3D
2169
+ objects.
2170
+
2171
+ Examples
2172
+ --------
2173
+ Using a custom view and projection matrix::
2174
+
2175
+ # Must be called every frame since these values are reset after
2176
+ # `flip()` is called!
2177
+ win.viewMatrix = viewtools.lookAt( ... )
2178
+ win.projectionMatrix = viewtools.perspectiveProjectionMatrix( ... )
2179
+ win.applyEyeTransform()
2180
+ # draw 3D objects here ...
2181
+
2182
+ """
2183
+ # apply the projection and view transformations
2184
+ if hasattr(self, '_projectionMatrix'):
2185
+ GL.glMatrixMode(GL.GL_PROJECTION)
2186
+ GL.glLoadIdentity()
2187
+ projMat = self._projectionMatrix.ctypes.data_as(
2188
+ ctypes.POINTER(ctypes.c_float))
2189
+ GL.glMultTransposeMatrixf(projMat)
2190
+
2191
+ if hasattr(self, '_viewMatrix'):
2192
+ GL.glMatrixMode(GL.GL_MODELVIEW)
2193
+ GL.glLoadIdentity()
2194
+ viewMat = self._viewMatrix.ctypes.data_as(
2195
+ ctypes.POINTER(ctypes.c_float))
2196
+ GL.glMultTransposeMatrixf(viewMat)
2197
+
2198
+ oldDepthMask = self.depthMask
2199
+ if clearDepth:
2200
+ GL.glDepthMask(GL.GL_TRUE)
2201
+ GL.glClear(GL.GL_DEPTH_BUFFER_BIT)
2202
+
2203
+ if oldDepthMask is False: # return to old state if needed
2204
+ GL.glDepthMask(GL.GL_FALSE)
2205
+
2206
+ def resetEyeTransform(self, clearDepth=True):
2207
+ """Restore the default projection and view settings to PsychoPy
2208
+ defaults. Call this prior to drawing 2D stimuli objects (i.e.
2209
+ GratingStim, ImageStim, Rect, etc.) if any eye transformations were
2210
+ applied for the stimuli to be drawn correctly.
2211
+
2212
+ Parameters
2213
+ ----------
2214
+ clearDepth : bool
2215
+ Clear the depth buffer upon reset. This ensures successive draw
2216
+ commands are not affected by previous data written to the depth
2217
+ buffer. Default is `True`.
2218
+
2219
+ Notes
2220
+ -----
2221
+ * Calling :py:attr:`~Window.flip()` automatically resets the view and
2222
+ projection to defaults. So you don't need to call this unless you are
2223
+ mixing 3D and 2D stimuli.
2224
+
2225
+ Examples
2226
+ --------
2227
+ Going between 3D and 2D stimuli::
2228
+
2229
+ # 2D stimuli can be drawn before setting a perspective projection
2230
+ win.setPerspectiveView()
2231
+ # draw 3D stimuli here ...
2232
+ win.resetEyeTransform()
2233
+ # 2D stimuli can be drawn here again ...
2234
+ win.flip()
2235
+
2236
+ """
2237
+ # should eventually have the same effect as calling _onResize(), so we
2238
+ # need to add the retina mode stuff eventually
2239
+ if hasattr(self, '_viewMatrix'):
2240
+ self._viewMatrix = numpy.identity(4, dtype=numpy.float32)
2241
+
2242
+ if hasattr(self, '_projectionMatrix'):
2243
+ self._projectionMatrix = viewtools.orthoProjectionMatrix(
2244
+ -1, 1, -1, 1, -1, 1, dtype=numpy.float32)
2245
+
2246
+ self.applyEyeTransform(clearDepth)
2247
+
2248
+ def coordToRay(self, screenXY):
2249
+ """Convert a screen coordinate to a direction vector.
2250
+
2251
+ Takes a screen/window coordinate and computes a vector which projects
2252
+ a ray from the viewpoint through it (line-of-sight). Any 3D point
2253
+ touching the ray will appear at the screen coordinate.
2254
+
2255
+ Uses the current `viewport` and `projectionMatrix` to calculate the
2256
+ vector. The vector is in eye-space, where the origin of the scene is
2257
+ centered at the viewpoint and the forward direction aligned with the -Z
2258
+ axis. A ray of (0, 0, -1) results from a point at the very center of the
2259
+ screen assuming symmetric frustums.
2260
+
2261
+ Note that if you are using a flipped/mirrored view, you must invert your
2262
+ supplied screen coordinates (`screenXY`) prior to passing them to this
2263
+ function.
2264
+
2265
+ Parameters
2266
+ ----------
2267
+ screenXY : array_like
2268
+ X, Y screen coordinate. Must be in units of the window.
2269
+
2270
+ Returns
2271
+ -------
2272
+ ndarray
2273
+ Normalized direction vector [x, y, z].
2274
+
2275
+ Examples
2276
+ --------
2277
+ Getting the direction vector between the mouse cursor and the eye::
2278
+
2279
+ mx, my = mouse.getPos()
2280
+ dir = win.coordToRay((mx, my))
2281
+
2282
+ Set the position of a 3D stimulus object using the mouse, constrained to
2283
+ a plane. The object origin will always be at the screen coordinate of
2284
+ the mouse cursor::
2285
+
2286
+ # the eye position in the scene is defined by a rigid body pose
2287
+ win.viewMatrix = camera.getViewMatrix()
2288
+ win.applyEyeTransform()
2289
+
2290
+ # get the mouse location and calculate the intercept
2291
+ mx, my = mouse.getPos()
2292
+ ray = win.coordToRay([mx, my])
2293
+ result = intersectRayPlane( # from mathtools
2294
+ orig=camera.pos,
2295
+ dir=camera.transformNormal(ray),
2296
+ planeOrig=(0, 0, -10),
2297
+ planeNormal=(0, 1, 0))
2298
+
2299
+ # if result is `None`, there is no intercept
2300
+ if result is not None:
2301
+ pos, dist = result
2302
+ objModel.thePose.pos = pos
2303
+ else:
2304
+ objModel.thePose.pos = (0, 0, -10) # plane origin
2305
+
2306
+ If you don't define the position of the viewer with a `RigidBodyPose`,
2307
+ you can obtain the appropriate eye position and rotate the ray by doing
2308
+ the following::
2309
+
2310
+ pos = numpy.linalg.inv(win.viewMatrix)[:3, 3]
2311
+ ray = win.coordToRay([mx, my]).dot(win.viewMatrix[:3, :3])
2312
+ # then ...
2313
+ result = intersectRayPlane(
2314
+ orig=pos,
2315
+ dir=ray,
2316
+ planeOrig=(0, 0, -10),
2317
+ planeNormal=(0, 1, 0))
2318
+
2319
+ """
2320
+ # put in units of pixels
2321
+ if self.units == 'pix':
2322
+ scrX, scrY = numpy.asarray(screenXY, numpy.float32)
2323
+ else:
2324
+ scrX, scrY = convertToPix(numpy.asarray([0, 0]),
2325
+ numpy.asarray(screenXY),
2326
+ units=self.units,
2327
+ win=self)[:2]
2328
+
2329
+ # transform psychopy mouse coordinates to viewport coordinates
2330
+ scrX = scrX + (self.size[0] / 2.)
2331
+ scrY = scrY + (self.size[1] / 2.)
2332
+
2333
+ # get the NDC coordinates of the
2334
+ projX = 2. * (scrX - self.viewport[0]) / self.viewport[2] - 1.
2335
+ projY = 2. * (scrY - self.viewport[1]) / self.viewport[3] - 1.
2336
+
2337
+ vecNear = numpy.array((projX, projY, 0., 1.), dtype=numpy.float32)
2338
+ vecFar = numpy.array((projX, projY, 1., 1.), dtype=numpy.float32)
2339
+
2340
+ # compute the inverse projection matrix
2341
+ invPM = numpy.linalg.inv(self.projectionMatrix)
2342
+
2343
+ vecNear[:] = vecNear.dot(invPM.T)
2344
+ vecFar[:] = vecFar.dot(invPM.T)
2345
+
2346
+ vecNear /= vecNear[3]
2347
+ vecFar /= vecFar[3]
2348
+
2349
+ # direction vector, get rid of `w`
2350
+ dirVec = vecFar[:3] - vecNear[:3]
2351
+
2352
+ return dirVec / numpy.linalg.norm(dirVec)
2353
+
2354
+ def getMovieFrame(self, buffer='front'):
2355
+ """Capture the current Window as an image.
2356
+
2357
+ Saves to stack for :py:attr:`~Window.saveMovieFrames()`. As of v1.81.00
2358
+ this also returns the frame as a PIL image
2359
+
2360
+ This can be done at any time (usually after a :py:attr:`~Window.flip()`
2361
+ command).
2362
+
2363
+ Frames are stored in memory until a :py:attr:`~Window.saveMovieFrames()`
2364
+ command is issued. You can issue :py:attr:`~Window.getMovieFrame()` as
2365
+ often as you like and then save them all in one go when finished.
2366
+
2367
+ The back buffer will return the frame that hasn't yet been 'flipped'
2368
+ to be visible on screen but has the advantage that the mouse and any
2369
+ other overlapping windows won't get in the way.
2370
+
2371
+ The default front buffer is to be called immediately after a
2372
+ :py:attr:`~Window.flip()` and gives a complete copy of the screen at the
2373
+ window's coordinates.
2374
+
2375
+ Parameters
2376
+ ----------
2377
+ buffer : str, optional
2378
+ Buffer to capture.
2379
+
2380
+ Returns
2381
+ -------
2382
+ Image
2383
+ Buffer pixel contents as a PIL/Pillow image object.
2384
+
2385
+ """
2386
+ im = self._getFrame(buffer=buffer)
2387
+ self.movieFrames.append(im)
2388
+ return im
2389
+
2390
+ def _getPixels(self, rect=None, buffer='front', includeAlpha=True,
2391
+ makeLum=False):
2392
+ """Return an array of pixel values from the current window buffer or
2393
+ sub-region.
2394
+
2395
+ Parameters
2396
+ ----------
2397
+ rect : tuple[int], optional
2398
+ The region of the window to capture in pixel coordinates (left,
2399
+ bottom, width, height). If `None`, the whole window is captured.
2400
+ buffer : str, optional
2401
+ Buffer to capture.
2402
+ includeAlpha : bool, optional
2403
+ Include the alpha channel in the returned array. Default is `True`.
2404
+ makeLum : bool, optional
2405
+ Convert the RGB values to luminance values. Values are rounded to
2406
+ the nearest integer. Default is `False`.
2407
+
2408
+ Returns
2409
+ -------
2410
+ ndarray
2411
+ Pixel values as a 3D array of shape (height, width, channels). If
2412
+ `includeAlpha` is `False`, the array will have shape (height, width,
2413
+ 3). If `makeLum` is `True`, the array will have shape (height,
2414
+ width).
2415
+
2416
+ Examples
2417
+ --------
2418
+ Get the pixel values of the whole window::
2419
+
2420
+ pix = win._getPixels()
2421
+
2422
+ Get pixel values and convert to luminance and get average::
2423
+
2424
+ pix = win._getPixels(makeLum=True)
2425
+ average = pix.mean()
2426
+
2427
+ """
2428
+ # do the reading of the pixels
2429
+ if buffer == 'back' and self.useFBO:
2430
+ GL.glReadBuffer(GL.GL_COLOR_ATTACHMENT0_EXT)
2431
+ elif buffer == 'back':
2432
+ GL.glReadBuffer(GL.GL_BACK)
2433
+ elif buffer == 'front':
2434
+ if self.useFBO:
2435
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0)
2436
+ GL.glReadBuffer(GL.GL_FRONT)
2437
+ else:
2438
+ raise ValueError("Requested read from buffer '{}' but should be "
2439
+ "'front' or 'back'".format(buffer))
2440
+
2441
+ if rect:
2442
+ # box corners in pix
2443
+ left, bottom, w, h = rect
2444
+ else:
2445
+ left = bottom = 0
2446
+ w, h = self.size
2447
+
2448
+ # get pixel data
2449
+ bufferDat = (GL.GLubyte * (4 * w * h))()
2450
+ GL.glReadPixels(
2451
+ left, bottom, w, h,
2452
+ GL.GL_RGBA,
2453
+ GL.GL_UNSIGNED_BYTE,
2454
+ bufferDat)
2455
+
2456
+ # convert to array
2457
+ toReturn = numpy.frombuffer(bufferDat, dtype=numpy.uint8)
2458
+ toReturn = toReturn.reshape((h, w, 4))
2459
+
2460
+ # rebind front buffer if needed
2461
+ if buffer == 'front' and self.useFBO:
2462
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, self.frameBuffer)
2463
+
2464
+ # if we want the color data without an alpha channel, we need to
2465
+ # convert the data to a numpy array and remove the alpha channel
2466
+ if not includeAlpha:
2467
+ toReturn = toReturn[:, :, :3] # remove alpha channel
2468
+
2469
+ # convert to luminance if requested
2470
+ if makeLum:
2471
+ coeffs = [0.2989, 0.5870, 0.1140]
2472
+ toReturn = numpy.rint(numpy.dot(toReturn[:, :, :3], coeffs)).astype(
2473
+ numpy.uint8)
2474
+
2475
+ return toReturn
2476
+
2477
+ def _getFrame(self, rect=None, buffer='front'):
2478
+ """Return the current Window as an image.
2479
+ """
2480
+ # GL.glLoadIdentity()
2481
+ # do the reading of the pixels
2482
+ if buffer == 'back' and self.useFBO:
2483
+ GL.glReadBuffer(GL.GL_COLOR_ATTACHMENT0_EXT)
2484
+ elif buffer == 'back':
2485
+ GL.glReadBuffer(GL.GL_BACK)
2486
+ elif buffer == 'front':
2487
+ if self.useFBO:
2488
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0)
2489
+ GL.glReadBuffer(GL.GL_FRONT)
2490
+ else:
2491
+ raise ValueError("Requested read from buffer '{}' but should be "
2492
+ "'front' or 'back'".format(buffer))
2493
+
2494
+ if rect:
2495
+ x, y = self.size # of window, not image
2496
+ imType = 'RGBA' # not tested with anything else
2497
+
2498
+ # box corners in pix
2499
+ left = int((rect[0] / 2. + 0.5) * x)
2500
+ bottom = int((rect[3] / 2. + 0.5) * y)
2501
+ w = int((rect[2] / 2. + 0.5) * x) - left
2502
+ h = int((rect[1] / 2. + 0.5) * y) - bottom
2503
+ else:
2504
+ left = bottom = 0
2505
+ w, h = self.size
2506
+
2507
+ # http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml
2508
+ bufferDat = (GL.GLubyte * (4 * w * h))()
2509
+ GL.glReadPixels(left, bottom, w, h,
2510
+ GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, bufferDat)
2511
+ try:
2512
+ im = Image.fromstring(mode='RGBA', size=(w, h),
2513
+ data=bufferDat)
2514
+ except Exception:
2515
+ im = Image.frombytes(mode='RGBA', size=(w, h),
2516
+ data=bufferDat)
2517
+
2518
+ im = im.transpose(Image.FLIP_TOP_BOTTOM)
2519
+ im = im.convert('RGB')
2520
+
2521
+ if self.useFBO and buffer == 'front':
2522
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, self.frameBuffer)
2523
+ return im
2524
+
2525
+ @property
2526
+ def screenshot(self):
2527
+ return self._getFrame()
2528
+
2529
+ def saveMovieFrames(self, fileName, codec='libx264',
2530
+ fps=30, clearFrames=True):
2531
+ """Writes any captured frames to disk.
2532
+
2533
+ Will write any format that is understood by PIL (tif, jpg, png, ...)
2534
+
2535
+ Parameters
2536
+ ----------
2537
+ filename : str
2538
+ Name of file, including path. The extension at the end of the file
2539
+ determines the type of file(s) created. If an image type (e.g. .png)
2540
+ is given, then multiple static frames are created. If it is .gif
2541
+ then an animated GIF image is created (although you will get higher
2542
+ quality GIF by saving PNG files and then combining them in dedicated
2543
+ image manipulation software, such as GIMP). On Windows and Linux
2544
+ `.mpeg` files can be created if `pymedia` is installed. On macOS
2545
+ `.mov` files can be created if the pyobjc-frameworks-QTKit is
2546
+ installed. Unfortunately the libs used for movie generation can be
2547
+ flaky and poor quality. As for animated GIFs, better results can be
2548
+ achieved by saving as individual .png frames and then combining them
2549
+ into a movie using software like ffmpeg.
2550
+ codec : str, optional
2551
+ The codec to be used **by moviepy** for mp4/mpg/mov files. If
2552
+ `None` then the default will depend on file extension. Can be
2553
+ one of ``libx264``, ``mpeg4`` for mp4/mov files. Can be
2554
+ ``rawvideo``, ``png`` for avi files (not recommended). Can be
2555
+ ``libvorbis`` for ogv files. Default is ``libx264``.
2556
+ fps : int, optional
2557
+ The frame rate to be used throughout the movie. **Only for
2558
+ quicktime (.mov) movies.**. Default is `30`.
2559
+ clearFrames : bool, optional
2560
+ Set this to `False` if you want the frames to be kept for
2561
+ additional calls to ``saveMovieFrames``. Default is `True`.
2562
+
2563
+ Examples
2564
+ --------
2565
+ Writes a series of static frames as frame001.tif, frame002.tif etc.::
2566
+
2567
+ myWin.saveMovieFrames('frame.tif')
2568
+
2569
+ As of PsychoPy 1.84.1 the following are written with moviepy::
2570
+
2571
+ myWin.saveMovieFrames('stimuli.mp4') # codec = 'libx264' or 'mpeg4'
2572
+ myWin.saveMovieFrames('stimuli.mov')
2573
+ myWin.saveMovieFrames('stimuli.gif')
2574
+
2575
+ """
2576
+ fileRoot, fileExt = os.path.splitext(fileName)
2577
+ fileExt = fileExt.lower() # easier than testing both later
2578
+ if len(self.movieFrames) == 0:
2579
+ logging.error('no frames to write - did you forget to update '
2580
+ 'your window or call win.getMovieFrame()?')
2581
+ return
2582
+ else:
2583
+ logging.info('Writing %i frames to %s' % (len(self.movieFrames),
2584
+ fileName))
2585
+
2586
+ if fileExt in ['.gif', '.mpg', '.mpeg', '.mp4', '.mov']:
2587
+ # lazy loading of moviepy.editor (rarely needed)
2588
+ from moviepy.editor import ImageSequenceClip
2589
+ # save variety of movies with moviepy
2590
+ numpyFrames = []
2591
+ for frame in self.movieFrames:
2592
+ numpyFrames.append(numpy.array(frame))
2593
+ clip = ImageSequenceClip(numpyFrames, fps=fps)
2594
+ if fileExt == '.gif':
2595
+ clip.write_gif(fileName, fps=fps, fuzz=0, opt='nq')
2596
+ else:
2597
+ clip.write_videofile(fileName, codec=codec)
2598
+ elif len(self.movieFrames) == 1:
2599
+ # save an image using pillow
2600
+ self.movieFrames[0].save(fileName)
2601
+ else:
2602
+ frmc = numpy.ceil(numpy.log10(len(self.movieFrames) + 1))
2603
+ frame_name_format = "%s%%0%dd%s" % (fileRoot, frmc, fileExt)
2604
+ for frameN, thisFrame in enumerate(self.movieFrames):
2605
+ thisFileName = frame_name_format % (frameN + 1,)
2606
+ thisFrame.save(thisFileName)
2607
+ if clearFrames:
2608
+ self.movieFrames = []
2609
+
2610
+ def _getRegionOfFrame(self, rect=(-1, 1, 1, -1), buffer='front',
2611
+ power2=False, squarePower2=False):
2612
+ """Deprecated function, here for historical reasons. You may now use
2613
+ `:py:attr:`~Window._getFrame()` and specify a rect to get a sub-region,
2614
+ just as used here.
2615
+
2616
+ power2 can be useful with older OpenGL versions to avoid interpolation
2617
+ in :py:attr:`PatchStim`. If power2 or squarePower2, it will expand rect
2618
+ dimensions up to next power of two. squarePower2 uses the max
2619
+ dimensions. You need to check what your hardware & OpenGL supports,
2620
+ and call :py:attr:`~Window._getRegionOfFrame()` as appropriate.
2621
+ """
2622
+ # Ideally: rewrite using GL frame buffer object; glReadPixels == slow
2623
+ region = self._getFrame(rect=rect, buffer=buffer)
2624
+ if power2 or squarePower2: # use to avoid interpolation in PatchStim
2625
+ if squarePower2:
2626
+ maxsize = max(region.size)
2627
+ xPowerOf2 = int(2**numpy.ceil(numpy.log2(maxsize)))
2628
+ yPowerOf2 = xPowerOf2
2629
+ else:
2630
+ xPowerOf2 = int(2**numpy.ceil(numpy.log2(region.size[0])))
2631
+ yPowerOf2 = int(2**numpy.ceil(numpy.log2(region.size[1])))
2632
+ imP2 = Image.new('RGBA', (xPowerOf2, yPowerOf2))
2633
+ # paste centered
2634
+ imP2.paste(region, (int(xPowerOf2 / 2. - region.size[0] / 2.),
2635
+ int(yPowerOf2 / 2.) - region.size[1] / 2))
2636
+ region = imP2
2637
+ return region
2638
+
2639
+ def close(self):
2640
+ """Close the window (and reset the Bits++ if necess).
2641
+ """
2642
+ self._closed = True
2643
+
2644
+ # If iohub is running, inform it to stop using this win id
2645
+ # for mouse events
2646
+ try:
2647
+ if IOHUB_ACTIVE:
2648
+ from psychopy.iohub.client import ioHubConnection
2649
+ ioHubConnection.ACTIVE_CONNECTION.unregisterWindowHandles(self._hw_handle)
2650
+ except Exception:
2651
+ pass
2652
+
2653
+ self.backend.close() # moved here, dereferencing the window prevents
2654
+ # backend specific actions to take place
2655
+
2656
+ try:
2657
+ openWindows.remove(self)
2658
+ except Exception:
2659
+ pass
2660
+
2661
+ try:
2662
+ self.mouseVisible = True
2663
+ except Exception:
2664
+ # can cause unimportant "'NoneType' object is not callable"
2665
+ pass
2666
+
2667
+ try:
2668
+ if self.bits is not None:
2669
+ self.bits.reset()
2670
+ except Exception:
2671
+ pass
2672
+ try:
2673
+ logging.flush()
2674
+ except Exception:
2675
+ pass
2676
+
2677
+ def fps(self):
2678
+ """Report the frames per second since the last call to this function
2679
+ (or since the window was created if this is first call)"""
2680
+ fps = self.frames / self.frameClock.getTime()
2681
+ self.frameClock.reset()
2682
+ self.frames = 0
2683
+ return fps
2684
+
2685
+ @property
2686
+ def depthTest(self):
2687
+ """`True` if depth testing is enabled."""
2688
+ return self._depthTest
2689
+
2690
+ @depthTest.setter
2691
+ def depthTest(self, value):
2692
+ if value is True:
2693
+ GL.glEnable(GL.GL_DEPTH_TEST)
2694
+ elif value is False:
2695
+ GL.glDisable(GL.GL_DEPTH_TEST)
2696
+ else:
2697
+ raise TypeError("Value must be boolean.")
2698
+
2699
+ self._depthTest = value
2700
+
2701
+ @property
2702
+ def depthFunc(self):
2703
+ """Depth test comparison function for rendering."""
2704
+ return self._depthFunc
2705
+
2706
+ @depthFunc.setter
2707
+ def depthFunc(self, value):
2708
+ depthFuncs = {'never': GL.GL_NEVER, 'less': GL.GL_LESS,
2709
+ 'equal': GL.GL_EQUAL, 'lequal': GL.GL_LEQUAL,
2710
+ 'greater': GL.GL_GREATER, 'notequal': GL.GL_NOTEQUAL,
2711
+ 'gequal': GL.GL_GEQUAL, 'always': GL.GL_ALWAYS}
2712
+
2713
+ GL.glDepthFunc(depthFuncs[value])
2714
+
2715
+ self._depthFunc = value
2716
+
2717
+ @property
2718
+ def depthMask(self):
2719
+ """`True` if depth masking is enabled. Writing to the depth buffer will
2720
+ be disabled.
2721
+ """
2722
+ return self._depthMask
2723
+
2724
+ @depthMask.setter
2725
+ def depthMask(self, value):
2726
+ if value is True:
2727
+ GL.glDepthMask(GL.GL_TRUE)
2728
+ elif value is False:
2729
+ GL.glDepthMask(GL.GL_FALSE)
2730
+ else:
2731
+ raise TypeError("Value must be boolean.")
2732
+
2733
+ self._depthMask = value
2734
+
2735
+ @property
2736
+ def cullFaceMode(self):
2737
+ """Face culling mode, either `back`, `front` or `both`."""
2738
+ return self._cullFaceMode
2739
+
2740
+ @cullFaceMode.setter
2741
+ def cullFaceMode(self, value):
2742
+ if value == 'back':
2743
+ GL.glCullFace(GL.GL_BACK)
2744
+ elif value == 'front':
2745
+ GL.glCullFace(GL.GL_FRONT)
2746
+ elif value == 'both':
2747
+ GL.glCullFace(GL.GL_FRONT_AND_BACK)
2748
+ else:
2749
+ raise ValueError('Invalid face cull mode.')
2750
+
2751
+ self._cullFaceMode = value
2752
+
2753
+ @property
2754
+ def cullFace(self):
2755
+ """`True` if face culling is enabled.`"""
2756
+ return self._cullFace
2757
+
2758
+ @cullFace.setter
2759
+ def cullFace(self, value):
2760
+ if value is True:
2761
+ GL.glEnable(GL.GL_CULL_FACE)
2762
+ elif value is False:
2763
+ GL.glDisable(GL.GL_CULL_FACE)
2764
+ else:
2765
+ raise TypeError('Value must be type `bool`.')
2766
+
2767
+ self._cullFace = value
2768
+
2769
+ @property
2770
+ def frontFace(self):
2771
+ """Face winding order to define front, either `ccw` or `cw`."""
2772
+ return self._frontFace
2773
+
2774
+ @frontFace.setter
2775
+ def frontFace(self, value):
2776
+ if value == 'ccw':
2777
+ GL.glFrontFace(GL.GL_CCW)
2778
+ elif value == 'cw':
2779
+ GL.glFrontFace(GL.GL_CW)
2780
+ else:
2781
+ raise ValueError('Invalid value, must be `ccw` or `cw`.')
2782
+
2783
+ self._frontFace = value
2784
+
2785
+ @property
2786
+ def draw3d(self):
2787
+ """`True` if 3D drawing is enabled on this window."""
2788
+ return self._draw3d
2789
+
2790
+ @draw3d.setter
2791
+ def draw3d(self, value):
2792
+ if value is True:
2793
+ if self.depthMask is False:
2794
+ self.depthMask = True
2795
+ if self.depthTest is False:
2796
+ self.depthTest = True
2797
+ if self.cullFace is False:
2798
+ self.cullFace = True
2799
+ elif value is False:
2800
+ if self.depthMask is True:
2801
+ self.depthMask = False
2802
+ if self.depthTest is True:
2803
+ self.depthTest = False
2804
+ if self.cullFace is True:
2805
+ self.cullFace = False
2806
+ else:
2807
+ raise TypeError('Value must be type `bool`.')
2808
+
2809
+ self._draw3d = value
2810
+
2811
+ @attributeSetter
2812
+ def blendMode(self, blendMode):
2813
+ """Blend mode to use."""
2814
+ self.__dict__['blendMode'] = blendMode
2815
+ if blendMode == 'avg':
2816
+ GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
2817
+ if hasattr(self, '_shaders'):
2818
+ self._progSignedFrag = self._shaders['signedColor']
2819
+ self._progSignedTex = self._shaders['signedTex']
2820
+ self._progSignedTexMask = self._shaders['signedTexMask']
2821
+ self._progSignedTexMask1D = self._shaders['signedTexMask1D']
2822
+ self._progImageStim = self._shaders['imageStim']
2823
+ elif blendMode == 'add':
2824
+ GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE)
2825
+ if hasattr(self, '_shaders'):
2826
+ self._progSignedFrag = self._shaders['signedColor_adding']
2827
+ self._progSignedTex = self._shaders['signedTex_adding']
2828
+ self._progSignedTexMask = self._shaders['signedTexMask_adding']
2829
+ tmp = self._shaders['signedTexMask1D_adding']
2830
+ self._progSignedTexMask1D = tmp
2831
+ self._progImageStim = self._shaders['imageStim_adding']
2832
+ else:
2833
+ raise ValueError("Window blendMode should be set to 'avg' or 'add'"
2834
+ " but we received the value {}"
2835
+ .format(repr(blendMode)))
2836
+
2837
+ def setBlendMode(self, blendMode, log=None):
2838
+ """Usually you can use 'stim.attribute = value' syntax instead,
2839
+ but use this method if you need to suppress the log message.
2840
+ """
2841
+ setAttribute(self, 'blendMode', blendMode, log)
2842
+
2843
+ @property
2844
+ def colorSpace(self):
2845
+ """The name of the color space currently being used
2846
+
2847
+ Value should be: a string or None
2848
+
2849
+ For strings and hex values this is not needed.
2850
+ If None the default colorSpace for the stimulus is
2851
+ used (defined during initialisation).
2852
+
2853
+ Please note that changing colorSpace does not change stimulus
2854
+ parameters. Thus you usually want to specify colorSpace before
2855
+ setting the color. Example::
2856
+
2857
+ # A light green text
2858
+ stim = visual.TextStim(win, 'Color me!',
2859
+ color=(0, 1, 0), colorSpace='rgb')
2860
+
2861
+ # An almost-black text
2862
+ stim.colorSpace = 'rgb255'
2863
+
2864
+ # Make it light green again
2865
+ stim.color = (128, 255, 128)
2866
+ """
2867
+ if hasattr(self, '_colorSpace'):
2868
+ return self._colorSpace
2869
+ else:
2870
+ return 'rgb'
2871
+ @colorSpace.setter
2872
+ def colorSpace(self, value):
2873
+ if value in colorSpaces:
2874
+ self._colorSpace = value
2875
+ else:
2876
+ logging.error(f"'{value}' is not a valid color space")
2877
+
2878
+ @property
2879
+ def color(self):
2880
+ """Set the color of the window.
2881
+
2882
+ This command sets the color that the blank screen will have on the
2883
+ next clear operation. As a result it effectively takes TWO
2884
+ :py:attr:`~Window.flip()` operations to become visible (the first uses
2885
+ the color to create the new screen, the second presents that screen to
2886
+ the viewer). For this reason, if you want to changed background color of
2887
+ the window "on the fly", it might be a better idea to draw a
2888
+ :py:attr:`Rect` that fills the whole window with the desired
2889
+ :py:attr:`Rect.fillColor` attribute. That'll show up on first flip.
2890
+
2891
+ See other stimuli (e.g. :py:attr:`GratingStim.color`)
2892
+ for more info on the color attribute which essentially works the same on
2893
+ all PsychoPy stimuli.
2894
+
2895
+ See :ref:`colorspaces` for further information about the ways to
2896
+ specify colors and their various implications.
2897
+ """
2898
+ if hasattr(self, '_color'):
2899
+ return getattr(self._color, self.colorSpace)
2900
+ @color.setter
2901
+ def color(self, value):
2902
+ if isinstance(value, Color):
2903
+ # If supplied with a color object, set as that
2904
+ self._color = value
2905
+ else:
2906
+ # Otherwise, use it to make a color object
2907
+ self._color = Color(value, self.colorSpace)
2908
+ if not self._color:
2909
+ self._color = Color()
2910
+ logging.error(f"'{value}' is not a valid {self.colorSpace} color")
2911
+
2912
+ # if it is None then this will be done during window setup
2913
+ if self.backend is not None:
2914
+ self.backend.setCurrent() # make sure this window is active
2915
+ GL.glClearColor(*self._color.render('rgba1'))
2916
+
2917
+ def setColor(self, color, colorSpace=None, operation='', log=None):
2918
+ """Usually you can use ``stim.attribute = value`` syntax instead,
2919
+ but use this method if you want to set color and colorSpace
2920
+ simultaneously.
2921
+
2922
+ See :py:attr:`~Window.color` for documentation on colors.
2923
+ """
2924
+ self.colorSpace = colorSpace
2925
+ self.color = color
2926
+
2927
+ def setRGB(self, newRGB):
2928
+ """Deprecated: As of v1.61.00 please use `setColor()` instead
2929
+ """
2930
+ self.setColor(newRGB, colorSpace="rgb")
2931
+
2932
+ @property
2933
+ def rgb(self):
2934
+ if hasattr(self, "_color"):
2935
+ return self._color.render("rgb")
2936
+ @rgb.setter
2937
+ def rgb(self, value):
2938
+ self.color = Color(value, 'rgb')
2939
+
2940
+ @attributeSetter
2941
+ def backgroundImage(self, value):
2942
+ """
2943
+ Background image for the window, can be either a visual.ImageStim object or anything which could be passed to
2944
+ visual.ImageStim.image to create one. Will be drawn each time `win.flip()` is called, meaning it is always
2945
+ below all other contents of the window.
2946
+ """
2947
+ if value in (None, "None", "none", ""):
2948
+ # If given None, store so we know not to use a background image
2949
+ self._backgroundImage = None
2950
+ self.__dict__['backgroundImage'] = self._backgroundImage
2951
+ return
2952
+ elif hasattr(value, "draw") and hasattr(value, "win"):
2953
+ # If given a visual object, set its parent window to self and use it
2954
+ value.win = self
2955
+ self._backgroundImage = value
2956
+ else:
2957
+ # Otherwise, try to make an image from value (start off as if backgroundFit was None)
2958
+ self._backgroundImage = image.ImageStim(self, image=value, size=None, pos=(0, 0))
2959
+
2960
+ # Set background fit again now that we have an image
2961
+ if hasattr(self, "_backgroundFit"):
2962
+ self.backgroundFit = self._backgroundFit
2963
+
2964
+ self.__dict__['backgroundImage'] = self._backgroundImage
2965
+
2966
+ @attributeSetter
2967
+ def backgroundFit(self, value):
2968
+ """
2969
+ How should the background image of this window fit? Options are:
2970
+
2971
+ None, "None", "none"
2972
+ No scaling is applied, image is present at its pixel size unaltered.
2973
+ "cover"
2974
+ Image is scaled such that it covers the whole screen without changing its aspect ratio. In other words,
2975
+ both dimensions are evenly scaled such that its SHORTEST dimension matches the window's LONGEST dimension.
2976
+ "contain"
2977
+ Image is scaled such that it is contained within the screen without changing its aspect ratio. In other
2978
+ words, both dimensions are evenly scaled such that its LONGEST dimension matches the window's SHORTEST
2979
+ dimension.
2980
+ "scaleDown", "scale-down", "scaledown"
2981
+ If image is bigger than the window along any dimension, it will behave as if backgroundFit were "contain".
2982
+ Otherwise, it will behave as if backgroundFit were None.
2983
+ """
2984
+ self._backgroundFit = value
2985
+
2986
+ # Skip if no background image
2987
+ if (not hasattr(self, "_backgroundImage")) or (self._backgroundImage is None):
2988
+ self.__dict__['backgroundFit'] = self._backgroundFit
2989
+ return
2990
+
2991
+ # If value is scaleDown or alias, set to None or "contain" based on relative size
2992
+ if value in ("scaleDown", "scale-down", "scaledown"):
2993
+ overflow = numpy.asarray(self._backgroundImage._origSize) > numpy.asarray(self.size)
2994
+ if overflow.any():
2995
+ value = "contain"
2996
+ else:
2997
+ value = None
2998
+
2999
+ if value in (None, "None", "none"):
3000
+ # If value is None, don't change the backgroundImage at all
3001
+ pass
3002
+ elif value == "fill":
3003
+ # If value is fill, make backgroundImage fill screen
3004
+ self._backgroundImage.units = "norm"
3005
+ self._backgroundImage.size = (2, 2)
3006
+ self._backgroundImage.pos = (0, 0)
3007
+ if value in ("contain", "cover"):
3008
+ # If value is contain or cover, set one dimension to fill screen and the other to maintain ratio
3009
+ ratios = numpy.asarray(self._backgroundImage._origSize) / numpy.asarray(self.size)
3010
+ if value == "cover":
3011
+ i = ratios.argmin()
3012
+ else:
3013
+ i = ratios.argmax()
3014
+ size = [None, None]
3015
+ size[i] = 2
3016
+ self._backgroundImage.units = "norm"
3017
+ self._backgroundImage.size = size
3018
+ self._backgroundImage.pos = (0, 0)
3019
+
3020
+ self.__dict__['backgroundFit'] = self._backgroundFit
3021
+
3022
+ def _setupGamma(self, gammaVal):
3023
+ """A private method to work out how to handle gamma for this Window
3024
+ given that the user might have specified an explicit value, or maybe
3025
+ gave a Monitor.
3026
+ """
3027
+ # determine which gamma value to use (or native ramp)
3028
+ if gammaVal is not None:
3029
+ self._checkGamma()
3030
+ self.useNativeGamma = False
3031
+ elif not self.monitor.gammaIsDefault():
3032
+ if self.monitor.getGamma() is not None:
3033
+ self.__dict__['gamma'] = self.monitor.getGamma()
3034
+ self.useNativeGamma = False
3035
+ else:
3036
+ self.__dict__['gamma'] = None # gamma wasn't set anywhere
3037
+ self.useNativeGamma = True
3038
+
3039
+ # then try setting it
3040
+ if self.useNativeGamma:
3041
+ if self.autoLog:
3042
+ logging.info('Using gamma table of operating system')
3043
+ else:
3044
+ if self.autoLog:
3045
+ logging.info('Using gamma: self.gamma' + str(self.gamma))
3046
+ self.gamma = gammaVal # using either pygame or bits++
3047
+
3048
+
3049
+ @attributeSetter
3050
+ def gamma(self, gamma):
3051
+ """Set the monitor gamma for linearization.
3052
+
3053
+ Warnings
3054
+ --------
3055
+ Don't use this if using a Bits++ or Bits#, as it overrides monitor
3056
+ settings.
3057
+
3058
+ """
3059
+ self._checkGamma(gamma)
3060
+
3061
+ if self.bits is not None:
3062
+ msg = ("Do not use try to set the gamma of a window with "
3063
+ "Bits++/Bits# enabled. It was ambiguous what should "
3064
+ "happen. Use the setGamma() function of the bits box "
3065
+ "instead")
3066
+ raise DeprecationWarning(msg)
3067
+
3068
+ self.backend.gamma = self.__dict__['gamma']
3069
+
3070
+ def setGamma(self, gamma, log=None):
3071
+ """Usually you can use 'stim.attribute = value' syntax instead,
3072
+ but use this method if you need to suppress the log message.
3073
+
3074
+ """
3075
+ setAttribute(self, 'gamma', gamma, log)
3076
+
3077
+ @attributeSetter
3078
+ def gammaRamp(self, newRamp):
3079
+ """Sets the hardware CLUT using a specified 3xN array of floats ranging
3080
+ between 0.0 and 1.0.
3081
+
3082
+ Array must have a number of rows equal to 2 ^ max(bpc).
3083
+
3084
+ """
3085
+ self.backend.gammaRamp = newRamp
3086
+
3087
+ def _checkGamma(self, gamma=None):
3088
+ if gamma is None:
3089
+ gamma = self.gamma
3090
+ if isinstance(gamma, (float, int)):
3091
+ self.__dict__['gamma'] = [gamma] * 3
3092
+ elif hasattr(gamma, '__iter__'):
3093
+ self.__dict__['gamma'] = gamma
3094
+ else:
3095
+ raise ValueError('gamma must be a numeric scalar or iterable')
3096
+
3097
+ def setScale(self, units, font='dummyFont', prevScale=(1.0, 1.0)):
3098
+ """DEPRECATED: this method used to be used to switch between units for
3099
+ stimulus drawing but this is now handled by the stimuli themselves and
3100
+ the window should always be left in units of 'pix'
3101
+ """
3102
+ if self.useRetina:
3103
+ retinaScale = 2.0
3104
+ else:
3105
+ retinaScale = 1.0
3106
+ # then unit-specific changes
3107
+ if units == "norm":
3108
+ thisScale = numpy.array([1.0, 1.0])
3109
+ elif units == "height":
3110
+ thisScale = numpy.array([2.0 * self.size[1] / self.size[0], 2.0])
3111
+ elif units in ["pix", "pixels"]:
3112
+ thisScale = 2.0 / numpy.array(self.size) * retinaScale
3113
+ elif units == "cm":
3114
+ # windowPerCM = windowPerPIX / CMperPIX
3115
+ # = (window/winPIX) / (scrCm/scrPIX)
3116
+ if self.scrWidthCM in [0, None] or self.scrWidthPIX in [0, None]:
3117
+ logging.error('you did not give the width of the screen (pixels'
3118
+ ' and cm). Check settings in MonitorCentre.')
3119
+ core.wait(1.0)
3120
+ core.quit()
3121
+ thisScale = ((numpy.array([2.0, 2.0]) / self.size * retinaScale)
3122
+ / (self.scrWidthCM / self.scrWidthPIX))
3123
+ elif units in ["deg", "degs"]:
3124
+ # windowPerDeg = winPerCM * CMperDEG
3125
+ # = winPerCM * tan(pi/180) * distance
3126
+ if ((self.scrWidthCM in [0, None]) or
3127
+ (self.scrWidthPIX in [0, None])):
3128
+ logging.error('you did not give the width of the screen (pixels'
3129
+ ' and cm). Check settings in MonitorCentre.')
3130
+ core.wait(1.0)
3131
+ core.quit()
3132
+ cmScale = ((numpy.array([2.0, 2.0]) / self.size) * retinaScale /
3133
+ (self.scrWidthCM / self.scrWidthPIX))
3134
+ thisScale = cmScale * 0.017455 * self.scrDistCM
3135
+ elif units == "stroke_font":
3136
+ lw = 2 * font.letterWidth
3137
+ thisScale = numpy.array([lw, lw] / self.size * retinaScale / 38.0)
3138
+ # actually set the scale as appropriate
3139
+ # allows undoing of a previous scaling procedure
3140
+ thisScale = thisScale / numpy.asarray(prevScale)
3141
+ GL.glScalef(thisScale[0], thisScale[1], 1.0)
3142
+ return thisScale
3143
+
3144
+ def _checkMatchingSizes(self, requested, actual):
3145
+ """Checks whether the requested and actual screen sizes differ.
3146
+ If not then a warning is output and the window size is set to actual
3147
+ """
3148
+ if list(requested) != list(actual):
3149
+ logging.warning("User requested fullscreen with size %s, "
3150
+ "but screen is actually %s. Using actual size" %
3151
+ (requested, actual))
3152
+ self.clientSize = numpy.array(actual)
3153
+
3154
+ def _setupGL(self):
3155
+ """Setup OpenGL state for this window.
3156
+ """
3157
+ # setup screen color
3158
+ self.color = self.color # call attributeSetter
3159
+ GL.glClearDepth(1.0)
3160
+
3161
+ # viewport or drawable area of the framebuffer
3162
+ self.viewport = self.scissor = \
3163
+ (0, 0, self.frameBufferSize[0], self.frameBufferSize[1])
3164
+ self.scissorTest = True
3165
+ self.stencilTest = False
3166
+
3167
+ GL.glMatrixMode(GL.GL_PROJECTION) # Reset the projection matrix
3168
+ GL.glLoadIdentity()
3169
+ GL.gluOrtho2D(-1, 1, -1, 1)
3170
+
3171
+ GL.glMatrixMode(GL.GL_MODELVIEW) # Reset the modelview matrix
3172
+ GL.glLoadIdentity()
3173
+
3174
+ self.depthTest = False
3175
+ # GL.glEnable(GL.GL_DEPTH_TEST) # Enables Depth Testing
3176
+ # GL.glDepthFunc(GL.GL_LESS) # The Type Of Depth Test To Do
3177
+ GL.glEnable(GL.GL_BLEND)
3178
+
3179
+ GL.glShadeModel(GL.GL_SMOOTH) # Color Shading (FLAT or SMOOTH)
3180
+ GL.glEnable(GL.GL_POINT_SMOOTH)
3181
+
3182
+ # check for GL_ARB_texture_float
3183
+ # (which is needed for shaders to be useful)
3184
+ # this needs to be done AFTER the context has been created
3185
+ if not GL.gl_info.have_extension('GL_ARB_texture_float'):
3186
+ self._haveShaders = False
3187
+
3188
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT)
3189
+
3190
+ # identify gfx card vendor
3191
+ self.glVendor = GL.gl_info.get_vendor().lower()
3192
+
3193
+ requestedFBO = self.useFBO
3194
+ if self._haveShaders: # do this after setting up FrameBufferObject
3195
+ self._setupShaders()
3196
+ else:
3197
+ self.useFBO = False
3198
+ if self.useFBO:
3199
+ success = self._setupFrameBuffer()
3200
+ if not success:
3201
+ self.useFBO = False
3202
+ if requestedFBO and not self.useFBO:
3203
+ logging.warning("Framebuffer object (FBO) not supported on "
3204
+ "this graphics card")
3205
+ if self.blendMode == 'add' and not self.useFBO:
3206
+ logging.warning("Framebuffer object (FBO) is required for "
3207
+ "blendMode='add'. Reverting to blendMode='avg'")
3208
+ self.blendMode = 'avg'
3209
+
3210
+ def _setupShaders(self):
3211
+ self._progSignedTexFont = _shaders.compileProgram(
3212
+ _shaders.vertSimple, _shaders.fragSignedColorTexFont)
3213
+ self._progFBOtoFrame = _shaders.compileProgram(
3214
+ _shaders.vertSimple, _shaders.fragFBOtoFrame)
3215
+ self._shaders = {}
3216
+ self._shaders['signedColor'] = _shaders.compileProgram(
3217
+ _shaders.vertSimple, _shaders.fragSignedColor)
3218
+ self._shaders['signedColor_adding'] = _shaders.compileProgram(
3219
+ _shaders.vertSimple, _shaders.fragSignedColor_adding)
3220
+ self._shaders['signedTex'] = _shaders.compileProgram(
3221
+ _shaders.vertSimple, _shaders.fragSignedColorTex)
3222
+ self._shaders['signedTexMask'] = _shaders.compileProgram(
3223
+ _shaders.vertSimple, _shaders.fragSignedColorTexMask)
3224
+ self._shaders['signedTexMask1D'] = _shaders.compileProgram(
3225
+ _shaders.vertSimple, _shaders.fragSignedColorTexMask1D)
3226
+ self._shaders['signedTex_adding'] = _shaders.compileProgram(
3227
+ _shaders.vertSimple, _shaders.fragSignedColorTex_adding)
3228
+ self._shaders['signedTexMask_adding'] = _shaders.compileProgram(
3229
+ _shaders.vertSimple, _shaders.fragSignedColorTexMask_adding)
3230
+ self._shaders['signedTexMask1D_adding'] = _shaders.compileProgram(
3231
+ _shaders.vertSimple, _shaders.fragSignedColorTexMask1D_adding)
3232
+ self._shaders['imageStim'] = _shaders.compileProgram(
3233
+ _shaders.vertSimple, _shaders.fragImageStim)
3234
+ self._shaders['imageStim_adding'] = _shaders.compileProgram(
3235
+ _shaders.vertSimple, _shaders.fragImageStim_adding)
3236
+ self._shaders['stim3d_phong'] = {}
3237
+
3238
+ # Create shader flags, these are used as keys to pick the appropriate
3239
+ # shader for the given material and lighting configuration.
3240
+ shaderFlags = []
3241
+ for i in range(0, 8 + 1):
3242
+ for j in product((True, False), repeat=1):
3243
+ shaderFlags.append((i, j[0]))
3244
+
3245
+ # Compile shaders based on generated flags.
3246
+ for flag in shaderFlags:
3247
+ # Define GLSL preprocessor values to enable code paths for specific
3248
+ # material properties.
3249
+ srcDefs = {'MAX_LIGHTS': flag[0]}
3250
+
3251
+ if flag[1]: # has diffuse texture map
3252
+ srcDefs['DIFFUSE_TEXTURE'] = 1
3253
+
3254
+ # embed #DEFINE statements in GLSL source code
3255
+ vertSrc = gltools.embedShaderSourceDefs(
3256
+ _shaders.vertPhongLighting, srcDefs)
3257
+ fragSrc = gltools.embedShaderSourceDefs(
3258
+ _shaders.fragPhongLighting, srcDefs)
3259
+
3260
+ # build a shader program
3261
+ prog = gltools.createProgramObjectARB()
3262
+ vertexShader = gltools.compileShaderObjectARB(
3263
+ vertSrc, GL.GL_VERTEX_SHADER_ARB)
3264
+ fragmentShader = gltools.compileShaderObjectARB(
3265
+ fragSrc, GL.GL_FRAGMENT_SHADER_ARB)
3266
+
3267
+ gltools.attachObjectARB(prog, vertexShader)
3268
+ gltools.attachObjectARB(prog, fragmentShader)
3269
+ gltools.linkProgramObjectARB(prog)
3270
+ gltools.detachObjectARB(prog, vertexShader)
3271
+ gltools.detachObjectARB(prog, fragmentShader)
3272
+ gltools.deleteObjectARB(vertexShader)
3273
+ gltools.deleteObjectARB(fragmentShader)
3274
+
3275
+ # set the flag
3276
+ self._shaders['stim3d_phong'][flag] = prog
3277
+
3278
+ def _setupFrameBuffer(self):
3279
+
3280
+ # Setup framebuffer
3281
+ self.frameBuffer = GL.GLuint()
3282
+ GL.glGenFramebuffersEXT(1, ctypes.byref(self.frameBuffer))
3283
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, self.frameBuffer)
3284
+
3285
+ # Create texture to render to
3286
+ self.frameTexture = GL.GLuint()
3287
+ GL.glGenTextures(1, ctypes.byref(self.frameTexture))
3288
+ GL.glBindTexture(GL.GL_TEXTURE_2D, self.frameTexture)
3289
+ GL.glTexParameteri(GL.GL_TEXTURE_2D,
3290
+ GL.GL_TEXTURE_MAG_FILTER,
3291
+ GL.GL_LINEAR)
3292
+ GL.glTexParameteri(GL.GL_TEXTURE_2D,
3293
+ GL.GL_TEXTURE_MIN_FILTER,
3294
+ GL.GL_LINEAR)
3295
+ GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA32F_ARB,
3296
+ int(self.size[0]), int(self.size[1]), 0,
3297
+ GL.GL_RGBA, GL.GL_FLOAT, None)
3298
+ # attach texture to the frame buffer
3299
+ GL.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT,
3300
+ GL.GL_COLOR_ATTACHMENT0_EXT,
3301
+ GL.GL_TEXTURE_2D, self.frameTexture, 0)
3302
+
3303
+ # add a stencil buffer
3304
+ self._stencilTexture = GL.GLuint()
3305
+ GL.glGenRenderbuffersEXT(1, ctypes.byref(
3306
+ self._stencilTexture)) # like glGenTextures
3307
+ GL.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, self._stencilTexture)
3308
+ GL.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT,
3309
+ GL.GL_DEPTH24_STENCIL8_EXT,
3310
+ int(self.size[0]), int(self.size[1]))
3311
+ GL.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT,
3312
+ GL.GL_DEPTH_ATTACHMENT_EXT,
3313
+ GL.GL_RENDERBUFFER_EXT,
3314
+ self._stencilTexture)
3315
+ GL.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT,
3316
+ GL.GL_STENCIL_ATTACHMENT_EXT,
3317
+ GL.GL_RENDERBUFFER_EXT,
3318
+ self._stencilTexture)
3319
+
3320
+ status = GL.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT)
3321
+ if status != GL.GL_FRAMEBUFFER_COMPLETE_EXT:
3322
+ logging.error("Error in framebuffer activation")
3323
+ # UNBIND THE FRAME BUFFER OBJECT THAT WE HAD CREATED
3324
+ GL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0)
3325
+ return False
3326
+ GL.glDisable(GL.GL_TEXTURE_2D)
3327
+ # clear the buffers (otherwise the texture memory can contain
3328
+ # junk from other app)
3329
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT)
3330
+ GL.glClear(GL.GL_STENCIL_BUFFER_BIT)
3331
+ GL.glClear(GL.GL_DEPTH_BUFFER_BIT)
3332
+ return True
3333
+
3334
+ @attributeSetter
3335
+ def mouseVisible(self, visibility):
3336
+ """Sets the visibility of the mouse cursor.
3337
+
3338
+ If Window was initialized with ``allowGUI=False`` then the mouse is
3339
+ initially set to invisible, otherwise it will initially be visible.
3340
+
3341
+ Usage::
3342
+
3343
+ win.mouseVisible = False
3344
+ win.mouseVisible = True
3345
+
3346
+ """
3347
+ self.backend.setMouseVisibility(visibility)
3348
+ self.__dict__['mouseVisible'] = visibility
3349
+
3350
+ def setMouseVisible(self, visibility, log=None):
3351
+ """Usually you can use 'stim.attribute = value' syntax instead,
3352
+ but use this method if you need to suppress the log message."""
3353
+ setAttribute(self, 'mouseVisible', visibility, log)
3354
+
3355
+ def setMouseType(self, name='arrow'):
3356
+ """Change the appearance of the cursor for this window. Cursor types
3357
+ provide contextual hints about how to interact with on-screen objects.
3358
+
3359
+ The graphics used 'standard cursors' provided by the operating system.
3360
+ They may vary in appearance and hot spot location across platforms. The
3361
+ following names are valid on most platforms:
3362
+
3363
+ * ``arrow`` : Default pointer.
3364
+ * ``ibeam`` : Indicates text can be edited.
3365
+ * ``crosshair`` : Crosshair with hot-spot at center.
3366
+ * ``hand`` : A pointing hand.
3367
+ * ``hresize`` : Double arrows pointing horizontally.
3368
+ * ``vresize`` : Double arrows pointing vertically.
3369
+
3370
+ Parameters
3371
+ ----------
3372
+ name : str
3373
+ Type of standard cursor to use (see above). Default is ``arrow``.
3374
+
3375
+ Notes
3376
+ -----
3377
+ * On Windows the ``crosshair`` option is negated with the background
3378
+ color. It will not be visible when placed over 50% grey fields.
3379
+
3380
+ """
3381
+ if hasattr(self.backend, "setMouseType"):
3382
+ self.backend.setMouseType(name)
3383
+
3384
+ def showPilotingIndicator(self):
3385
+ """
3386
+ Show the visual indicator which shows we are in piloting mode.
3387
+ """
3388
+ # if we haven't made the indicator yet, do that now
3389
+ if self._pilotingIndicator is None:
3390
+ self._pilotingIndicator = TextBox2(
3391
+ self, text=_translate("PILOTING: Switch to run mode before testing."),
3392
+ letterHeight=0.1, alignment="bottom left",
3393
+ units="norm", size=(2, 2),
3394
+ borderColor="#EC9703", color="#EC9703", fillColor="transparent",
3395
+ borderWidth=20,
3396
+ autoDraw=False
3397
+ )
3398
+ # mark it as to be shown
3399
+ self._showPilotingIndicator = True
3400
+
3401
+ def hidePilotingIndicator(self):
3402
+ """
3403
+ Hide the visual indicator which shows we are in piloting mode.
3404
+ """
3405
+ # mark indicator as to be hidden
3406
+ self._showPilotingIndicator = False
3407
+
3408
+ def showMessage(self, msg):
3409
+ """Show a message in the window. This can be used to show information
3410
+ to the participant.
3411
+
3412
+ This creates a TextBox2 object that is displayed in the window. The
3413
+ text can be updated by calling this method again with a new message.
3414
+ The updated text will appear the next time `draw()` is called.
3415
+
3416
+ Parameters
3417
+ ----------
3418
+ msg : str or None
3419
+ Message text to display. If None, then any existing message is
3420
+ removed.
3421
+
3422
+ """
3423
+ if msg is None:
3424
+ self.hideMessage()
3425
+ else:
3426
+ self._showSplash = True
3427
+
3428
+ if self._splashTextbox is None: # create the textbox
3429
+ self._splashTextbox = TextBox2(
3430
+ self, text=msg,
3431
+ units="norm", size=(2, 2), alignment="center", # full screen and centred
3432
+ letterHeight=0.1, # font size relative to window
3433
+ autoDraw=False
3434
+ )
3435
+ else:
3436
+ self._splashTextbox.text = str(msg) # update the text
3437
+ # set text color to contrast with background
3438
+ self._splashTextbox.color = self._color.getReadable(contrast=1)
3439
+
3440
+ def hideMessage(self):
3441
+ """Remove any message that is currently being displayed."""
3442
+ self._showSplash = False
3443
+
3444
+ def getActualFrameRate(self, nIdentical=10, nMaxFrames=100,
3445
+ nWarmUpFrames=10, threshold=1, infoMsg=None):
3446
+ """Measures the actual frames-per-second (FPS) for the screen.
3447
+
3448
+ This is done by waiting (for a max of `nMaxFrames`) until
3449
+ `nIdentical` frames in a row have identical frame times (std dev below
3450
+ `threshold` ms).
3451
+
3452
+ Parameters
3453
+ ----------
3454
+ nIdentical : int, optional
3455
+ The number of consecutive frames that will be evaluated.
3456
+ Higher --> greater precision. Lower --> faster.
3457
+ nMaxFrames : int, optional
3458
+ The maximum number of frames to wait for a matching set of
3459
+ nIdentical.
3460
+ nWarmUpFrames : int, optional
3461
+ The number of frames to display before starting the test
3462
+ (this is in place to allow the system to settle after opening
3463
+ the `Window` for the first time.
3464
+ threshold : int or float, optional
3465
+ The threshold for the std deviation (in ms) before the set
3466
+ are considered a match.
3467
+
3468
+ Returns
3469
+ -------
3470
+ float or None
3471
+ Frame rate (FPS) in seconds. If there is no such sequence of
3472
+ identical frames a warning is logged and `None` will be returned.
3473
+
3474
+ """
3475
+ if nIdentical > nMaxFrames:
3476
+ raise ValueError(
3477
+ 'Parameter `nIdentical` must be equal to or less than '
3478
+ '`nMaxFrames`')
3479
+
3480
+ screen = self.screen
3481
+ name = self.name
3482
+
3483
+ if infoMsg is None:
3484
+ infoMsg = "Attempting to measure frame rate of screen, please wait ..."
3485
+
3486
+ self.showMessage(infoMsg)
3487
+
3488
+ # log that we're measuring the frame rate now
3489
+ if self.autoLog:
3490
+ msg = "{}: Attempting to measure frame rate of screen ({:d}) ..."
3491
+ logging.exp(msg.format(name, screen))
3492
+
3493
+ # Disable `recordFrameIntervals` prior to the warmup as we expect to see
3494
+ # some instability here.
3495
+ recordFrmIntsOrig = self.recordFrameIntervals
3496
+ self.recordFrameIntervals = False
3497
+
3498
+ # warm-up, allow the system to settle a bit before measuring frames
3499
+ for frameN in range(nWarmUpFrames):
3500
+ self.flip()
3501
+
3502
+ # run test frames
3503
+ self.recordFrameIntervals = True # record intervals for actual test
3504
+ threshSecs = threshold / 1000.0 # must be in seconds
3505
+ for frameN in range(nMaxFrames):
3506
+ self.flip()
3507
+ recentFrames = self.frameIntervals[-nIdentical:]
3508
+ nIntervals = len(self.frameIntervals)
3509
+ if len(recentFrames) < 3:
3510
+ continue # no need to check variance yet
3511
+ recentFramesStd = numpy.std(recentFrames) # compute variability
3512
+ if nIntervals >= nIdentical and recentFramesStd < threshSecs:
3513
+ # average duration of recent frames
3514
+ period = numpy.mean(recentFrames) # log this too?
3515
+ rate = 1.0 / period # compute frame rate in Hz
3516
+ if self.autoLog:
3517
+ scrStr = "" if screen is None else " (%i)" % screen
3518
+ msg = "Screen{} actual frame rate measured at {:.2f}Hz"
3519
+ logging.exp(msg.format(scrStr, rate))
3520
+
3521
+ self.recordFrameIntervals = recordFrmIntsOrig
3522
+ self.frameIntervals = []
3523
+ self.hideMessage() # remove the message
3524
+ return rate
3525
+
3526
+ self.hideMessage() # remove the message
3527
+
3528
+ # if we get here we reached end of `maxFrames` with no consistent value
3529
+ msg = ("Couldn't measure a consistent frame rate!\n"
3530
+ " - Is your graphics card set to sync to vertical blank?\n"
3531
+ " - Are you running other processes on your computer?\n")
3532
+ logging.warning(msg)
3533
+
3534
+ return None
3535
+
3536
+ def getMsPerFrame(self, nFrames=60, showVisual=False, msg='', msDelay=0.):
3537
+ """Assesses the monitor refresh rate (average, median, SD) under
3538
+ current conditions, over at least 60 frames.
3539
+
3540
+ Records time for each refresh (frame) for n frames (at least 60),
3541
+ while displaying an optional visual. The visual is just eye-candy to
3542
+ show that something is happening when assessing many frames. You can
3543
+ also give it text to display instead of a visual,
3544
+ e.g., ``msg='(testing refresh rate...)'``; setting msg implies
3545
+ ``showVisual == False``.
3546
+
3547
+ To simulate refresh rate under cpu load, you can specify a time to
3548
+ wait within the loop prior to doing the :py:attr:`~Window.flip()`.
3549
+ If 0 < msDelay < 100, wait for that long in ms.
3550
+
3551
+ Returns timing stats (in ms) of:
3552
+
3553
+ - average time per frame, for all frames
3554
+ - standard deviation of all frames
3555
+ - median, as the average of 12 frame times around the median
3556
+ (~monitor refresh rate)
3557
+
3558
+ :Author:
3559
+ - 2010 written by Jeremy Gray
3560
+
3561
+ """
3562
+
3563
+ # lower bound of 60 samples--need enough to estimate the SD
3564
+ nFrames = max(60, nFrames)
3565
+ num2avg = 12 # how many to average from around the median
3566
+ if len(msg):
3567
+ showVisual = False
3568
+ showText = True
3569
+ myMsg = TextStim(self, text=msg, italic=True,
3570
+ color=(.7, .6, .5), colorSpace='rgb',
3571
+ height=0.1, autoLog=False)
3572
+ else:
3573
+ showText = False
3574
+ if showVisual:
3575
+ x, y = self.size
3576
+ myStim = GratingStim(self, tex='sin', mask='gauss',
3577
+ size=[.6 * y / float(x), .6], sf=3.0,
3578
+ opacity=.2,
3579
+ autoLog=False)
3580
+ clockt = [] # clock times
3581
+ # end of drawing time, in clock time units,
3582
+ # for testing how long myStim.draw() takes
3583
+ drawt = []
3584
+
3585
+ if msDelay > 0 and msDelay < 100:
3586
+ doWait = True
3587
+ delayTime = msDelay / 1000. # sec
3588
+ else:
3589
+ doWait = False
3590
+
3591
+ winUnitsSaved = self.units
3592
+ # norm is required for the visual (or text) display, as coded below
3593
+ self.units = 'norm'
3594
+
3595
+ # accumulate secs per frame (and time-to-draw) for a bunch of frames:
3596
+ rush(True)
3597
+ for i in range(5): # wake everybody up
3598
+ self.flip()
3599
+ for i in range(nFrames): # ... and go for real this time
3600
+ clockt.append(core.getTime())
3601
+ if showVisual:
3602
+ myStim.setPhase(1.0 / nFrames, '+', log=False)
3603
+ myStim.setSF(3. / nFrames, '+', log=False)
3604
+ myStim.setOri(12. / nFrames, '+', log=False)
3605
+ myStim.setOpacity(.9 / nFrames, '+', log=False)
3606
+ myStim.draw()
3607
+ elif showText:
3608
+ myMsg.draw()
3609
+ if doWait:
3610
+ core.wait(delayTime)
3611
+ drawt.append(core.getTime())
3612
+ self.flip()
3613
+ rush(False)
3614
+
3615
+ self.units = winUnitsSaved # restore
3616
+
3617
+ frameTimes = [(clockt[i] - clockt[i - 1])
3618
+ for i in range(1, len(clockt))]
3619
+ drawTimes = [(drawt[i] - clockt[i]) for
3620
+ i in range(len(clockt))] # == drawing only
3621
+ freeTimes = [frameTimes[i] - drawTimes[i] for
3622
+ i in range(len(frameTimes))] # == unused time
3623
+
3624
+ # cast to float so that the resulting type == type(0.123)
3625
+ # for median
3626
+ frameTimes.sort()
3627
+ # median-most slice
3628
+ msPFmed = 1000. * float(numpy.average(
3629
+ frameTimes[((nFrames - num2avg) // 2):((nFrames + num2avg) // 2)]))
3630
+ msPFavg = 1000. * float(numpy.average(frameTimes))
3631
+ msPFstd = 1000. * float(numpy.std(frameTimes))
3632
+ msdrawAvg = 1000. * float(numpy.average(drawTimes))
3633
+ msdrawSD = 1000. * float(numpy.std(drawTimes))
3634
+ msfree = 1000. * float(numpy.average(freeTimes))
3635
+
3636
+ return msPFavg, msPFstd, msPFmed # msdrawAvg, msdrawSD, msfree
3637
+
3638
+ def _startOfFlip(self):
3639
+ """Custom hardware classes may want to prevent flipping from
3640
+ occurring and can override this method as needed.
3641
+
3642
+ Return `True` to indicate hardware flip.
3643
+ """
3644
+ return True
3645
+
3646
+ def _renderFBO(self):
3647
+ """Perform a warp operation.
3648
+
3649
+ (in this case a copy operation without any warping)
3650
+ """
3651
+ GL.glBegin(GL.GL_QUADS)
3652
+ GL.glTexCoord2f(0.0, 0.0)
3653
+ GL.glVertex2f(-1.0, -1.0)
3654
+ GL.glTexCoord2f(0.0, 1.0)
3655
+ GL.glVertex2f(-1.0, 1.0)
3656
+ GL.glTexCoord2f(1.0, 1.0)
3657
+ GL.glVertex2f(1.0, 1.0)
3658
+ GL.glTexCoord2f(1.0, 0.0)
3659
+ GL.glVertex2f(1.0, -1.0)
3660
+ GL.glEnd()
3661
+
3662
+ def _prepareFBOrender(self):
3663
+ GL.glUseProgram(self._progFBOtoFrame)
3664
+
3665
+ def _finishFBOrender(self):
3666
+ GL.glUseProgram(0)
3667
+
3668
+ def _afterFBOrender(self):
3669
+ pass
3670
+
3671
+ def _endOfFlip(self, clearBuffer):
3672
+ """Override end of flip with custom color channel masking if required.
3673
+ """
3674
+ if clearBuffer:
3675
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT)
3676
+
3677
+
3678
+ def getMsPerFrame(myWin, nFrames=60, showVisual=False, msg='', msDelay=0.):
3679
+ """
3680
+ Deprecated: please use the getMsPerFrame method in the
3681
+ `psychopy.visual.Window` class.
3682
+
3683
+ Assesses the monitor refresh rate (average, median, SD) under current
3684
+ conditions, over at least 60 frames.
3685
+
3686
+ Records time for each refresh (frame) for n frames (at least 60), while
3687
+ displaying an optional visual. The visual is just eye-candy to show that
3688
+ something is happening when assessing many frames. You can also give it
3689
+ text to display instead of a visual, e.g.,
3690
+ msg='(testing refresh rate...)'; setting msg implies showVisual == False.
3691
+ To simulate refresh rate under
3692
+ cpu load, you can specify a time to wait within the loop prior to
3693
+ doing the win.flip(). If 0 < msDelay < 100, wait for that long in ms.
3694
+
3695
+ Returns timing stats (in ms) of:
3696
+
3697
+ - average time per frame, for all frames
3698
+ - standard deviation of all frames
3699
+ - median, as the average of 12 frame times around the median
3700
+ (~monitor refresh rate)
3701
+
3702
+ :Author:
3703
+ - 2010 written by Jeremy Gray
3704
+ """
3705
+ return myWin.getMsPerFrame(nFrames=60, showVisual=showVisual, msg=msg,
3706
+ msDelay=0.)