psychopy 2024.2.5__py3-none-any.whl → 2025.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 (860) hide show
  1. psychopy/CHANGELOG.txt +4 -4
  2. psychopy/GIT_SHA +1 -1
  3. psychopy/LICENSE.txt +1 -1
  4. psychopy/VERSION +1 -1
  5. psychopy/__init__.py +10 -7
  6. psychopy/alerts/__init__.py +1 -1
  7. psychopy/alerts/_alerts.py +53 -17
  8. psychopy/alerts/_errorHandler.py +3 -4
  9. psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
  10. psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
  11. psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
  12. psychopy/alerts/alertsCatalogue/alertCategories.yaml +8 -1
  13. psychopy/alerts/alertsCatalogue/alertmsg.py +1 -1
  14. psychopy/alerts/alerttools.py +0 -16
  15. psychopy/app/Resources/betasplash.png +0 -0
  16. psychopy/app/Resources/betasplash@2x.png +0 -0
  17. psychopy/app/Resources/classic/case.png +0 -0
  18. psychopy/app/Resources/classic/case@2x.png +0 -0
  19. psychopy/app/Resources/classic/fileaudio.png +0 -0
  20. psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
  21. psychopy/app/Resources/classic/filecss.png +0 -0
  22. psychopy/app/Resources/classic/filecss@2x.png +0 -0
  23. psychopy/app/Resources/classic/filecsv.png +0 -0
  24. psychopy/app/Resources/classic/filecsv@2x.png +0 -0
  25. psychopy/app/Resources/classic/filedesign.png +0 -0
  26. psychopy/app/Resources/classic/filedesign@2x.png +0 -0
  27. psychopy/app/Resources/classic/filefont.png +0 -0
  28. psychopy/app/Resources/classic/filefont@2x.png +0 -0
  29. psychopy/app/Resources/classic/filegit.png +0 -0
  30. psychopy/app/Resources/classic/filegit@2x.png +0 -0
  31. psychopy/app/Resources/classic/filehtml.png +0 -0
  32. psychopy/app/Resources/classic/filehtml@2x.png +0 -0
  33. psychopy/app/Resources/classic/fileimage.png +0 -0
  34. psychopy/app/Resources/classic/fileimage@2x.png +0 -0
  35. psychopy/app/Resources/classic/fileinfo.png +0 -0
  36. psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
  37. psychopy/app/Resources/classic/filejs.png +0 -0
  38. psychopy/app/Resources/classic/filejs@2x.png +0 -0
  39. psychopy/app/Resources/classic/filejson.png +0 -0
  40. psychopy/app/Resources/classic/filejson@2x.png +0 -0
  41. psychopy/app/Resources/classic/filepkg.png +0 -0
  42. psychopy/app/Resources/classic/filepkg@2x.png +0 -0
  43. psychopy/app/Resources/classic/filepsyexp.png +0 -0
  44. psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
  45. psychopy/app/Resources/classic/filepy.png +0 -0
  46. psychopy/app/Resources/classic/filepy@2x.png +0 -0
  47. psychopy/app/Resources/classic/filetxt.png +0 -0
  48. psychopy/app/Resources/classic/filetxt@2x.png +0 -0
  49. psychopy/app/Resources/classic/fileunknown.png +0 -0
  50. psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
  51. psychopy/app/Resources/classic/filevideo.png +0 -0
  52. psychopy/app/Resources/classic/filevideo@2x.png +0 -0
  53. psychopy/app/Resources/classic/find.png +0 -0
  54. psychopy/app/Resources/classic/find@2x.png +0 -0
  55. psychopy/app/Resources/classic/loop.png +0 -0
  56. psychopy/app/Resources/classic/loop@2x.png +0 -0
  57. psychopy/app/Resources/classic/regex.png +0 -0
  58. psychopy/app/Resources/classic/regex@2x.png +0 -0
  59. psychopy/app/Resources/dark/case.png +0 -0
  60. psychopy/app/Resources/dark/case@2x.png +0 -0
  61. psychopy/app/Resources/dark/fileaudio.png +0 -0
  62. psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
  63. psychopy/app/Resources/dark/filecss.png +0 -0
  64. psychopy/app/Resources/dark/filecss@2x.png +0 -0
  65. psychopy/app/Resources/dark/filecsv.png +0 -0
  66. psychopy/app/Resources/dark/filecsv@2x.png +0 -0
  67. psychopy/app/Resources/dark/filedesign.png +0 -0
  68. psychopy/app/Resources/dark/filedesign@2x.png +0 -0
  69. psychopy/app/Resources/dark/filefont.png +0 -0
  70. psychopy/app/Resources/dark/filefont@2x.png +0 -0
  71. psychopy/app/Resources/dark/filegit.png +0 -0
  72. psychopy/app/Resources/dark/filegit@2x.png +0 -0
  73. psychopy/app/Resources/dark/filehtml.png +0 -0
  74. psychopy/app/Resources/dark/filehtml@2x.png +0 -0
  75. psychopy/app/Resources/dark/fileimage.png +0 -0
  76. psychopy/app/Resources/dark/fileimage@2x.png +0 -0
  77. psychopy/app/Resources/dark/fileinfo.png +0 -0
  78. psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
  79. psychopy/app/Resources/dark/filejs.png +0 -0
  80. psychopy/app/Resources/dark/filejs@2x.png +0 -0
  81. psychopy/app/Resources/dark/filejson.png +0 -0
  82. psychopy/app/Resources/dark/filejson@2x.png +0 -0
  83. psychopy/app/Resources/dark/filepkg.png +0 -0
  84. psychopy/app/Resources/dark/filepkg@2x.png +0 -0
  85. psychopy/app/Resources/dark/filepsyexp.png +0 -0
  86. psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
  87. psychopy/app/Resources/dark/filepy.png +0 -0
  88. psychopy/app/Resources/dark/filepy@2x.png +0 -0
  89. psychopy/app/Resources/dark/filetxt.png +0 -0
  90. psychopy/app/Resources/dark/filetxt@2x.png +0 -0
  91. psychopy/app/Resources/dark/fileunknown.png +0 -0
  92. psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
  93. psychopy/app/Resources/dark/filevideo.png +0 -0
  94. psychopy/app/Resources/dark/filevideo@2x.png +0 -0
  95. psychopy/app/Resources/dark/find.png +0 -0
  96. psychopy/app/Resources/dark/find@2x.png +0 -0
  97. psychopy/app/Resources/dark/loop.png +0 -0
  98. psychopy/app/Resources/dark/loop@2x.png +0 -0
  99. psychopy/app/Resources/dark/regex.png +0 -0
  100. psychopy/app/Resources/dark/regex@2x.png +0 -0
  101. psychopy/app/Resources/light/case.png +0 -0
  102. psychopy/app/Resources/light/case@2x.png +0 -0
  103. psychopy/app/Resources/light/fileaudio.png +0 -0
  104. psychopy/app/Resources/light/fileaudio@2x.png +0 -0
  105. psychopy/app/Resources/light/filecss.png +0 -0
  106. psychopy/app/Resources/light/filecss@2x.png +0 -0
  107. psychopy/app/Resources/light/filecsv.png +0 -0
  108. psychopy/app/Resources/light/filecsv@2x.png +0 -0
  109. psychopy/app/Resources/light/filedesign.png +0 -0
  110. psychopy/app/Resources/light/filedesign@2x.png +0 -0
  111. psychopy/app/Resources/light/filefont.png +0 -0
  112. psychopy/app/Resources/light/filefont@2x.png +0 -0
  113. psychopy/app/Resources/light/filegit.png +0 -0
  114. psychopy/app/Resources/light/filegit@2x.png +0 -0
  115. psychopy/app/Resources/light/filehtml.png +0 -0
  116. psychopy/app/Resources/light/filehtml@2x.png +0 -0
  117. psychopy/app/Resources/light/fileimage.png +0 -0
  118. psychopy/app/Resources/light/fileimage@2x.png +0 -0
  119. psychopy/app/Resources/light/fileinfo.png +0 -0
  120. psychopy/app/Resources/light/fileinfo@2x.png +0 -0
  121. psychopy/app/Resources/light/filejs.png +0 -0
  122. psychopy/app/Resources/light/filejs@2x.png +0 -0
  123. psychopy/app/Resources/light/filejson.png +0 -0
  124. psychopy/app/Resources/light/filejson@2x.png +0 -0
  125. psychopy/app/Resources/light/filepkg.png +0 -0
  126. psychopy/app/Resources/light/filepkg@2x.png +0 -0
  127. psychopy/app/Resources/light/filepsyexp.png +0 -0
  128. psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
  129. psychopy/app/Resources/light/filepy.png +0 -0
  130. psychopy/app/Resources/light/filepy@2x.png +0 -0
  131. psychopy/app/Resources/light/filetxt.png +0 -0
  132. psychopy/app/Resources/light/filetxt@2x.png +0 -0
  133. psychopy/app/Resources/light/fileunknown.png +0 -0
  134. psychopy/app/Resources/light/fileunknown@2x.png +0 -0
  135. psychopy/app/Resources/light/filevideo.png +0 -0
  136. psychopy/app/Resources/light/filevideo@2x.png +0 -0
  137. psychopy/app/Resources/light/find.png +0 -0
  138. psychopy/app/Resources/light/find@2x.png +0 -0
  139. psychopy/app/Resources/light/loop.png +0 -0
  140. psychopy/app/Resources/light/loop@2x.png +0 -0
  141. psychopy/app/Resources/light/regex.png +0 -0
  142. psychopy/app/Resources/light/regex@2x.png +0 -0
  143. psychopy/app/Resources/routine_templates/Basic.psyexp +0 -1
  144. psychopy/app/Resources/routine_templates/Misc.psyexp +0 -1
  145. psychopy/app/Resources/routine_templates/Online.psyexp +0 -2
  146. psychopy/app/Resources/routine_templates/Trials.psyexp +0 -1
  147. psychopy/app/Resources/splash.png +0 -0
  148. psychopy/app/Resources/splash@2x.png +0 -0
  149. psychopy/app/__init__.py +49 -8
  150. psychopy/app/__main__.py +3 -0
  151. psychopy/app/_psychopyApp.py +134 -125
  152. psychopy/app/builder/builder.py +42 -22
  153. psychopy/app/builder/dialogs/__init__.py +44 -11
  154. psychopy/app/builder/dialogs/dlgsCode.py +1 -1
  155. psychopy/app/builder/dialogs/dlgsConditions.py +1 -1
  156. psychopy/app/builder/dialogs/findDlg.py +106 -20
  157. psychopy/app/builder/dialogs/paramCtrls.py +42 -1
  158. psychopy/app/builder/validators.py +1 -1
  159. psychopy/app/coder/codeEditorBase.py +8 -8
  160. psychopy/app/coder/coder.py +32 -29
  161. psychopy/app/coder/fileBrowser.py +68 -22
  162. psychopy/app/coder/folding.py +1 -1
  163. psychopy/app/coder/psychoParser.py +1 -1
  164. psychopy/app/coder/repl.py +1 -1
  165. psychopy/app/coder/sourceTree.py +1 -1
  166. psychopy/app/connections/__init__.py +1 -1
  167. psychopy/app/connections/news.py +1 -1
  168. psychopy/app/connections/sendusage.py +1 -1
  169. psychopy/app/connections/updates.py +1 -1
  170. psychopy/app/console.py +1 -1
  171. psychopy/app/errorDlg.py +1 -1
  172. psychopy/app/frametracker.py +1 -1
  173. psychopy/app/idle.py +1 -1
  174. psychopy/app/jobs.py +5 -2
  175. psychopy/app/linuxconfig/__init__.py +1 -1
  176. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  177. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4 -4
  178. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  179. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  180. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  181. psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +3 -3
  182. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  183. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  184. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  185. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  186. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +4 -4
  187. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  188. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +4 -4
  189. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  190. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +4 -4
  191. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  192. psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +2 -2
  193. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  194. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +1 -1
  195. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  196. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  197. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +2 -2
  198. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  199. psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +2 -2
  200. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  201. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +2 -2
  202. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  203. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  204. psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +2 -2
  205. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  206. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3421 -2396
  207. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  208. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  209. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +2 -2
  210. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  211. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  212. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  213. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  214. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +4 -4
  215. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  216. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  217. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  218. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +2 -2
  219. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  220. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +2 -2
  221. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  222. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +3 -3
  223. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  224. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +2 -2
  225. psychopy/app/{builder/localizedStrings.py → localizedStrings.py} +173 -26
  226. psychopy/app/pavlovia_ui/__init__.py +1 -1
  227. psychopy/app/pavlovia_ui/_base.py +1 -1
  228. psychopy/app/pavlovia_ui/functions.py +1 -1
  229. psychopy/app/pavlovia_ui/menu.py +1 -1
  230. psychopy/app/pavlovia_ui/project.py +1 -1
  231. psychopy/app/pavlovia_ui/search.py +1 -1
  232. psychopy/app/pavlovia_ui/sync.py +1 -1
  233. psychopy/app/pavlovia_ui/user.py +1 -1
  234. psychopy/app/plugin_manager/dialog.py +34 -96
  235. psychopy/app/plugin_manager/packages.py +10 -14
  236. psychopy/app/plugin_manager/plugins.py +64 -4
  237. psychopy/app/preferencesDlg.py +12 -37
  238. psychopy/app/psychopyApp.py +130 -44
  239. psychopy/app/ribbon.py +1 -0
  240. psychopy/app/runner/runner.py +19 -7
  241. psychopy/app/runner/scriptProcess.py +11 -6
  242. psychopy/app/stdout/stdOutRich.py +9 -2
  243. psychopy/app/themes/fonts.py +1 -1
  244. psychopy/app/themes/icons.py +2 -38
  245. psychopy/app/ui/__init__.py +1 -1
  246. psychopy/app/utils.py +3 -3
  247. psychopy/assets/default.mp3 +0 -0
  248. psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
  249. psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
  250. psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
  251. psychopy/assets/fonts/NotoSans-Regular.ttf +0 -0
  252. psychopy/assets/voicekeyThresholdStim.wav +0 -0
  253. psychopy/clock.py +4 -1
  254. psychopy/colors.py +2 -0
  255. psychopy/core.py +1 -1
  256. psychopy/data/base.py +1 -1
  257. psychopy/data/experiment.py +151 -46
  258. psychopy/data/routine.py +27 -1
  259. psychopy/data/staircase.py +2 -1
  260. psychopy/data/trial.py +62 -14
  261. psychopy/data/utils.py +1 -1
  262. psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +333 -218
  263. psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +261 -239
  264. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +319 -180
  265. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +204 -116
  266. psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
  267. psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
  268. psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
  269. psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
  270. psychopy/demos/builder/Experiments/BART/bart.psyexp +779 -866
  271. psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +242 -180
  272. psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +419 -406
  273. psychopy/demos/builder/Experiments/dragAndDrop/README.md +2 -37
  274. psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +460 -1204
  275. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
  276. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
  277. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
  278. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
  279. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
  280. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
  281. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
  282. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
  283. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
  284. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
  285. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
  286. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
  287. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
  288. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
  289. psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +583 -542
  290. psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +458 -427
  291. psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +588 -550
  292. psychopy/demos/builder/Experiments/stroop/stroop.psyexp +303 -207
  293. psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +390 -215
  294. psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +390 -215
  295. psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +357 -331
  296. psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -2
  297. psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +287 -277
  298. psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +370 -320
  299. psychopy/demos/builder/Feature Demos/noise/noise.psyexp +452 -399
  300. psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +168 -133
  301. psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +4 -3
  302. psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +420 -392
  303. psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +917 -871
  304. psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
  305. psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +200 -0
  306. psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +25 -9
  307. psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +372 -361
  308. psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +25 -9
  309. psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +320 -235
  310. psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +790 -651
  311. psychopy/demos/builder/Hardware/camera/camera.psyexp +326 -246
  312. psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +432 -327
  313. psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +440 -321
  314. psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +190 -181
  315. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +323 -312
  316. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
  317. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp +312 -0
  318. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +329 -273
  319. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
  320. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
  321. psychopy/demos/builder/Hardware/microphone/microphone.psyexp +450 -404
  322. psychopy/demos/builder/Hardware/pump/pump.psyexp +593 -329
  323. psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
  324. psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +336 -274
  325. psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +200 -149
  326. psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -279
  327. psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +677 -564
  328. psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +214 -158
  329. psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +195 -146
  330. psychopy/demos/coder/experiment control/runtimeInfo.py +1 -1
  331. psychopy/devices/__init__.py +1 -1
  332. psychopy/event.py +1 -1
  333. psychopy/exceptions.py +1 -1
  334. psychopy/experiment/__init__.py +1 -1
  335. psychopy/experiment/_experiment.py +30 -9
  336. psychopy/experiment/components/__init__.py +1 -6
  337. psychopy/experiment/components/_base.py +44 -19
  338. psychopy/experiment/components/aperture/__init__.py +1 -1
  339. psychopy/experiment/components/brush/__init__.py +2 -2
  340. psychopy/experiment/components/button/__init__.py +24 -28
  341. psychopy/experiment/components/camera/__init__.py +38 -39
  342. psychopy/experiment/components/code/__init__.py +1 -1
  343. psychopy/experiment/components/dots/__init__.py +1 -1
  344. psychopy/experiment/components/eyetracker_record/__init__.py +7 -3
  345. psychopy/experiment/components/form/__init__.py +3 -3
  346. psychopy/experiment/components/grating/__init__.py +1 -1
  347. psychopy/experiment/components/image/__init__.py +1 -1
  348. psychopy/experiment/components/joyButtons/__init__.py +2 -2
  349. psychopy/experiment/components/joyButtons/virtualJoyButtons.py +1 -1
  350. psychopy/experiment/components/joystick/__init__.py +3 -3
  351. psychopy/experiment/components/joystick/virtualJoystick.py +1 -1
  352. psychopy/experiment/components/keyboard/__init__.py +98 -122
  353. psychopy/experiment/components/microphone/__init__.py +54 -98
  354. psychopy/experiment/components/mouse/__init__.py +92 -93
  355. psychopy/experiment/components/movie/__init__.py +28 -50
  356. psychopy/experiment/components/parallelOut/__init__.py +3 -3
  357. psychopy/experiment/components/polygon/__init__.py +2 -3
  358. psychopy/experiment/components/roi/__init__.py +2 -2
  359. psychopy/experiment/components/routineSettings/__init__.py +2 -0
  360. psychopy/experiment/components/serialOut/__init__.py +7 -7
  361. psychopy/experiment/components/settings/__init__.py +317 -313
  362. psychopy/experiment/components/settings/eyetracking.py +108 -0
  363. psychopy/experiment/components/slider/__init__.py +5 -5
  364. psychopy/experiment/components/sound/__init__.py +168 -78
  365. psychopy/experiment/components/soundsensor/__init__.py +361 -0
  366. psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
  367. psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
  368. psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
  369. psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
  370. psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
  371. psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
  372. psychopy/experiment/components/static/__init__.py +59 -33
  373. psychopy/experiment/components/text/__init__.py +2 -6
  374. psychopy/experiment/components/textbox/__init__.py +3 -7
  375. psychopy/experiment/components/unknown/__init__.py +2 -0
  376. psychopy/experiment/components/unknownPlugin/__init__.py +2 -0
  377. psychopy/experiment/exports.py +1 -1
  378. psychopy/experiment/flow.py +2 -2
  379. psychopy/experiment/localization.py +1 -1
  380. psychopy/experiment/loops.py +43 -10
  381. psychopy/experiment/params.py +6 -4
  382. psychopy/experiment/plugins.py +8 -1
  383. psychopy/experiment/py2js.py +1 -1
  384. psychopy/experiment/py2js_transpiler.py +1 -1
  385. psychopy/experiment/routines/__init__.py +1 -1
  386. psychopy/experiment/routines/_base.py +23 -24
  387. psychopy/experiment/routines/audioValidator/__init__.py +343 -0
  388. psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
  389. psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
  390. psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
  391. psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
  392. psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
  393. psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
  394. psychopy/experiment/routines/eyetracker_calibrate/__init__.py +76 -17
  395. psychopy/experiment/routines/eyetracker_validate/__init__.py +1 -1
  396. psychopy/experiment/routines/unknown/__init__.py +2 -0
  397. psychopy/experiment/routines/{photodiodeValidator → visualValidator}/__init__.py +89 -120
  398. psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
  399. psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
  400. psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
  401. psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
  402. psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
  403. psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
  404. psychopy/experiment/utils.py +1 -1
  405. psychopy/gui/__init__.py +1 -1
  406. psychopy/gui/qtgui.py +15 -6
  407. psychopy/gui/wxgui.py +1 -1
  408. psychopy/hardware/__init__.py +0 -1
  409. psychopy/hardware/base.py +147 -16
  410. psychopy/hardware/bbtk/__init__.py +10 -16
  411. psychopy/hardware/brainproducts.py +7 -13
  412. psychopy/hardware/button.py +21 -2
  413. psychopy/hardware/buttonbox/__init__.py +1 -1
  414. psychopy/hardware/camera/__init__.py +16 -3
  415. psychopy/hardware/cedrus.py +5 -16
  416. psychopy/hardware/crs/__init__.py +1 -1
  417. psychopy/hardware/crs/bits.py +36 -33
  418. psychopy/hardware/crs/colorcal.py +8 -11
  419. psychopy/hardware/crs/optical.py +7 -10
  420. psychopy/hardware/crs/shaders.py +18 -5
  421. psychopy/hardware/emotiv.py +1 -1
  422. psychopy/hardware/emulator.py +11 -5
  423. psychopy/hardware/exceptions.py +86 -0
  424. psychopy/hardware/forp.py +18 -23
  425. psychopy/hardware/gammasci.py +8 -3
  426. psychopy/hardware/iolab.py +8 -19
  427. psychopy/hardware/joystick/__init__.py +865 -266
  428. psychopy/hardware/joystick/_base.py +251 -0
  429. psychopy/hardware/joystick/backend_glfw.py +306 -0
  430. psychopy/hardware/joystick/backend_pyglet.py +309 -0
  431. psychopy/hardware/joystick/mappings.py +287 -0
  432. psychopy/hardware/keyboard.py +4 -2
  433. psychopy/hardware/labhackers.py +1 -1
  434. psychopy/hardware/labjacks.py +9 -13
  435. psychopy/hardware/{photodiode.py → lightsensor.py} +146 -203
  436. psychopy/hardware/listener.py +9 -8
  437. psychopy/hardware/manager.py +24 -35
  438. psychopy/hardware/microphone.py +534 -154
  439. psychopy/hardware/minolta.py +14 -4
  440. psychopy/hardware/mouse/__init__.py +1 -1
  441. psychopy/hardware/photometer/__init__.py +2 -2
  442. psychopy/hardware/pr.py +14 -4
  443. psychopy/hardware/qmix.py +18 -27
  444. psychopy/hardware/serialdevice.py +43 -12
  445. psychopy/hardware/soundsensor.py +473 -0
  446. psychopy/hardware/spatial/__init__.py +231 -0
  447. psychopy/hardware/speaker.py +298 -36
  448. psychopy/hardware/triggerbox/__init__.py +1 -1
  449. psychopy/hardware/triggerbox/base.py +1 -1
  450. psychopy/hardware/triggerbox/parallel.py +1 -1
  451. psychopy/info.py +1 -1
  452. psychopy/iohub/devices/eyetracker/__init__.py +10 -18
  453. psychopy/iohub/devices/eyetracker/calibration/procedure.py +15 -33
  454. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +1 -0
  455. psychopy/iohub/devices/mouse/linux2.py +2 -1
  456. psychopy/layout.py +1 -1
  457. psychopy/liaison.py +91 -39
  458. psychopy/locale_setup.py +11 -1
  459. psychopy/localization/__init__.py +1 -1
  460. psychopy/localization/_localization.py +1 -1
  461. psychopy/localization/messages.pot +2 -2
  462. psychopy/logging.py +14 -12
  463. psychopy/microphone.py +4 -3
  464. psychopy/misc.py +1 -1
  465. psychopy/monitors/MonitorCenter.py +3 -3
  466. psychopy/monitors/__init__.py +1 -1
  467. psychopy/monitors/calibData.py +1 -1
  468. psychopy/monitors/calibTools.py +3 -2
  469. psychopy/platform_specific/__init__.py +1 -1
  470. psychopy/platform_specific/darwin.py +1 -1
  471. psychopy/platform_specific/linux.py +1 -1
  472. psychopy/platform_specific/win32.py +1 -1
  473. psychopy/plugins/__init__.py +26 -17
  474. psychopy/plugins/util.py +65 -0
  475. psychopy/preferences/Darwin.spec +11 -3
  476. psychopy/preferences/FreeBSD.spec +11 -3
  477. psychopy/preferences/Linux.spec +11 -3
  478. psychopy/preferences/Windows.spec +11 -3
  479. psychopy/preferences/__init__.py +1 -1
  480. psychopy/preferences/baseNoArch.spec +11 -3
  481. psychopy/preferences/hints.py +78 -61
  482. psychopy/preferences/preferences.py +82 -13
  483. psychopy/projects/__init__.py +1 -1
  484. psychopy/projects/pavlovia.py +29 -13
  485. psychopy/scripts/psyexpCompile.py +1 -1
  486. psychopy/session.py +81 -8
  487. psychopy/sound/__init__.py +25 -10
  488. psychopy/sound/_base.py +134 -34
  489. psychopy/sound/audioclip.py +38 -15
  490. psychopy/sound/audiodevice.py +1 -1
  491. psychopy/sound/backend_ptb.py +53 -321
  492. psychopy/sound/backend_pygame.py +7 -3
  493. psychopy/sound/backend_pyo.py +53 -22
  494. psychopy/sound/backend_pysound.py +10 -27
  495. psychopy/sound/backend_sounddevice.py +33 -21
  496. psychopy/sound/exceptions.py +1 -1
  497. psychopy/sound/microphone.py +83 -5
  498. psychopy/sound/transcribe.py +3 -3
  499. psychopy/tests/data/test_basic_run.py +1 -0
  500. psychopy/tests/data/test_sounds/default_16000.wav +0 -0
  501. psychopy/tests/data/test_sounds/default_192000.wav +0 -0
  502. psychopy/tests/data/test_sounds/default_22050.wav +0 -0
  503. psychopy/tests/data/test_sounds/default_32000.wav +0 -0
  504. psychopy/tests/data/test_sounds/default_44100.wav +0 -0
  505. psychopy/tests/data/test_sounds/default_48000.wav +0 -0
  506. psychopy/tests/data/test_sounds/default_8000.wav +0 -0
  507. psychopy/tests/data/test_sounds/default_96000.wav +0 -0
  508. psychopy/tests/test_alerts/test_alerttools.py +2 -1
  509. psychopy/tests/test_app/test_command_line.py +65 -0
  510. psychopy/tests/test_data/test_TrialHandler2.py +18 -7
  511. psychopy/tests/test_demos/test_builder_demos.py +1 -1
  512. psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +5238 -4188
  513. psychopy/tests/test_experiment/needs_wx/test_components.py +1 -1
  514. psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
  515. psychopy/tests/test_experiment/test_components/test_all_components.py +1 -1
  516. psychopy/tests/test_experiment/test_components/test_base_components.py +26 -17
  517. psychopy/tests/test_experiment/test_loops.py +12 -4
  518. psychopy/tests/test_experiment/test_params.py +17 -4
  519. psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +2 -2
  520. psychopy/tests/test_hardware/test_photodiode.py +66 -0
  521. psychopy/tests/test_liaison/test_Liaison.py +4 -4
  522. psychopy/tests/test_misc/test_clock.py +2 -0
  523. psychopy/tests/test_misc/test_color.py +2 -0
  524. psychopy/tests/test_misc/test_event.py +1 -0
  525. psychopy/tests/test_plugins/__init__.py +0 -0
  526. psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
  527. psychopy/tests/test_sound/test_sound.py +111 -40
  528. psychopy/tests/test_tools/test_colorspacetools.py +24 -23
  529. psychopy/tests/test_tools/test_mathtools.py +9 -9
  530. psychopy/tests/test_tools/test_viewtools.py +101 -0
  531. psychopy/tests/test_validators/__init__.py +0 -0
  532. psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
  533. psychopy/tests/test_visual/test_all_stimuli.py +2 -2
  534. psychopy/tests/test_visual/test_basevisual.py +37 -7
  535. psychopy/tests/test_visual/test_button.py +2 -2
  536. psychopy/tests/test_visual/test_circle.py +10 -2
  537. psychopy/tests/test_visual/test_dots.py +1 -1
  538. psychopy/tests/test_visual/test_form.py +13 -13
  539. psychopy/tests/test_visual/test_gamma.py +3 -3
  540. psychopy/tests/test_visual/test_image.py +2 -2
  541. psychopy/tests/test_visual/test_progress.py +2 -2
  542. psychopy/tests/test_visual/test_roi.py +8 -2
  543. psychopy/tests/test_visual/test_shape.py +2 -2
  544. psychopy/tests/test_visual/test_slider.py +2 -2
  545. psychopy/tests/test_visual/test_target.py +2 -2
  546. psychopy/tests/test_visual/test_textbox.py +6 -8
  547. psychopy/tests/test_visual/test_winScalePos.py +6 -5
  548. psychopy/tests/test_visual/test_window.py +17 -0
  549. psychopy/tests/utils.py +51 -1
  550. psychopy/tools/__init__.py +1 -1
  551. psychopy/tools/arraytools.py +2 -2
  552. psychopy/tools/attributetools.py +52 -1
  553. psychopy/tools/audiotools.py +4 -1
  554. psychopy/tools/colorspacetools.py +6 -4
  555. psychopy/tools/coordinatetools.py +1 -1
  556. psychopy/tools/fileerrortools.py +21 -9
  557. psychopy/tools/filetools.py +2 -2
  558. psychopy/tools/fontmanager.py +47 -28
  559. psychopy/tools/gltools.py +2964 -558
  560. psychopy/tools/imagetools.py +1 -1
  561. psychopy/tools/mathtools.py +997 -127
  562. psychopy/tools/monitorunittools.py +7 -1
  563. psychopy/tools/movietools.py +1 -2
  564. psychopy/tools/pkgtools.py +157 -127
  565. psychopy/tools/plottools.py +1 -1
  566. psychopy/tools/rifttools.py +1 -1
  567. psychopy/tools/stereotools.py +1 -1
  568. psychopy/tools/stimulustools.py +172 -2
  569. psychopy/tools/stringtools.py +22 -2
  570. psychopy/tools/systemtools.py +1 -1
  571. psychopy/tools/typetools.py +1 -1
  572. psychopy/tools/unittools.py +1 -1
  573. psychopy/tools/versionchooser.py +3 -1
  574. psychopy/tools/viewtools.py +54 -70
  575. psychopy/tools/wizard.py +2 -2
  576. psychopy/validation/__init__.py +6 -0
  577. psychopy/validation/audio.py +74 -0
  578. psychopy/validation/visual.py +115 -0
  579. psychopy/visual/__init__.py +1 -4
  580. psychopy/visual/aperture.py +9 -6
  581. psychopy/visual/backends/__init__.py +1 -1
  582. psychopy/visual/backends/_base.py +1 -1
  583. psychopy/visual/backends/gamma.py +1 -1
  584. psychopy/visual/backends/glfwbackend.py +8 -12
  585. psychopy/visual/backends/pygamebackend.py +1 -1
  586. psychopy/visual/backends/pygletbackend.py +32 -11
  587. psychopy/visual/basevisual.py +93 -13
  588. psychopy/visual/brush.py +1 -1
  589. psychopy/visual/bufferimage.py +90 -10
  590. psychopy/visual/button.py +1 -1
  591. psychopy/visual/circle.py +12 -20
  592. psychopy/visual/custommouse.py +1 -1
  593. psychopy/visual/dot.py +80 -14
  594. psychopy/visual/elementarray.py +84 -10
  595. psychopy/visual/filters.py +1 -1
  596. psychopy/visual/form.py +43 -28
  597. psychopy/visual/grating.py +105 -25
  598. psychopy/visual/helpers.py +1 -1
  599. psychopy/visual/image.py +98 -20
  600. psychopy/visual/line.py +15 -25
  601. psychopy/visual/movie.py +1 -1
  602. psychopy/visual/movie2.py +4 -3
  603. psychopy/visual/movie3.py +4 -3
  604. psychopy/visual/movies/__init__.py +1 -1
  605. psychopy/visual/movies/frame.py +1 -1
  606. psychopy/visual/movies/metadata.py +1 -1
  607. psychopy/visual/movies/players/__init__.py +1 -1
  608. psychopy/visual/movies/players/_base.py +1 -1
  609. psychopy/visual/movies/players/ffpyplayer_player.py +2 -3
  610. psychopy/visual/nnlvs.py +9 -6
  611. psychopy/visual/noise.py +4 -16
  612. psychopy/visual/patch.py +4 -3
  613. psychopy/visual/pie.py +3 -14
  614. psychopy/visual/polygon.py +21 -28
  615. psychopy/visual/radial.py +4 -18
  616. psychopy/visual/ratingscale.py +4 -3
  617. psychopy/visual/rect.py +16 -25
  618. psychopy/visual/rift.py +8 -2
  619. psychopy/visual/secondorder.py +4 -16
  620. psychopy/visual/shaders.py +620 -286
  621. psychopy/visual/shape.py +281 -90
  622. psychopy/visual/simpleimage.py +1 -1
  623. psychopy/visual/slider.py +78 -25
  624. psychopy/visual/stim3d.py +5 -608
  625. psychopy/visual/text.py +13 -3
  626. psychopy/visual/textbox2/textbox2.py +188 -56
  627. psychopy/visual/vlcmoviestim.py +1 -1
  628. psychopy/visual/window.py +373 -200
  629. psychopy/web.py +1 -1
  630. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/METADATA +9 -9
  631. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/RECORD +644 -621
  632. psychopy/.DS_Store +0 -0
  633. psychopy/__init__.py.orig +0 -65
  634. psychopy/app/.DS_Store +0 -0
  635. psychopy/app/Resources/.DS_Store +0 -0
  636. psychopy/app/Resources/classic/filecsv16.png +0 -0
  637. psychopy/app/Resources/classic/fileimage16.png +0 -0
  638. psychopy/app/Resources/classic/fileunknown16.png +0 -0
  639. psychopy/app/Resources/dark/filecsv16.png +0 -0
  640. psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
  641. psychopy/app/Resources/dark/fileimage16.png +0 -0
  642. psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
  643. psychopy/app/Resources/dark/fileunknown16.png +0 -0
  644. psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
  645. psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
  646. psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
  647. psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
  648. psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  649. psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
  650. psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
  651. psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
  652. psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
  653. psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
  654. psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
  655. psychopy/app/Resources/light/filecsv16.png +0 -0
  656. psychopy/app/Resources/light/filecsv16@2x.png +0 -0
  657. psychopy/app/Resources/light/fileimage16.png +0 -0
  658. psychopy/app/Resources/light/fileimage16@2x.png +0 -0
  659. psychopy/app/Resources/light/fileunknown16.png +0 -0
  660. psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
  661. psychopy/app/Resources/psychopySplash.png +0 -0
  662. psychopy/app/Resources/psychopySplash@2x.png +0 -0
  663. psychopy/app/builder/builder.py.orig +0 -3932
  664. psychopy/app/builder/dialogs/__init__.py.orig +0 -1679
  665. psychopy/app/builder/dialogs/paramCtrls.py.orig +0 -713
  666. psychopy/app/colorpicker/__init__.py.orig +0 -411
  667. psychopy/app/locale/ar_001/.DS_Store +0 -0
  668. psychopy/app/locale/ar_001/LC_MESSAGE/.DS_Store +0 -0
  669. psychopy/core.py.orig +0 -169
  670. psychopy/demos/builder/.DS_Store +0 -0
  671. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +0 -330
  672. psychopy/demos/builder/Experiments/.DS_Store +0 -0
  673. psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
  674. psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +0 -61
  675. psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +0 -91
  676. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
  677. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
  678. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
  679. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
  680. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
  681. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
  682. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
  683. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
  684. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
  685. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
  686. psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
  687. psychopy/demos/builder/Tools/.DS_Store +0 -0
  688. psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
  689. psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
  690. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +0 -38
  691. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +0 -3418
  692. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
  693. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +0 -2
  694. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +0 -15
  695. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
  696. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +0 -562
  697. psychopy/demos/coder/.DS_Store +0 -0
  698. psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
  699. psychopy/demos/coder/iohub/.iohpid +0 -1
  700. psychopy/demos/coder/iohub/eyetracking/.iohpid +0 -1
  701. psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
  702. psychopy/demos/coder/stimuli/.DS_Store +0 -0
  703. psychopy/experiment/_experiment.py.orig +0 -1032
  704. psychopy/experiment/components/.DS_Store +0 -0
  705. psychopy/experiment/components/_base.py.orig +0 -823
  706. psychopy/experiment/components/form/.DS_Store +0 -0
  707. psychopy/experiment/components/microphone/__init__.py.orig +0 -490
  708. psychopy/experiment/components/settings/__init__.py.orig +0 -1337
  709. psychopy/experiment/components/textbox/__init__.py.orig +0 -310
  710. psychopy/experiment/components/webcam/.DS_Store +0 -0
  711. psychopy/experiment/components/webcam/light/.DS_Store +0 -0
  712. psychopy/experiment/loops.py.orig +0 -829
  713. psychopy/experiment/params.py.orig +0 -408
  714. psychopy/experiment/routine.py.orig +0 -503
  715. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
  716. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
  717. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
  718. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
  719. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
  720. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
  721. psychopy/hardware/.DS_Store +0 -0
  722. psychopy/hardware/brainproducts.py.orig +0 -680
  723. psychopy/hardware/iolab.py.orig +0 -238
  724. psychopy/iohub/datastore/__init__.py.orig +0 -443
  725. psychopy/iohub/datastore/util.py.orig +0 -692
  726. psychopy/iohub/devices/mouse/darwin.py.orig +0 -427
  727. psychopy/iohub/devices/mouse/linux2.py.orig +0 -198
  728. psychopy/preferences/.DS_Store +0 -0
  729. psychopy/projects/pavlovia.py.orig +0 -1295
  730. psychopy/tests/.DS_Store +0 -0
  731. psychopy/tests/data/.DS_Store +0 -0
  732. psychopy/tests/data/TestCircle_fill_local.png +0 -0
  733. psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
  734. psychopy/tests/data/aperture1_norm_local.png +0 -0
  735. psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
  736. psychopy/tests/data/beatandrcos_height_local.png +0 -0
  737. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  738. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  739. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  740. psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
  741. psychopy/tests/data/blend_add_height_local.png +0 -0
  742. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  743. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  744. psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
  745. psychopy/tests/data/blend_add_norm_local.png +0 -0
  746. psychopy/tests/data/blend_add_stencil_local.png +0 -0
  747. psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
  748. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  749. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  750. psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
  751. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  752. psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
  753. psychopy/tests/data/circleHex_height_local.png +0 -0
  754. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  755. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  756. psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
  757. psychopy/tests/data/circleHex_norm_local.png +0 -0
  758. psychopy/tests/data/circleHex_stencil_local.png +0 -0
  759. psychopy/tests/data/color_comparison_local.png +0 -0
  760. psychopy/tests/data/correctScript/.DS_Store +0 -0
  761. psychopy/tests/data/dots_height_local.png +0 -0
  762. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  763. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  764. psychopy/tests/data/dots_normNoShade_local.png +0 -0
  765. psychopy/tests/data/dots_norm_local.png +0 -0
  766. psychopy/tests/data/dots_stencil_local.png +0 -0
  767. psychopy/tests/data/elarray1_height_local.png +0 -0
  768. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  769. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  770. psychopy/tests/data/elarray1_norm_local.png +0 -0
  771. psychopy/tests/data/elarray1_stencil_local.png +0 -0
  772. psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
  773. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  774. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  775. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  776. psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
  777. psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
  778. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  779. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  780. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  781. psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
  782. psychopy/tests/data/gabor1_height_local.png +0 -0
  783. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  784. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  785. psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
  786. psychopy/tests/data/gabor1_norm_local.png +0 -0
  787. psychopy/tests/data/gabor1_stencil_local.png +0 -0
  788. psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
  789. psychopy/tests/data/imageAndGauss_height_local.png +0 -0
  790. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  791. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  792. psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
  793. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  794. psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
  795. psychopy/tests/data/movFrame1_stencil_local.png +0 -0
  796. psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
  797. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  798. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  799. psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
  800. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  801. psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
  802. psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
  803. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  804. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  805. psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
  806. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  807. psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
  808. psychopy/tests/data/numpyImage_height_local.png +0 -0
  809. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  810. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  811. psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
  812. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  813. psychopy/tests/data/numpyImage_stencil_local.png +0 -0
  814. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  815. psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
  816. psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
  817. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  818. psychopy/tests/data/shape2_1_stencil_local.png +0 -0
  819. psychopy/tests/data/text1_height_local.png +0 -0
  820. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  821. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  822. psychopy/tests/data/text1_norm_local.png +0 -0
  823. psychopy/tests/data/text1_stencil_local.png +0 -0
  824. psychopy/tests/data/wedge1_height_local.png +0 -0
  825. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  826. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  827. psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
  828. psychopy/tests/data/wedge1_norm_local.png +0 -0
  829. psychopy/tests/data/wedge1_stencil_local.png +0 -0
  830. psychopy/tests/test_app/.DS_Store +0 -0
  831. psychopy/tests/test_app/test_builder/.DS_Store +0 -0
  832. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +0 -177
  833. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
  834. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
  835. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +0 -168
  836. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
  837. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
  838. psychopy/tests/test_data/.DS_Store +0 -0
  839. psychopy/tests/test_hardware/test_CRS_BitsSharp.py +0 -67
  840. psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +0 -68
  841. psychopy/tests/test_hardware/test_CRS_bitsShaders.py +0 -110
  842. psychopy/tests/test_visual/test_image.py.orig +0 -219
  843. psychopy/visual/basevisual.py.orig +0 -1723
  844. psychopy/visual/form.py.orig +0 -1181
  845. psychopy/visual/text.py.orig +0 -752
  846. psychopy/visual/textbox2/textbox2.py.orig +0 -1315
  847. psychopy/visual/windowwarp.py.orig +0 -463
  848. /psychopy/{app/cortex.log → alerts/alertsCatalogue/3600.yaml} +0 -0
  849. /psychopy/{app/Resources → assets}/fonts/Arvo-Bold.ttf +0 -0
  850. /psychopy/{app/Resources → assets}/fonts/Arvo-BoldItalic.ttf +0 -0
  851. /psychopy/{app/Resources → assets}/fonts/Arvo-Italic.ttf +0 -0
  852. /psychopy/{app/Resources → assets}/fonts/Arvo-Regular.ttf +0 -0
  853. /psychopy/{app/Resources → assets}/fonts/DejaVuSerif.ttf +0 -0
  854. /psychopy/{app/Resources → assets}/fonts/IndieFlower-Regular.ttf +0 -0
  855. /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
  856. /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
  857. /psychopy/demos/builder/Experiments/{GoNoGo → goNoGo}/readme.md +0 -0
  858. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/WHEEL +0 -0
  859. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/entry_points.txt +0 -0
  860. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -4,7 +4,7 @@
