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.
- psychopy/CHANGELOG.txt +4 -4
- psychopy/GIT_SHA +1 -1
- psychopy/LICENSE.txt +1 -1
- psychopy/VERSION +1 -1
- psychopy/__init__.py +10 -7
- psychopy/alerts/__init__.py +1 -1
- psychopy/alerts/_alerts.py +53 -17
- psychopy/alerts/_errorHandler.py +3 -4
- psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
- psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +8 -1
- psychopy/alerts/alertsCatalogue/alertmsg.py +1 -1
- psychopy/alerts/alerttools.py +0 -16
- psychopy/app/Resources/betasplash.png +0 -0
- psychopy/app/Resources/betasplash@2x.png +0 -0
- psychopy/app/Resources/classic/case.png +0 -0
- psychopy/app/Resources/classic/case@2x.png +0 -0
- psychopy/app/Resources/classic/fileaudio.png +0 -0
- psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
- psychopy/app/Resources/classic/filecss.png +0 -0
- psychopy/app/Resources/classic/filecss@2x.png +0 -0
- psychopy/app/Resources/classic/filecsv.png +0 -0
- psychopy/app/Resources/classic/filecsv@2x.png +0 -0
- psychopy/app/Resources/classic/filedesign.png +0 -0
- psychopy/app/Resources/classic/filedesign@2x.png +0 -0
- psychopy/app/Resources/classic/filefont.png +0 -0
- psychopy/app/Resources/classic/filefont@2x.png +0 -0
- psychopy/app/Resources/classic/filegit.png +0 -0
- psychopy/app/Resources/classic/filegit@2x.png +0 -0
- psychopy/app/Resources/classic/filehtml.png +0 -0
- psychopy/app/Resources/classic/filehtml@2x.png +0 -0
- psychopy/app/Resources/classic/fileimage.png +0 -0
- psychopy/app/Resources/classic/fileimage@2x.png +0 -0
- psychopy/app/Resources/classic/fileinfo.png +0 -0
- psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
- psychopy/app/Resources/classic/filejs.png +0 -0
- psychopy/app/Resources/classic/filejs@2x.png +0 -0
- psychopy/app/Resources/classic/filejson.png +0 -0
- psychopy/app/Resources/classic/filejson@2x.png +0 -0
- psychopy/app/Resources/classic/filepkg.png +0 -0
- psychopy/app/Resources/classic/filepkg@2x.png +0 -0
- psychopy/app/Resources/classic/filepsyexp.png +0 -0
- psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/classic/filepy.png +0 -0
- psychopy/app/Resources/classic/filepy@2x.png +0 -0
- psychopy/app/Resources/classic/filetxt.png +0 -0
- psychopy/app/Resources/classic/filetxt@2x.png +0 -0
- psychopy/app/Resources/classic/fileunknown.png +0 -0
- psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
- psychopy/app/Resources/classic/filevideo.png +0 -0
- psychopy/app/Resources/classic/filevideo@2x.png +0 -0
- psychopy/app/Resources/classic/find.png +0 -0
- psychopy/app/Resources/classic/find@2x.png +0 -0
- psychopy/app/Resources/classic/loop.png +0 -0
- psychopy/app/Resources/classic/loop@2x.png +0 -0
- psychopy/app/Resources/classic/regex.png +0 -0
- psychopy/app/Resources/classic/regex@2x.png +0 -0
- psychopy/app/Resources/dark/case.png +0 -0
- psychopy/app/Resources/dark/case@2x.png +0 -0
- psychopy/app/Resources/dark/fileaudio.png +0 -0
- psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
- psychopy/app/Resources/dark/filecss.png +0 -0
- psychopy/app/Resources/dark/filecss@2x.png +0 -0
- psychopy/app/Resources/dark/filecsv.png +0 -0
- psychopy/app/Resources/dark/filecsv@2x.png +0 -0
- psychopy/app/Resources/dark/filedesign.png +0 -0
- psychopy/app/Resources/dark/filedesign@2x.png +0 -0
- psychopy/app/Resources/dark/filefont.png +0 -0
- psychopy/app/Resources/dark/filefont@2x.png +0 -0
- psychopy/app/Resources/dark/filegit.png +0 -0
- psychopy/app/Resources/dark/filegit@2x.png +0 -0
- psychopy/app/Resources/dark/filehtml.png +0 -0
- psychopy/app/Resources/dark/filehtml@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage.png +0 -0
- psychopy/app/Resources/dark/fileimage@2x.png +0 -0
- psychopy/app/Resources/dark/fileinfo.png +0 -0
- psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
- psychopy/app/Resources/dark/filejs.png +0 -0
- psychopy/app/Resources/dark/filejs@2x.png +0 -0
- psychopy/app/Resources/dark/filejson.png +0 -0
- psychopy/app/Resources/dark/filejson@2x.png +0 -0
- psychopy/app/Resources/dark/filepkg.png +0 -0
- psychopy/app/Resources/dark/filepkg@2x.png +0 -0
- psychopy/app/Resources/dark/filepsyexp.png +0 -0
- psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/dark/filepy.png +0 -0
- psychopy/app/Resources/dark/filepy@2x.png +0 -0
- psychopy/app/Resources/dark/filetxt.png +0 -0
- psychopy/app/Resources/dark/filetxt@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown.png +0 -0
- psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
- psychopy/app/Resources/dark/filevideo.png +0 -0
- psychopy/app/Resources/dark/filevideo@2x.png +0 -0
- psychopy/app/Resources/dark/find.png +0 -0
- psychopy/app/Resources/dark/find@2x.png +0 -0
- psychopy/app/Resources/dark/loop.png +0 -0
- psychopy/app/Resources/dark/loop@2x.png +0 -0
- psychopy/app/Resources/dark/regex.png +0 -0
- psychopy/app/Resources/dark/regex@2x.png +0 -0
- psychopy/app/Resources/light/case.png +0 -0
- psychopy/app/Resources/light/case@2x.png +0 -0
- psychopy/app/Resources/light/fileaudio.png +0 -0
- psychopy/app/Resources/light/fileaudio@2x.png +0 -0
- psychopy/app/Resources/light/filecss.png +0 -0
- psychopy/app/Resources/light/filecss@2x.png +0 -0
- psychopy/app/Resources/light/filecsv.png +0 -0
- psychopy/app/Resources/light/filecsv@2x.png +0 -0
- psychopy/app/Resources/light/filedesign.png +0 -0
- psychopy/app/Resources/light/filedesign@2x.png +0 -0
- psychopy/app/Resources/light/filefont.png +0 -0
- psychopy/app/Resources/light/filefont@2x.png +0 -0
- psychopy/app/Resources/light/filegit.png +0 -0
- psychopy/app/Resources/light/filegit@2x.png +0 -0
- psychopy/app/Resources/light/filehtml.png +0 -0
- psychopy/app/Resources/light/filehtml@2x.png +0 -0
- psychopy/app/Resources/light/fileimage.png +0 -0
- psychopy/app/Resources/light/fileimage@2x.png +0 -0
- psychopy/app/Resources/light/fileinfo.png +0 -0
- psychopy/app/Resources/light/fileinfo@2x.png +0 -0
- psychopy/app/Resources/light/filejs.png +0 -0
- psychopy/app/Resources/light/filejs@2x.png +0 -0
- psychopy/app/Resources/light/filejson.png +0 -0
- psychopy/app/Resources/light/filejson@2x.png +0 -0
- psychopy/app/Resources/light/filepkg.png +0 -0
- psychopy/app/Resources/light/filepkg@2x.png +0 -0
- psychopy/app/Resources/light/filepsyexp.png +0 -0
- psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/light/filepy.png +0 -0
- psychopy/app/Resources/light/filepy@2x.png +0 -0
- psychopy/app/Resources/light/filetxt.png +0 -0
- psychopy/app/Resources/light/filetxt@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown.png +0 -0
- psychopy/app/Resources/light/fileunknown@2x.png +0 -0
- psychopy/app/Resources/light/filevideo.png +0 -0
- psychopy/app/Resources/light/filevideo@2x.png +0 -0
- psychopy/app/Resources/light/find.png +0 -0
- psychopy/app/Resources/light/find@2x.png +0 -0
- psychopy/app/Resources/light/loop.png +0 -0
- psychopy/app/Resources/light/loop@2x.png +0 -0
- psychopy/app/Resources/light/regex.png +0 -0
- psychopy/app/Resources/light/regex@2x.png +0 -0
- psychopy/app/Resources/routine_templates/Basic.psyexp +0 -1
- psychopy/app/Resources/routine_templates/Misc.psyexp +0 -1
- psychopy/app/Resources/routine_templates/Online.psyexp +0 -2
- psychopy/app/Resources/routine_templates/Trials.psyexp +0 -1
- psychopy/app/Resources/splash.png +0 -0
- psychopy/app/Resources/splash@2x.png +0 -0
- psychopy/app/__init__.py +49 -8
- psychopy/app/__main__.py +3 -0
- psychopy/app/_psychopyApp.py +134 -125
- psychopy/app/builder/builder.py +42 -22
- psychopy/app/builder/dialogs/__init__.py +44 -11
- psychopy/app/builder/dialogs/dlgsCode.py +1 -1
- psychopy/app/builder/dialogs/dlgsConditions.py +1 -1
- psychopy/app/builder/dialogs/findDlg.py +106 -20
- psychopy/app/builder/dialogs/paramCtrls.py +42 -1
- psychopy/app/builder/validators.py +1 -1
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +32 -29
- psychopy/app/coder/fileBrowser.py +68 -22
- psychopy/app/coder/folding.py +1 -1
- psychopy/app/coder/psychoParser.py +1 -1
- psychopy/app/coder/repl.py +1 -1
- psychopy/app/coder/sourceTree.py +1 -1
- psychopy/app/connections/__init__.py +1 -1
- psychopy/app/connections/news.py +1 -1
- psychopy/app/connections/sendusage.py +1 -1
- psychopy/app/connections/updates.py +1 -1
- psychopy/app/console.py +1 -1
- psychopy/app/errorDlg.py +1 -1
- psychopy/app/frametracker.py +1 -1
- psychopy/app/idle.py +1 -1
- psychopy/app/jobs.py +5 -2
- psychopy/app/linuxconfig/__init__.py +1 -1
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +3 -3
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +1 -1
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3421 -2396
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +3 -3
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +2 -2
- psychopy/app/{builder/localizedStrings.py → localizedStrings.py} +173 -26
- psychopy/app/pavlovia_ui/__init__.py +1 -1
- psychopy/app/pavlovia_ui/_base.py +1 -1
- psychopy/app/pavlovia_ui/functions.py +1 -1
- psychopy/app/pavlovia_ui/menu.py +1 -1
- psychopy/app/pavlovia_ui/project.py +1 -1
- psychopy/app/pavlovia_ui/search.py +1 -1
- psychopy/app/pavlovia_ui/sync.py +1 -1
- psychopy/app/pavlovia_ui/user.py +1 -1
- psychopy/app/plugin_manager/dialog.py +34 -96
- psychopy/app/plugin_manager/packages.py +10 -14
- psychopy/app/plugin_manager/plugins.py +64 -4
- psychopy/app/preferencesDlg.py +12 -37
- psychopy/app/psychopyApp.py +130 -44
- psychopy/app/ribbon.py +1 -0
- psychopy/app/runner/runner.py +19 -7
- psychopy/app/runner/scriptProcess.py +11 -6
- psychopy/app/stdout/stdOutRich.py +9 -2
- psychopy/app/themes/fonts.py +1 -1
- psychopy/app/themes/icons.py +2 -38
- psychopy/app/ui/__init__.py +1 -1
- psychopy/app/utils.py +3 -3
- psychopy/assets/default.mp3 +0 -0
- psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
- psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Regular.ttf +0 -0
- psychopy/assets/voicekeyThresholdStim.wav +0 -0
- psychopy/clock.py +4 -1
- psychopy/colors.py +2 -0
- psychopy/core.py +1 -1
- psychopy/data/base.py +1 -1
- psychopy/data/experiment.py +151 -46
- psychopy/data/routine.py +27 -1
- psychopy/data/staircase.py +2 -1
- psychopy/data/trial.py +62 -14
- psychopy/data/utils.py +1 -1
- psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +333 -218
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +261 -239
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +319 -180
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +204 -116
- psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/bart.psyexp +779 -866
- psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +242 -180
- psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +419 -406
- psychopy/demos/builder/Experiments/dragAndDrop/README.md +2 -37
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +460 -1204
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +583 -542
- psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +458 -427
- psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +588 -550
- psychopy/demos/builder/Experiments/stroop/stroop.psyexp +303 -207
- psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +390 -215
- psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +390 -215
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +357 -331
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -2
- psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +287 -277
- psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +370 -320
- psychopy/demos/builder/Feature Demos/noise/noise.psyexp +452 -399
- psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +168 -133
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +4 -3
- psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +420 -392
- psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +917 -871
- psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +200 -0
- psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +25 -9
- psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +372 -361
- psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +25 -9
- psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +320 -235
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +790 -651
- psychopy/demos/builder/Hardware/camera/camera.psyexp +326 -246
- psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +432 -327
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +440 -321
- psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +190 -181
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +323 -312
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +329 -273
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +450 -404
- psychopy/demos/builder/Hardware/pump/pump.psyexp +593 -329
- psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +336 -274
- psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +200 -149
- psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -279
- psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +677 -564
- psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +214 -158
- psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +195 -146
- psychopy/demos/coder/experiment control/runtimeInfo.py +1 -1
- psychopy/devices/__init__.py +1 -1
- psychopy/event.py +1 -1
- psychopy/exceptions.py +1 -1
- psychopy/experiment/__init__.py +1 -1
- psychopy/experiment/_experiment.py +30 -9
- psychopy/experiment/components/__init__.py +1 -6
- psychopy/experiment/components/_base.py +44 -19
- psychopy/experiment/components/aperture/__init__.py +1 -1
- psychopy/experiment/components/brush/__init__.py +2 -2
- psychopy/experiment/components/button/__init__.py +24 -28
- psychopy/experiment/components/camera/__init__.py +38 -39
- psychopy/experiment/components/code/__init__.py +1 -1
- psychopy/experiment/components/dots/__init__.py +1 -1
- psychopy/experiment/components/eyetracker_record/__init__.py +7 -3
- psychopy/experiment/components/form/__init__.py +3 -3
- psychopy/experiment/components/grating/__init__.py +1 -1
- psychopy/experiment/components/image/__init__.py +1 -1
- psychopy/experiment/components/joyButtons/__init__.py +2 -2
- psychopy/experiment/components/joyButtons/virtualJoyButtons.py +1 -1
- psychopy/experiment/components/joystick/__init__.py +3 -3
- psychopy/experiment/components/joystick/virtualJoystick.py +1 -1
- psychopy/experiment/components/keyboard/__init__.py +98 -122
- psychopy/experiment/components/microphone/__init__.py +54 -98
- psychopy/experiment/components/mouse/__init__.py +92 -93
- psychopy/experiment/components/movie/__init__.py +28 -50
- psychopy/experiment/components/parallelOut/__init__.py +3 -3
- psychopy/experiment/components/polygon/__init__.py +2 -3
- psychopy/experiment/components/roi/__init__.py +2 -2
- psychopy/experiment/components/routineSettings/__init__.py +2 -0
- psychopy/experiment/components/serialOut/__init__.py +7 -7
- psychopy/experiment/components/settings/__init__.py +317 -313
- psychopy/experiment/components/settings/eyetracking.py +108 -0
- psychopy/experiment/components/slider/__init__.py +5 -5
- psychopy/experiment/components/sound/__init__.py +168 -78
- psychopy/experiment/components/soundsensor/__init__.py +361 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
- psychopy/experiment/components/static/__init__.py +59 -33
- psychopy/experiment/components/text/__init__.py +2 -6
- psychopy/experiment/components/textbox/__init__.py +3 -7
- psychopy/experiment/components/unknown/__init__.py +2 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -0
- psychopy/experiment/exports.py +1 -1
- psychopy/experiment/flow.py +2 -2
- psychopy/experiment/localization.py +1 -1
- psychopy/experiment/loops.py +43 -10
- psychopy/experiment/params.py +6 -4
- psychopy/experiment/plugins.py +8 -1
- psychopy/experiment/py2js.py +1 -1
- psychopy/experiment/py2js_transpiler.py +1 -1
- psychopy/experiment/routines/__init__.py +1 -1
- psychopy/experiment/routines/_base.py +23 -24
- psychopy/experiment/routines/audioValidator/__init__.py +343 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/__init__.py +76 -17
- psychopy/experiment/routines/eyetracker_validate/__init__.py +1 -1
- psychopy/experiment/routines/unknown/__init__.py +2 -0
- psychopy/experiment/routines/{photodiodeValidator → visualValidator}/__init__.py +89 -120
- psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
- psychopy/experiment/utils.py +1 -1
- psychopy/gui/__init__.py +1 -1
- psychopy/gui/qtgui.py +15 -6
- psychopy/gui/wxgui.py +1 -1
- psychopy/hardware/__init__.py +0 -1
- psychopy/hardware/base.py +147 -16
- psychopy/hardware/bbtk/__init__.py +10 -16
- psychopy/hardware/brainproducts.py +7 -13
- psychopy/hardware/button.py +21 -2
- psychopy/hardware/buttonbox/__init__.py +1 -1
- psychopy/hardware/camera/__init__.py +16 -3
- psychopy/hardware/cedrus.py +5 -16
- psychopy/hardware/crs/__init__.py +1 -1
- psychopy/hardware/crs/bits.py +36 -33
- psychopy/hardware/crs/colorcal.py +8 -11
- psychopy/hardware/crs/optical.py +7 -10
- psychopy/hardware/crs/shaders.py +18 -5
- psychopy/hardware/emotiv.py +1 -1
- psychopy/hardware/emulator.py +11 -5
- psychopy/hardware/exceptions.py +86 -0
- psychopy/hardware/forp.py +18 -23
- psychopy/hardware/gammasci.py +8 -3
- psychopy/hardware/iolab.py +8 -19
- psychopy/hardware/joystick/__init__.py +865 -266
- psychopy/hardware/joystick/_base.py +251 -0
- psychopy/hardware/joystick/backend_glfw.py +306 -0
- psychopy/hardware/joystick/backend_pyglet.py +309 -0
- psychopy/hardware/joystick/mappings.py +287 -0
- psychopy/hardware/keyboard.py +4 -2
- psychopy/hardware/labhackers.py +1 -1
- psychopy/hardware/labjacks.py +9 -13
- psychopy/hardware/{photodiode.py → lightsensor.py} +146 -203
- psychopy/hardware/listener.py +9 -8
- psychopy/hardware/manager.py +24 -35
- psychopy/hardware/microphone.py +534 -154
- psychopy/hardware/minolta.py +14 -4
- psychopy/hardware/mouse/__init__.py +1 -1
- psychopy/hardware/photometer/__init__.py +2 -2
- psychopy/hardware/pr.py +14 -4
- psychopy/hardware/qmix.py +18 -27
- psychopy/hardware/serialdevice.py +43 -12
- psychopy/hardware/soundsensor.py +473 -0
- psychopy/hardware/spatial/__init__.py +231 -0
- psychopy/hardware/speaker.py +298 -36
- psychopy/hardware/triggerbox/__init__.py +1 -1
- psychopy/hardware/triggerbox/base.py +1 -1
- psychopy/hardware/triggerbox/parallel.py +1 -1
- psychopy/info.py +1 -1
- psychopy/iohub/devices/eyetracker/__init__.py +10 -18
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +15 -33
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +1 -0
- psychopy/iohub/devices/mouse/linux2.py +2 -1
- psychopy/layout.py +1 -1
- psychopy/liaison.py +91 -39
- psychopy/locale_setup.py +11 -1
- psychopy/localization/__init__.py +1 -1
- psychopy/localization/_localization.py +1 -1
- psychopy/localization/messages.pot +2 -2
- psychopy/logging.py +14 -12
- psychopy/microphone.py +4 -3
- psychopy/misc.py +1 -1
- psychopy/monitors/MonitorCenter.py +3 -3
- psychopy/monitors/__init__.py +1 -1
- psychopy/monitors/calibData.py +1 -1
- psychopy/monitors/calibTools.py +3 -2
- psychopy/platform_specific/__init__.py +1 -1
- psychopy/platform_specific/darwin.py +1 -1
- psychopy/platform_specific/linux.py +1 -1
- psychopy/platform_specific/win32.py +1 -1
- psychopy/plugins/__init__.py +26 -17
- psychopy/plugins/util.py +65 -0
- psychopy/preferences/Darwin.spec +11 -3
- psychopy/preferences/FreeBSD.spec +11 -3
- psychopy/preferences/Linux.spec +11 -3
- psychopy/preferences/Windows.spec +11 -3
- psychopy/preferences/__init__.py +1 -1
- psychopy/preferences/baseNoArch.spec +11 -3
- psychopy/preferences/hints.py +78 -61
- psychopy/preferences/preferences.py +82 -13
- psychopy/projects/__init__.py +1 -1
- psychopy/projects/pavlovia.py +29 -13
- psychopy/scripts/psyexpCompile.py +1 -1
- psychopy/session.py +81 -8
- psychopy/sound/__init__.py +25 -10
- psychopy/sound/_base.py +134 -34
- psychopy/sound/audioclip.py +38 -15
- psychopy/sound/audiodevice.py +1 -1
- psychopy/sound/backend_ptb.py +53 -321
- psychopy/sound/backend_pygame.py +7 -3
- psychopy/sound/backend_pyo.py +53 -22
- psychopy/sound/backend_pysound.py +10 -27
- psychopy/sound/backend_sounddevice.py +33 -21
- psychopy/sound/exceptions.py +1 -1
- psychopy/sound/microphone.py +83 -5
- psychopy/sound/transcribe.py +3 -3
- psychopy/tests/data/test_basic_run.py +1 -0
- psychopy/tests/data/test_sounds/default_16000.wav +0 -0
- psychopy/tests/data/test_sounds/default_192000.wav +0 -0
- psychopy/tests/data/test_sounds/default_22050.wav +0 -0
- psychopy/tests/data/test_sounds/default_32000.wav +0 -0
- psychopy/tests/data/test_sounds/default_44100.wav +0 -0
- psychopy/tests/data/test_sounds/default_48000.wav +0 -0
- psychopy/tests/data/test_sounds/default_8000.wav +0 -0
- psychopy/tests/data/test_sounds/default_96000.wav +0 -0
- psychopy/tests/test_alerts/test_alerttools.py +2 -1
- psychopy/tests/test_app/test_command_line.py +65 -0
- psychopy/tests/test_data/test_TrialHandler2.py +18 -7
- psychopy/tests/test_demos/test_builder_demos.py +1 -1
- psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +5238 -4188
- psychopy/tests/test_experiment/needs_wx/test_components.py +1 -1
- psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
- psychopy/tests/test_experiment/test_components/test_all_components.py +1 -1
- psychopy/tests/test_experiment/test_components/test_base_components.py +26 -17
- psychopy/tests/test_experiment/test_loops.py +12 -4
- psychopy/tests/test_experiment/test_params.py +17 -4
- psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +2 -2
- psychopy/tests/test_hardware/test_photodiode.py +66 -0
- psychopy/tests/test_liaison/test_Liaison.py +4 -4
- psychopy/tests/test_misc/test_clock.py +2 -0
- psychopy/tests/test_misc/test_color.py +2 -0
- psychopy/tests/test_misc/test_event.py +1 -0
- psychopy/tests/test_plugins/__init__.py +0 -0
- psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
- psychopy/tests/test_sound/test_sound.py +111 -40
- psychopy/tests/test_tools/test_colorspacetools.py +24 -23
- psychopy/tests/test_tools/test_mathtools.py +9 -9
- psychopy/tests/test_tools/test_viewtools.py +101 -0
- psychopy/tests/test_validators/__init__.py +0 -0
- psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
- psychopy/tests/test_visual/test_all_stimuli.py +2 -2
- psychopy/tests/test_visual/test_basevisual.py +37 -7
- psychopy/tests/test_visual/test_button.py +2 -2
- psychopy/tests/test_visual/test_circle.py +10 -2
- psychopy/tests/test_visual/test_dots.py +1 -1
- psychopy/tests/test_visual/test_form.py +13 -13
- psychopy/tests/test_visual/test_gamma.py +3 -3
- psychopy/tests/test_visual/test_image.py +2 -2
- psychopy/tests/test_visual/test_progress.py +2 -2
- psychopy/tests/test_visual/test_roi.py +8 -2
- psychopy/tests/test_visual/test_shape.py +2 -2
- psychopy/tests/test_visual/test_slider.py +2 -2
- psychopy/tests/test_visual/test_target.py +2 -2
- psychopy/tests/test_visual/test_textbox.py +6 -8
- psychopy/tests/test_visual/test_winScalePos.py +6 -5
- psychopy/tests/test_visual/test_window.py +17 -0
- psychopy/tests/utils.py +51 -1
- psychopy/tools/__init__.py +1 -1
- psychopy/tools/arraytools.py +2 -2
- psychopy/tools/attributetools.py +52 -1
- psychopy/tools/audiotools.py +4 -1
- psychopy/tools/colorspacetools.py +6 -4
- psychopy/tools/coordinatetools.py +1 -1
- psychopy/tools/fileerrortools.py +21 -9
- psychopy/tools/filetools.py +2 -2
- psychopy/tools/fontmanager.py +47 -28
- psychopy/tools/gltools.py +2964 -558
- psychopy/tools/imagetools.py +1 -1
- psychopy/tools/mathtools.py +997 -127
- psychopy/tools/monitorunittools.py +7 -1
- psychopy/tools/movietools.py +1 -2
- psychopy/tools/pkgtools.py +157 -127
- psychopy/tools/plottools.py +1 -1
- psychopy/tools/rifttools.py +1 -1
- psychopy/tools/stereotools.py +1 -1
- psychopy/tools/stimulustools.py +172 -2
- psychopy/tools/stringtools.py +22 -2
- psychopy/tools/systemtools.py +1 -1
- psychopy/tools/typetools.py +1 -1
- psychopy/tools/unittools.py +1 -1
- psychopy/tools/versionchooser.py +3 -1
- psychopy/tools/viewtools.py +54 -70
- psychopy/tools/wizard.py +2 -2
- psychopy/validation/__init__.py +6 -0
- psychopy/validation/audio.py +74 -0
- psychopy/validation/visual.py +115 -0
- psychopy/visual/__init__.py +1 -4
- psychopy/visual/aperture.py +9 -6
- psychopy/visual/backends/__init__.py +1 -1
- psychopy/visual/backends/_base.py +1 -1
- psychopy/visual/backends/gamma.py +1 -1
- psychopy/visual/backends/glfwbackend.py +8 -12
- psychopy/visual/backends/pygamebackend.py +1 -1
- psychopy/visual/backends/pygletbackend.py +32 -11
- psychopy/visual/basevisual.py +93 -13
- psychopy/visual/brush.py +1 -1
- psychopy/visual/bufferimage.py +90 -10
- psychopy/visual/button.py +1 -1
- psychopy/visual/circle.py +12 -20
- psychopy/visual/custommouse.py +1 -1
- psychopy/visual/dot.py +80 -14
- psychopy/visual/elementarray.py +84 -10
- psychopy/visual/filters.py +1 -1
- psychopy/visual/form.py +43 -28
- psychopy/visual/grating.py +105 -25
- psychopy/visual/helpers.py +1 -1
- psychopy/visual/image.py +98 -20
- psychopy/visual/line.py +15 -25
- psychopy/visual/movie.py +1 -1
- psychopy/visual/movie2.py +4 -3
- psychopy/visual/movie3.py +4 -3
- psychopy/visual/movies/__init__.py +1 -1
- psychopy/visual/movies/frame.py +1 -1
- psychopy/visual/movies/metadata.py +1 -1
- psychopy/visual/movies/players/__init__.py +1 -1
- psychopy/visual/movies/players/_base.py +1 -1
- psychopy/visual/movies/players/ffpyplayer_player.py +2 -3
- psychopy/visual/nnlvs.py +9 -6
- psychopy/visual/noise.py +4 -16
- psychopy/visual/patch.py +4 -3
- psychopy/visual/pie.py +3 -14
- psychopy/visual/polygon.py +21 -28
- psychopy/visual/radial.py +4 -18
- psychopy/visual/ratingscale.py +4 -3
- psychopy/visual/rect.py +16 -25
- psychopy/visual/rift.py +8 -2
- psychopy/visual/secondorder.py +4 -16
- psychopy/visual/shaders.py +620 -286
- psychopy/visual/shape.py +281 -90
- psychopy/visual/simpleimage.py +1 -1
- psychopy/visual/slider.py +78 -25
- psychopy/visual/stim3d.py +5 -608
- psychopy/visual/text.py +13 -3
- psychopy/visual/textbox2/textbox2.py +188 -56
- psychopy/visual/vlcmoviestim.py +1 -1
- psychopy/visual/window.py +373 -200
- psychopy/web.py +1 -1
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/METADATA +9 -9
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/RECORD +644 -621
- psychopy/.DS_Store +0 -0
- psychopy/__init__.py.orig +0 -65
- psychopy/app/.DS_Store +0 -0
- psychopy/app/Resources/.DS_Store +0 -0
- psychopy/app/Resources/classic/filecsv16.png +0 -0
- psychopy/app/Resources/classic/fileimage16.png +0 -0
- psychopy/app/Resources/classic/fileunknown16.png +0 -0
- psychopy/app/Resources/dark/filecsv16.png +0 -0
- psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage16.png +0 -0
- psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown16.png +0 -0
- psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
- psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
- psychopy/app/Resources/light/filecsv16.png +0 -0
- psychopy/app/Resources/light/filecsv16@2x.png +0 -0
- psychopy/app/Resources/light/fileimage16.png +0 -0
- psychopy/app/Resources/light/fileimage16@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown16.png +0 -0
- psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
- psychopy/app/Resources/psychopySplash.png +0 -0
- psychopy/app/Resources/psychopySplash@2x.png +0 -0
- psychopy/app/builder/builder.py.orig +0 -3932
- psychopy/app/builder/dialogs/__init__.py.orig +0 -1679
- psychopy/app/builder/dialogs/paramCtrls.py.orig +0 -713
- psychopy/app/colorpicker/__init__.py.orig +0 -411
- psychopy/app/locale/ar_001/.DS_Store +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/.DS_Store +0 -0
- psychopy/core.py.orig +0 -169
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +0 -330
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +0 -61
- psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +0 -91
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
- psychopy/demos/builder/Tools/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +0 -38
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +0 -3418
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +0 -2
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +0 -15
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +0 -562
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
- psychopy/demos/coder/iohub/.iohpid +0 -1
- psychopy/demos/coder/iohub/eyetracking/.iohpid +0 -1
- psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/.DS_Store +0 -0
- psychopy/experiment/_experiment.py.orig +0 -1032
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/_base.py.orig +0 -823
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py.orig +0 -490
- psychopy/experiment/components/settings/__init__.py.orig +0 -1337
- psychopy/experiment/components/textbox/__init__.py.orig +0 -310
- psychopy/experiment/components/webcam/.DS_Store +0 -0
- psychopy/experiment/components/webcam/light/.DS_Store +0 -0
- psychopy/experiment/loops.py.orig +0 -829
- psychopy/experiment/params.py.orig +0 -408
- psychopy/experiment/routine.py.orig +0 -503
- psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/brainproducts.py.orig +0 -680
- psychopy/hardware/iolab.py.orig +0 -238
- psychopy/iohub/datastore/__init__.py.orig +0 -443
- psychopy/iohub/datastore/util.py.orig +0 -692
- psychopy/iohub/devices/mouse/darwin.py.orig +0 -427
- psychopy/iohub/devices/mouse/linux2.py.orig +0 -198
- psychopy/preferences/.DS_Store +0 -0
- psychopy/projects/pavlovia.py.orig +0 -1295
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestCircle_fill_local.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
- psychopy/tests/data/aperture1_norm_local.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_height_local.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_norm_local.png +0 -0
- psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
- psychopy/tests/data/blend_add_height_local.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
- psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
- psychopy/tests/data/blend_add_norm_local.png +0 -0
- psychopy/tests/data/blend_add_stencil_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
- psychopy/tests/data/circleHex_height_local.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
- psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
- psychopy/tests/data/circleHex_norm_local.png +0 -0
- psychopy/tests/data/circleHex_stencil_local.png +0 -0
- psychopy/tests/data/color_comparison_local.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/dots_height_local.png +0 -0
- psychopy/tests/data/dots_normAddBlend_local.png +0 -0
- psychopy/tests/data/dots_normHexbackground_local.png +0 -0
- psychopy/tests/data/dots_normNoShade_local.png +0 -0
- psychopy/tests/data/dots_norm_local.png +0 -0
- psychopy/tests/data/dots_stencil_local.png +0 -0
- psychopy/tests/data/elarray1_height_local.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
- psychopy/tests/data/elarray1_norm_local.png +0 -0
- psychopy/tests/data/elarray1_stencil_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
- psychopy/tests/data/gabor1_height_local.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
- psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
- psychopy/tests/data/gabor1_norm_local.png +0 -0
- psychopy/tests/data/gabor1_stencil_local.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_height_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
- psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
- psychopy/tests/data/movFrame1_stencil_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/numpyImage_height_local.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
- psychopy/tests/data/numpyImage_norm_local.png +0 -0
- psychopy/tests/data/numpyImage_stencil_local.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
- psychopy/tests/data/shape2_1_norm_local.png +0 -0
- psychopy/tests/data/shape2_1_stencil_local.png +0 -0
- psychopy/tests/data/text1_height_local.png +0 -0
- psychopy/tests/data/text1_normAddBlend_local.png +0 -0
- psychopy/tests/data/text1_normHexbackground_local.png +0 -0
- psychopy/tests/data/text1_norm_local.png +0 -0
- psychopy/tests/data/text1_stencil_local.png +0 -0
- psychopy/tests/data/wedge1_height_local.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
- psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
- psychopy/tests/data/wedge1_norm_local.png +0 -0
- psychopy/tests/data/wedge1_stencil_local.png +0 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +0 -177
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +0 -168
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
- psychopy/tests/test_data/.DS_Store +0 -0
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py +0 -67
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +0 -68
- psychopy/tests/test_hardware/test_CRS_bitsShaders.py +0 -110
- psychopy/tests/test_visual/test_image.py.orig +0 -219
- psychopy/visual/basevisual.py.orig +0 -1723
- psychopy/visual/form.py.orig +0 -1181
- psychopy/visual/text.py.orig +0 -752
- psychopy/visual/textbox2/textbox2.py.orig +0 -1315
- psychopy/visual/windowwarp.py.orig +0 -463
- /psychopy/{app/cortex.log → alerts/alertsCatalogue/3600.yaml} +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Bold.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-BoldItalic.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Italic.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Regular.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/DejaVuSerif.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/IndieFlower-Regular.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
- /psychopy/demos/builder/Experiments/{GoNoGo → goNoGo}/readme.md +0 -0
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/WHEEL +0 -0
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/licenses/LICENSE +0 -0
psychopy/app/builder/builder.py
CHANGED
|
@@ -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-
|
|
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
|
-
'
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
1034
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1568
|
-
dlg
|
|
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.
|
|
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.
|
|
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-
|
|
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
|
|
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
|
-
|
|
687
|
-
|
|
688
|
-
dependentCtrls
|
|
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
|
-
|
|
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
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
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-
|
|
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-
|
|
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.
|
|
31
|
-
self.sizer.Add(self.termCtrl,
|
|
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("
|
|
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
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
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
|
|
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 = [
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
242
|
+
if compareStrings(str(param.val), term, caseSensitive, regex):
|
|
174
243
|
# append path (routine -> param)
|
|
175
244
|
found.append(
|
|
176
|
-
(
|
|
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
|
|
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
|
-
(
|
|
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-
|
|
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-
|
|
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-
|
|
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.
|
|
83
|
-
self.RedoID = wx.
|
|
84
|
-
self.CutID = wx.
|
|
85
|
-
self.CopyID = wx.
|
|
86
|
-
self.PasteID = wx.
|
|
87
|
-
self.DeleteID = wx.
|
|
88
|
-
self.SelectAllID = wx.
|
|
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)
|