4
4
  """
5
5
  Defines the behavior of Psychopy's Builder view window
6
6
  Part of the PsychoPy library
7
- Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
7
+ Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
8
8
  Distributed under the terms of the GNU General Public License (GPL).
9
9
  """
10
10
  import collections
@@ -76,9 +76,7 @@ from psychopy.scripts.psyexpCompile import generateScript
76
76
 
77
77
  # Components which are always hidden
78
78
  alwaysHidden = [
79
- 'SettingsComponent', 'RoutineSettingsComponent', 'UnknownComponent', 'UnknownRoutine',
80
- 'UnknownStandaloneRoutine', 'UnknownPluginComponent', 'BaseComponent', 'BaseStandaloneRoutine',
81
- 'BaseValidatorRoutine'
79
+ 'BaseComponent', 'BaseStandaloneRoutine', 'BaseValidatorRoutine'
82
80
  ]
83
81
 
84
82
 
@@ -314,7 +312,7 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
314
312
  _translate("Save &as...\t%s") % keys['saveAs'],
315
313
  _translate("Save current experiment file as..."))
316
314
  # export html
317
- self.menuIDs.ID_EXPORT_HTML = wx.NewId()
315
+ self.menuIDs.ID_EXPORT_HTML = wx.NewIdRef(count=1)
318
316
  menu.Append(
319
317
  self.menuIDs.ID_EXPORT_HTML,
320
318
  _translate("Export HTML...\t%s") % keys['exportHTML'],
@@ -322,10 +320,10 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
322
320
  )
323
321
  self.Bind(wx.EVT_MENU, self.fileExport, id=self.menuIDs.ID_EXPORT_HTML)
324
322
  # reveal folder
325
- self.menuIDs.ID_REVEAL = wx.NewId()
323
+ self.menuIDs.ID_REVEAL = wx.NewIdRef(count=1)
326
324
  menu.Append(
327
325
  self.menuIDs.ID_REVEAL,
328
- _translate("Reveal in file explorer..."),
326
+ _translate("Reveal in file explorer...\t%s") % keys['revealFolder'],
329
327
  _translate("Open the folder containing this experiment in your system's file explorer")
330
328
  )
331
329
  self.Bind(wx.EVT_MENU, self.fileReveal, id=self.menuIDs.ID_REVEAL)
@@ -348,7 +346,7 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
348
346
  wx.ID_ANY, _translate("Reset preferences...")
349
347
  )
350
348
  self.Bind(wx.EVT_MENU, self.resetPrefs, item)
351
- # item = menu.Append(wx.NewId(), "Plug&ins")
349
+ # item = menu.Append(wx.NewIdRef(count=1), "Plug&ins")
352
350
  # self.Bind(wx.EVT_MENU, self.pluginManager, item)
353
351
  self.fileMenu.AppendSeparator()
354
352
  self.fileMenu.Append(wx.ID_EXIT,
@@ -373,6 +371,13 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
373
371
  menu.Append(wx.ID_PASTE, _translate("&Paste\t%s") % keys['paste'])
374
372
  self.Bind(wx.EVT_MENU, self.paste, id=wx.ID_PASTE)
375
373
 
374
+ item = menu.Append(
375
+ wx.ID_ANY,
376
+ _translate("&Find in experiment...\t%s") % keys['builderFind'],
377
+ _translate("Search the whole experiment for a specific term")
378
+ )
379
+ self.Bind(wx.EVT_MENU, self.onFindInExperiment, item)
380
+
376
381
  # ---_view---#000000#FFFFFF-------------------------------------------
377
382
  self.viewMenu = wx.Menu()
378
383
  menuBar.Append(self.viewMenu, _translate('&View'))
@@ -465,6 +470,13 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
465
470
  self.expMenu = wx.Menu()
466
471
  menuBar.Append(self.expMenu, _translate('E&xperiment'))
467
472
  menu = self.expMenu
473
+
474
+ item = menu.Append(wx.ID_ANY,
475
+ _translate("Experiment &Settings\t%s") % keys['expSettings'],
476
+ _translate("Edit experiment settings"))
477
+ self.Bind(wx.EVT_MENU, self.setExperimentSettings, item)
478
+ menu.AppendSeparator()
479
+
468
480
  item = menu.Append(wx.ID_ANY,
469
481
  _translate("&New Routine\t%s") % keys['newRoutine'],
470
482
  _translate("Create a new routine (e.g. the trial "
@@ -511,11 +523,6 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
511
523
  self.Bind(wx.EVT_MENU, self.flowPanel.canvas.insertLoop, item)
512
524
  menu.AppendSeparator()
513
525
 
514
- item = menu.Append(wx.ID_ANY,
515
- _translate("&Find in experiment...\t%s") % keys['builderFind'],
516
- _translate("Search the whole experiment for a specific term"))
517
- self.Bind(wx.EVT_MENU, self.onFindInExperiment, item)
518
-
519
526
  item = menu.Append(wx.ID_ANY,
520
527
  _translate("README..."),
521
528
  _translate("Add or edit the text shown when your experiment is opened"))
@@ -1030,10 +1037,8 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
1030
1037
  ok = self.checkSave()
1031
1038
  if not ok:
1032
1039
  return False # user cancelled
1033
- if self.filename is None:
1034
- frameData = self.appData['defaultFrame']
1035
- else:
1036
- frameData = dict(self.appData['defaultFrame'])
1040
+ frameData = self.appData['defaultFrame']
1041
+ if self.fileExists:
1037
1042
  self.appData['prevFiles'].append(self.filename)
1038
1043
 
1039
1044
  # get size and window layout info
@@ -1065,7 +1070,11 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
1065
1070
  self.appData['fileHistory'] = copy.copy(tmp[-fhMax:])
1066
1071
 
1067
1072
  # assign the data to this filename
1068
- self.appData['frames'][str(self.filename)] = frameData
1073
+ if (
1074
+ str(self.filename) not in self.appData['frames']
1075
+ and str(self.filename) not in self.appData
1076
+ ):
1077
+ self.appData['frames'][str(self.filename)] = frameData
1069
1078
  # save the display data only for those frames in the history:
1070
1079
  tmp2 = {}
1071
1080
  for f in self.appData['frames']:
@@ -1564,8 +1573,8 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
1564
1573
  def openPluginManager(self, evt=None):
1565
1574
  dlg = psychopy.app.plugin_manager.dialog.EnvironmentManagerDlg(self)
1566
1575
  dlg.Show()
1567
- # Do post-close checks
1568
- dlg.onClose()
1576
+
1577
+ return dlg
1569
1578
 
1570
1579
  def onPavloviaCreate(self, evt=None):
1571
1580
  if Path(self.filename).is_file():
@@ -2496,6 +2505,8 @@ class RoutineCanvas(wx.ScrolledWindow, handlers.ThemeMixin):
2496
2505
  maxDur, useMax = self.routine.settings.getDuration()
2497
2506
  overspill = 0
2498
2507
  if useMax:
2508
+ if maxDur is None:
2509
+ maxDur = duration
2499
2510
  overspill = max(duration - maxDur, 0)
2500
2511
  duration = min(maxDur, duration)
2501
2512
  # If there's a fixed end time and no start time, start 20px before 0
@@ -3247,6 +3258,9 @@ class ComponentsPanel(scrolledpanel.ScrolledPanel, handlers.ThemeMixin):
3247
3258
  # Check whether button is hidden by prefs
3248
3259
  if name in prefs.builder['hiddenComponents'] + alwaysHidden:
3249
3260
  shown = False
3261
+ # check whether comp/rt indicates itsef as hidden
3262
+ if emt.hidden:
3263
+ shown = False
3250
3264
  # Check whether button refers to a future comp/rt
3251
3265
  if hasattr(emt, "version"):
3252
3266
  ver = parseVersionSafely(emt.version)
@@ -4215,7 +4229,7 @@ class FlowCanvas(wx.ScrolledWindow, handlers.ThemeMixin):
4215
4229
 
4216
4230
  def drawLineStart(self, dc, pos):
4217
4231
  # draw bar at start of timeline; circle looked bad, offset vertically
4218
- tmpId = wx.NewId()
4232
+ tmpId = wx.NewIdRef(count=1)
4219
4233
  dc.SetId(tmpId)
4220
4234
  ptSize = (9, 9, 12)[self.appData['flowSize']]
4221
4235
  thic = (1, 1, 2)[self.appData['flowSize']]
@@ -4229,7 +4243,7 @@ class FlowCanvas(wx.ScrolledWindow, handlers.ThemeMixin):
4229
4243
 
4230
4244
  def drawLineEnd(self, dc, pos):
4231
4245
  # draws arrow at end of timeline
4232
- tmpId = wx.NewId()
4246
+ tmpId = wx.NewIdRef(count=1)
4233
4247
  dc.SetId(tmpId)
4234
4248
  dc.SetBrush(wx.Brush(colors.app['fl_flowline_bg']))
4235
4249
  dc.SetPen(wx.Pen(colors.app['fl_flowline_bg']))
@@ -4512,6 +4526,12 @@ class BuilderRibbon(ribbon.FrameRibbon):
4512
4526
  tooltip=_translate("Redo last action"),
4513
4527
  callback=parent.redo
4514
4528
  )
4529
+ # find
4530
+ self.addButton(
4531
+ section="edit", name="find", label=_translate("Find"), icon="find",
4532
+ tooltip=_translate("Search the whole experiment for a specific term"),
4533
+ callback=parent.onFindInExperiment
4534
+ )
4515
4535
 
4516
4536
  self.addSeparator()
4517
4537
 
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Dialog classes for the Builder, including ParamCtrls
@@ -28,9 +28,10 @@ from .dlgsConditions import DlgConditions
28
28
  from .dlgsCode import DlgCodeComponentProperties, CodeBox
29
29
  from .findDlg import BuilderFindDlg
30
30
  from . import paramCtrls
31
- from psychopy import data, logging, exceptions
31
+ from psychopy.app.utils import HyperLinkCtrl
32
+ from psychopy import data, logging, exceptions, plugins
32
33
  from psychopy.localization import _translate
33
- from psychopy.tools import versionchooser as vc
34
+ from psychopy.tools import versionchooser as vc, pkgtools
34
35
  from psychopy.alerts import alert
35
36
  from ...colorpicker import PsychoColorPicker
36
37
  from pathlib import Path
@@ -194,6 +195,13 @@ class ParamCtrls():
194
195
  fieldName=fieldName,
195
196
  size=wx.Size(int(self.valueWidth), 24))
196
197
  self.valueCtrl.allowedVals = param.allowedVals
198
+ elif param.inputType == 'font':
199
+ self.valueCtrl = paramCtrls.FontCtrl(
200
+ parent,
201
+ val=str(param.val),
202
+ valType=param.valType,
203
+ fieldName=fieldName,
204
+ size=wx.Size(int(self.valueWidth), 24))
197
205
  elif param.inputType == 'survey':
198
206
  self.valueCtrl = paramCtrls.SurveyCtrl(
199
207
  parent,
@@ -649,6 +657,9 @@ class ParamNotebook(wx.Notebook, handlers.ThemeMixin):
649
657
  "false": "Disable", # permitted: hide, show, enable, disable
650
658
  }"""
651
659
  isChanged = False
660
+ # This list will be used to delay the populate actions on the
661
+ # dependent params
662
+ populateCtrls = []
652
663
  for thisDep in self.parent.element.depends:
653
664
  if not (
654
665
  thisDep['param'] in list(self.ctrls) + ['start', 'stop']
@@ -683,9 +694,10 @@ class ParamNotebook(wx.Notebook, handlers.ThemeMixin):
683
694
  # only repopulate if dependency ctrl has changed
684
695
  dependencyParam = self.parent.element.params[thisDep['dependsOn']]
685
696
  if dependencyParam.val != dependencyCtrls.getValue():
686
- dependencyParam.val = dependencyCtrls.getValue()
687
- if hasattr(dependentCtrls.valueCtrl, "populate"):
688
- dependentCtrls.valueCtrl.populate()
697
+ # Delay the populate action
698
+ populateCtrls.append(
699
+ [dependencyParam, dependencyCtrls, dependentCtrls]
700
+ )
689
701
  else:
690
702
  # if action is "enable" then do ctrl.Enable() etc
691
703
  for ctrlName in ['valueCtrl', 'nameCtrl', 'updatesCtrl']:
@@ -694,6 +706,11 @@ class ParamNotebook(wx.Notebook, handlers.ThemeMixin):
694
706
  evalStr = ("dependentCtrls.{}.{}()"
695
707
  .format(ctrlName, action.title()))
696
708
  eval(evalStr)
709
+ # Execute the populate actions
710
+ for elem in populateCtrls:
711
+ elem[0].val = elem[1].getValue()
712
+ if hasattr(elem[2].valueCtrl, "populate"):
713
+ elem[2].valueCtrl.populate()
697
714
  # Update sizer
698
715
  if isChanged:
699
716
  self.sizer.SetEmptyCellSize((0, 0))
@@ -879,6 +896,7 @@ class _BaseParamsDlg(wx.Dialog):
879
896
  self.showAdvanced = showAdvanced
880
897
  self.order = element.order
881
898
  self.depends = element.depends
899
+ self.plugin = element.plugin
882
900
  self.data = []
883
901
  # max( len(str(self.params[x])) for x in keys )
884
902
  self.maxFieldLength = 10
@@ -907,12 +925,26 @@ class _BaseParamsDlg(wx.Dialog):
907
925
 
908
926
  self.mainSizer.Add(self.ctrls, # ctrls is the notebook of params
909
927
  proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
928
+ # if element came from a plugin that's not installed, add button to open plugins dlg
929
+ self.pluginBtn = HyperLinkCtrl(
930
+ self, label=_translate("Requires plugin {}, click here to install.").format(self.plugin)
931
+ )
932
+ self.pluginBtn.Bind(wx.EVT_BUTTON, self.jumpToPlugin)
933
+ self.mainSizer.Add(self.pluginBtn, border=6, flag=wx.CENTER | wx.ALL)
934
+ # show/hide button according to whether the plugin is installed or not
935
+ self.pluginBtn.Show(
936
+ self.plugin not in (None, "None", "") and self.plugin not in plugins.listPlugins()
937
+ )
910
938
 
911
939
  self.SetSizerAndFit(self.mainSizer)
912
940
 
913
941
  def getParams(self):
914
942
  return self.ctrls.getParams()
915
943
 
944
+ def jumpToPlugin(self, evt):
945
+ dlg = self.frame.openPluginManager()
946
+ dlg.jumpToPlugin(self.plugin)
947
+
916
948
  def openMonitorCenter(self, event):
917
949
  self.app.openMonitorCenter(event)
918
950
  self.paramCtrls['Monitor'].valueCtrl.SetFocus()
@@ -962,8 +994,7 @@ class _BaseParamsDlg(wx.Dialog):
962
994
  border=3)
963
995
  self.OKbtn = wx.Button(self, wx.ID_OK, _translate(" OK "))
964
996
  # intercept OK button if a loop dialog, in case file name was edited:
965
- if type(self) == DlgLoopProperties:
966
- self.OKbtn.Bind(wx.EVT_BUTTON, self.onOK)
997
+ self.OKbtn.Bind(wx.EVT_BUTTON, self.onOK)
967
998
  self.OKbtn.SetDefault()
968
999
  CANCEL = wx.Button(self, wx.ID_CANCEL, _translate(" Cancel "))
969
1000
 
@@ -1025,9 +1056,11 @@ class _BaseParamsDlg(wx.Dialog):
1025
1056
  def onOK(self, event=None):
1026
1057
  """Handler for OK button which should validate dialog contents.
1027
1058
  """
1028
- valid = self.Validate()
1029
- if not valid:
1030
- return
1059
+ # run "on ok" validation for each ctrl
1060
+ for ctrl in self.paramCtrls.values():
1061
+ if hasattr(ctrl, "valueCtrl") and hasattr(ctrl.valueCtrl, "onOK"):
1062
+ ctrl.valueCtrl.onOK()
1063
+
1031
1064
  event.Skip()
1032
1065
 
1033
1066
  def onTextEventCode(self, event=None):
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Dialog classes for the Builder Code component
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Conditions-file preview and mini-editor for the Builder
@@ -1,8 +1,10 @@
1
1
  import wx
2
2
  from psychopy import experiment
3
+ from psychopy.experiment.components.routineSettings import RoutineSettingsComponent
3
4
  from psychopy.app import utils
4
5
  from psychopy.app.themes import icons
5
6
  from psychopy.localization import _translate
7
+ from psychopy.tools import stringtools
6
8
 
7
9
 
8
10
  class BuilderFindDlg(wx.Dialog):
@@ -25,10 +27,34 @@ class BuilderFindDlg(wx.Dialog):
25
27
  self.sizer = wx.BoxSizer(wx.VERTICAL)
26
28
  self.border.Add(self.sizer, border=12, proportion=1, flag=wx.EXPAND | wx.ALL)
27
29
 
30
+ # create search box and controls
31
+ self.searchPnl = wx.Panel(self)
32
+ self.searchPnl.sizer = wx.BoxSizer(wx.HORIZONTAL)
33
+ self.searchPnl.SetSizer(self.searchPnl.sizer)
34
+ self.sizer.Add(self.searchPnl, flag=wx.EXPAND | wx.ALL, border=6)
35
+
28
36
  # create search box
29
- self.termCtrl = wx.SearchCtrl(self)
30
- self.termCtrl.Bind(wx.EVT_SEARCH, self.onSearch)
31
- self.sizer.Add(self.termCtrl, border=6, flag=wx.EXPAND | wx.ALL)
37
+ self.termCtrl = wx.SearchCtrl(self.searchPnl)
38
+ self.termCtrl.Bind(wx.EVT_TEXT, self.onSearchTyping)
39
+ self.searchPnl.sizer.Add(self.termCtrl, proportion=1, flag=wx.EXPAND, border=6)
40
+
41
+ # add toggle for case sensitivity
42
+ self.caseSensitiveToggle = wx.ToggleButton(self.searchPnl, style=wx.BU_EXACTFIT)
43
+ self.caseSensitiveToggle.SetBitmap(
44
+ icons.ButtonIcon("case", size=16, theme="light").bitmap
45
+ )
46
+ self.caseSensitiveToggle.SetToolTip(_translate("Match case?"))
47
+ self.caseSensitiveToggle.Bind(wx.EVT_TOGGLEBUTTON, self.onSearchTyping)
48
+ self.searchPnl.sizer.Add(self.caseSensitiveToggle, flag=wx.EXPAND | wx.LEFT, border=6)
49
+
50
+ # add toggle for regex
51
+ self.regexToggle = wx.ToggleButton(self.searchPnl, style=wx.BU_EXACTFIT)
52
+ self.regexToggle.SetBitmap(
53
+ icons.ButtonIcon("regex", size=16, theme="light").bitmap
54
+ )
55
+ self.regexToggle.SetToolTip(_translate("Match regex?"))
56
+ self.regexToggle.Bind(wx.EVT_TOGGLEBUTTON, self.onSearchTyping)
57
+ self.searchPnl.sizer.Add(self.regexToggle, flag=wx.EXPAND | wx.LEFT, border=6)
32
58
 
33
59
  # create results box
34
60
  self.resultsCtrl = utils.ListCtrl(self, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
@@ -41,11 +67,18 @@ class BuilderFindDlg(wx.Dialog):
41
67
  # setup component icons
42
68
  self.imageList = wx.ImageList(16, 16)
43
69
  self.imageMap = {}
70
+ # icon for each Component/Routine
44
71
  for cls in experiment.getAllElements().values():
45
72
  i = self.imageList.Add(
46
73
  icons.ComponentIcon(cls, theme="light", size=16).bitmap
47
74
  )
48
75
  self.imageMap[cls] = i
76
+ # icon for loop
77
+ i = self.imageList.Add(
78
+ icons.ButtonIcon("loop", theme="light", size=16).bitmap
79
+ )
80
+ self.imageMap[experiment.loops.LoopInitiator] = i
81
+ # set icons
49
82
  self.resultsCtrl.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL)
50
83
 
51
84
  # add buttons
@@ -65,49 +98,62 @@ class BuilderFindDlg(wx.Dialog):
65
98
 
66
99
  def resetListCtrl(self):
67
100
  self.resultsCtrl.ClearAll()
68
- self.resultsCtrl.AppendColumn(_translate("Component"), width=120)
101
+ self.resultsCtrl.AppendColumn(_translate("Location"), width=120)
69
102
  self.resultsCtrl.AppendColumn(_translate("Parameter"), width=120)
70
103
  self.resultsCtrl.AppendColumn(_translate("Value"), width=-1)
71
104
  self.resultsCtrl.resizeLastColumn(minWidth=120)
72
105
  self.selectedResult = None
73
106
 
74
- def onSearch(self, evt):
75
- # get term to search
76
- term = evt.GetString()
107
+ def onSearchTyping(self, evt):
108
+ term = self.termCtrl.GetValue()
109
+ caseSensitive = self.caseSensitiveToggle.GetValue()
110
+ regex = self.regexToggle.GetValue()
111
+
77
112
  if term:
78
113
  # get locations of term in experiment
79
- self.results = getParamLocations(self.exp, term=term)
114
+ self.results = getParamLocations(self.exp, term=term, caseSensitive=caseSensitive, regex=regex)
80
115
  else:
81
116
  # return nothing for blank string
82
117
  self.results = []
118
+
83
119
  # clear old output
84
120
  self.resetListCtrl()
121
+
85
122
  # show new output
86
123
  for result in self.results:
87
124
  # unpack result
88
- rt, comp, paramName, param = result
125
+ parent, comp, paramName, param = result
89
126
  # sanitize val for display
90
127
  val = str(param.val)
91
128
  if "\n" in val:
92
129
  # if multiline, show first line with match
93
130
  for line in val.split("\n"):
94
- if self.termCtrl.GetValue() in line:
131
+ if compareStrings(line, term, caseSensitive, regex):
95
132
  val = line
96
133
  break
134
+ # construct location string
135
+ if parent is None:
136
+ location = comp.name
137
+ else:
138
+ location = f"{comp.name} ({parent.name})"
97
139
  # construct entry
98
- entry = [comp.name, param.label, val]
140
+ entry = [location, param.label, val]
99
141
  # add entry
100
142
  self.resultsCtrl.Append(entry)
101
143
  # set image for comp
144
+ fallbackImg = icons.ButtonIcon("experiment", theme="light", size=16).bitmap
102
145
  self.resultsCtrl.SetItemImage(
103
146
  item=self.resultsCtrl.GetItemCount()-1,
104
- image=self.imageMap[type(comp)]
147
+ image=self.imageMap.get(type(comp), fallbackImg)
105
148
  )
149
+
106
150
  # size
107
151
  self.resultsCtrl.Layout()
108
152
  # disable Go button until item selected
109
153
  self.okBtn.Disable()
110
154
 
155
+ evt.Skip()
156
+
111
157
  def onSelectResult(self, evt):
112
158
  if evt.GetEventType() == wx.EVT_LIST_ITEM_SELECTED.typeId:
113
159
  # if item is selected, store its info
@@ -127,7 +173,7 @@ class BuilderFindDlg(wx.Dialog):
127
173
  if self.selectedResult is None:
128
174
  return
129
175
  # do usual OK button stuff
130
- self.Close()
176
+ # self.Close()
131
177
  # unpack
132
178
  rt, comp, paramName, param = self.selectedResult
133
179
  # navigate to routine
@@ -137,17 +183,39 @@ class BuilderFindDlg(wx.Dialog):
137
183
  if isinstance(comp, experiment.components.BaseComponent):
138
184
  # if we have a component, open its dialog and navigate to categ page
139
185
  if hasattr(comp, 'type') and comp.type.lower() == 'code':
140
- openToPage = paramName
186
+ # For code components, we need to find the index of the page
187
+ openToPage = list(comp.params.keys()).index(paramName)
141
188
  else:
142
189
  openToPage = param.categ
143
190
  page.editComponentProperties(component=comp, openToPage=openToPage)
144
- else:
191
+ elif isinstance(comp, experiment.routines.BaseStandaloneRoutine):
145
192
  # if we're in a standalone routine, just navigate to categ page
146
193
  i = page.ctrls.getCategoryIndex(param.categ)
147
194
  page.ctrls.ChangeSelection(i)
195
+ elif isinstance(comp, experiment.loops.LoopInitiator):
196
+ # if we're in a loop, open the loop dialog
197
+ self.frame.flowPanel.canvas.editLoopProperties(loop=comp.loop)
198
+
148
199
 
200
+ def compareStrings(text, term, caseSensitive, regex):
201
+ # lowercase everything if doing a non-case-sensitive check
202
+ if not caseSensitive:
203
+ term = term.lower()
204
+ text = text.lower()
205
+ # convert to regex object if using regex
206
+ if regex:
207
+ # if term isn't valid regex, assume no match
208
+ try:
209
+ stringtools.re.compile(term)
210
+ except stringtools.re.error:
211
+ return False
212
+ # convert to a regex searchable
213
+ text = stringtools.RegexSearchable(text)
214
+
215
+ return term in text
149
216
 
150
- def getParamLocations(exp, term):
217
+
218
+ def getParamLocations(exp, term, caseSensitive=False, regex=False):
151
219
  """
152
220
  Get locations of params containing the given term.
153
221
 
@@ -162,6 +230,7 @@ def getParamLocations(exp, term):
162
230
  List of tuples, with each tuple functioning as a path to the found
163
231
  param
164
232
  """
233
+
165
234
  # array to store results in
166
235
  found = []
167
236
 
@@ -170,20 +239,37 @@ def getParamLocations(exp, term):
170
239
  if isinstance(rt, experiment.routines.BaseStandaloneRoutine):
171
240
  # find in standalone routine
172
241
  for paramName, param in rt.params.items():
173
- if term in str(param.val):
242
+ if compareStrings(str(param.val), term, caseSensitive, regex):
174
243
  # append path (routine -> param)
175
244
  found.append(
176
- (rt, rt, paramName, param)
245
+ (None, rt, paramName, param)
177
246
  )
178
247
  if isinstance(rt, experiment.routines.Routine):
179
248
  # find in regular routine
180
249
  for comp in rt:
181
250
  for paramName, param in comp.params.items():
182
- if term in str(param.val):
251
+ if compareStrings(str(param.val), term, caseSensitive, regex):
252
+ # treat RoutineSettings as synonymous with the Routine
253
+ if isinstance(comp, RoutineSettingsComponent):
254
+ parent = None
255
+ else:
256
+ parent = rt
183
257
  # append path (routine -> component -> param)
184
258
  found.append(
185
- (rt, comp, paramName, param)
259
+ (parent, comp, paramName, param)
186
260
  )
261
+ for obj in exp.flow:
262
+ # find in loop
263
+ if isinstance(obj, experiment.loops.LoopInitiator):
264
+ loop = obj.loop
265
+ for paramName, param in loop.params.items():
266
+ if compareStrings(str(param.val), term, caseSensitive, regex):
267
+ # append path (loop -> param)
268
+ found.append(
269
+ (None, obj, paramName, param)
270
+ )
187
271
 
188
272
  return found
189
273
 
274
+
275
+
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
  import ast
8
8
  import os
@@ -1180,3 +1180,44 @@ class DictCtrl(ListWidget, _ValidatorMixin, _HideMixin):
1180
1180
  Hide all items in the dict ctrl
1181
1181
  """
1182
1182
  self.Show(False)
1183
+
1184
+
1185
+ class FontCtrl(SingleLineCtrl):
1186
+ def onOK(self):
1187
+ # get a font manager
1188
+ from psychopy.tools.fontmanager import FontManager, MissingFontError
1189
+ fm = FontManager()
1190
+ # check whether the font is installed
1191
+ installed = fm.getFontsMatching(self.GetValue(), fallback=False)
1192
+ # if not installed, ask the user whether to download from Google Fonts
1193
+ if not installed:
1194
+ # create dialog
1195
+ dlg = wx.MessageDialog(
1196
+ self.GetTopLevelParent(),
1197
+ _translate(
1198
+ "Font {} is not installed, would you like to download it from Google Fonts?"
1199
+ ).format(self.GetValue()),
1200
+ style=wx.YES|wx.NO|wx.ICON_QUESTION
1201
+ )
1202
+ # download if yes
1203
+ if dlg.ShowModal() == wx.ID_YES:
1204
+ try:
1205
+ fm.addGoogleFont(self.GetValue().strip())
1206
+ except MissingFontError as err:
1207
+ dlg = wx.MessageDialog(
1208
+ self.GetTopLevelParent(),
1209
+ _translate(
1210
+ "Could not download font {} from Google Fonts, reason: {}"
1211
+ ).format(self.GetValue(), err),
1212
+ style=wx.OK|wx.ICON_ERROR
1213
+ )
1214
+ dlg.ShowModal()
1215
+ else:
1216
+ dlg = wx.MessageDialog(
1217
+ self.GetTopLevelParent(),
1218
+ _translate(
1219
+ "Font download successfully"
1220
+ ),
1221
+ style=wx.OK|wx.ICON_INFORMATION
1222
+ )
1223
+ dlg.ShowModal()
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Module containing validators for various parameters.
@@ -7,7 +7,7 @@
7
7
  """
8
8
 
9
9
  # Part of the PsychoPy library
10
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
10
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
11
11
  # Distributed under the terms of the GNU General Public License (GPL).
12
12
 
13
13
  import wx
@@ -79,13 +79,13 @@ class BaseCodeEditor(wx.stc.StyledTextCtrl, handlers.ThemeMixin):
79
79
 
80
80
  if not hasattr(self, "UndoID"):
81
81
  # Create a new ID for all items
82
- self.UndoID = wx.NewId()
83
- self.RedoID = wx.NewId()
84
- self.CutID = wx.NewId()
85
- self.CopyID = wx.NewId()
86
- self.PasteID = wx.NewId()
87
- self.DeleteID = wx.NewId()
88
- self.SelectAllID = wx.NewId()
82
+ self.UndoID = wx.NewIdRef(count=1)
83
+ self.RedoID = wx.NewIdRef(count=1)
84
+ self.CutID = wx.NewIdRef(count=1)
85
+ self.CopyID = wx.NewIdRef(count=1)
86
+ self.PasteID = wx.NewIdRef(count=1)
87
+ self.DeleteID = wx.NewIdRef(count=1)
88
+ self.SelectAllID = wx.NewIdRef(count=1)
89
89
 
90
90
  # Bind items to relevant method
91
91
  self.Bind(wx.EVT_MENU, self.onUndo, id=self.UndoID)