psychopy 2025.1.0__py3-none-any.whl → 2025.2.1__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/VERSION +1 -1
- psychopy/alerts/alertsCatalogue/4810.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +4 -0
- psychopy/alerts/alertsCatalogue/alertmsg.py +15 -1
- psychopy/alerts/alertsCatalogue/generateAlertmsg.py +2 -2
- psychopy/app/Resources/classic/add_many.png +0 -0
- psychopy/app/Resources/classic/add_many@2x.png +0 -0
- psychopy/app/Resources/classic/devices.png +0 -0
- psychopy/app/Resources/classic/devices@2x.png +0 -0
- psychopy/app/Resources/classic/photometer.png +0 -0
- psychopy/app/Resources/classic/photometer@2x.png +0 -0
- psychopy/app/Resources/dark/add_many.png +0 -0
- psychopy/app/Resources/dark/add_many@2x.png +0 -0
- psychopy/app/Resources/dark/devices.png +0 -0
- psychopy/app/Resources/dark/devices@2x.png +0 -0
- psychopy/app/Resources/dark/photometer.png +0 -0
- psychopy/app/Resources/dark/photometer@2x.png +0 -0
- psychopy/app/Resources/light/add_many.png +0 -0
- psychopy/app/Resources/light/add_many@2x.png +0 -0
- psychopy/app/Resources/light/devices.png +0 -0
- psychopy/app/Resources/light/devices@2x.png +0 -0
- psychopy/app/Resources/light/photometer.png +0 -0
- psychopy/app/Resources/light/photometer@2x.png +0 -0
- psychopy/app/_psychopyApp.py +35 -13
- psychopy/app/builder/builder.py +88 -35
- psychopy/app/builder/dialogs/__init__.py +69 -220
- psychopy/app/builder/dialogs/dlgsCode.py +29 -8
- psychopy/app/builder/dialogs/paramCtrls.py +1468 -904
- psychopy/app/builder/validators.py +25 -17
- psychopy/app/coder/coder.py +12 -1
- psychopy/app/coder/repl.py +5 -2
- psychopy/app/colorpicker/__init__.py +1 -1
- psychopy/app/deviceManager/__init__.py +1 -0
- psychopy/app/deviceManager/addDialog.py +218 -0
- psychopy/app/deviceManager/dialog.py +185 -0
- psychopy/app/deviceManager/panel.py +191 -0
- psychopy/app/deviceManager/utils.py +60 -0
- psychopy/app/idle.py +7 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +12695 -10592
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +11221 -9712
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.po +10195 -18
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +11917 -9101
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +11924 -9103
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +11917 -9101
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +11084 -9569
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +11590 -5806
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +11091 -9577
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +11072 -9549
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +11071 -9559
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +11072 -9560
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1485 -1137
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +11463 -8757
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +11288 -9434
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +11441 -8747
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +11069 -9545
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +12085 -8268
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +11929 -8022
- psychopy/app/plugin_manager/dialog.py +12 -3
- psychopy/app/plugin_manager/packageIndex.py +303 -0
- psychopy/app/plugin_manager/packages.py +203 -63
- psychopy/app/plugin_manager/plugins.py +120 -240
- psychopy/app/preferencesDlg.py +6 -1
- psychopy/app/psychopyApp.py +16 -4
- psychopy/app/runner/runner.py +10 -2
- psychopy/app/runner/scriptProcess.py +8 -3
- psychopy/app/stdout/stdOutRich.py +11 -4
- psychopy/app/themes/icons.py +3 -0
- psychopy/app/utils.py +61 -0
- psychopy/colors.py +10 -5
- psychopy/data/experiment.py +133 -23
- psychopy/data/routine.py +12 -0
- psychopy/data/staircase.py +42 -20
- psychopy/data/trial.py +20 -12
- psychopy/data/utils.py +43 -3
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +22 -5
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +2 -12
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -8
- psychopy/demos/builder/Feature Demos/movies/movie.psyexp +220 -0
- psychopy/demos/builder/Feature Demos/movies/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +1 -2
- psychopy/demos/builder/Hardware/camera/camera.psyexp +3 -16
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +3 -16
- psychopy/demos/coder/hardware/hdf5_extract.py +133 -0
- psychopy/event.py +20 -15
- psychopy/experiment/_experiment.py +86 -10
- psychopy/experiment/components/__init__.py +3 -10
- psychopy/experiment/components/_base.py +9 -20
- psychopy/experiment/components/button/__init__.py +1 -1
- psychopy/experiment/components/buttonBox/__init__.py +50 -54
- psychopy/experiment/components/camera/__init__.py +137 -359
- psychopy/experiment/components/keyboard/__init__.py +17 -24
- psychopy/experiment/components/microphone/__init__.py +61 -110
- psychopy/experiment/components/movie/__init__.py +2 -3
- psychopy/experiment/components/serialOut/__init__.py +192 -93
- psychopy/experiment/components/settings/__init__.py +45 -27
- psychopy/experiment/components/sound/__init__.py +82 -73
- psychopy/experiment/components/soundsensor/__init__.py +43 -80
- psychopy/experiment/devices.py +303 -0
- psychopy/experiment/exports.py +20 -18
- psychopy/experiment/flow.py +7 -0
- psychopy/experiment/loops.py +47 -29
- psychopy/experiment/monitor.py +74 -0
- psychopy/experiment/params.py +48 -10
- psychopy/experiment/plugins.py +28 -108
- psychopy/experiment/py2js_transpiler.py +1 -1
- psychopy/experiment/routines/__init__.py +1 -1
- psychopy/experiment/routines/_base.py +59 -24
- psychopy/experiment/routines/audioValidator/__init__.py +19 -155
- psychopy/experiment/routines/visualValidator/__init__.py +25 -25
- psychopy/hardware/__init__.py +20 -57
- psychopy/hardware/button.py +15 -2
- psychopy/hardware/camera/__init__.py +2237 -1394
- psychopy/hardware/joystick/__init__.py +1 -1
- psychopy/hardware/keyboard.py +5 -8
- psychopy/hardware/listener.py +4 -1
- psychopy/hardware/manager.py +75 -35
- psychopy/hardware/microphone.py +53 -7
- psychopy/hardware/monitor.py +144 -0
- psychopy/hardware/photometer/__init__.py +156 -117
- psychopy/hardware/serialdevice.py +16 -2
- psychopy/hardware/soundsensor.py +4 -1
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +2 -2
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +1 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +10 -0
- psychopy/iohub/devices/keyboard/darwin.py +8 -5
- psychopy/iohub/util/__init__.py +7 -8
- psychopy/localization/generateTranslationTemplate.py +208 -116
- psychopy/localization/messages.pot +4305 -3502
- psychopy/monitors/MonitorCenter.py +174 -74
- psychopy/plugins/__init__.py +6 -4
- psychopy/preferences/devices.py +80 -0
- psychopy/preferences/generateHints.py +2 -1
- psychopy/preferences/preferences.py +35 -11
- psychopy/scripts/psychopy-pkgutil.py +969 -0
- psychopy/scripts/psyexpCompile.py +1 -1
- psychopy/session.py +34 -38
- psychopy/sound/__init__.py +6 -260
- psychopy/sound/audioclip.py +164 -0
- psychopy/sound/backend_ptb.py +8 -0
- psychopy/sound/backend_pygame.py +10 -0
- psychopy/sound/backend_pysound.py +9 -0
- psychopy/sound/backends/__init__.py +0 -0
- psychopy/sound/microphone.py +3 -0
- psychopy/sound/sound.py +58 -0
- psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +1 -1
- psychopy/tests/data/duplicateHeaders.csv +2 -0
- psychopy/tests/test_app/test_builder/test_BuilderFrame.py +22 -7
- psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +0 -2
- psychopy/tests/test_data/test_utils.py +5 -1
- psychopy/tests/test_experiment/test_components/test_ButtonBoxComponent.py +22 -2
- psychopy/tests/test_hardware/test_ports.py +0 -12
- psychopy/tests/test_tools/test_stringtools.py +1 -1
- psychopy/tools/attributetools.py +12 -5
- psychopy/tools/fontmanager.py +17 -14
- psychopy/tools/gltools.py +4 -2
- psychopy/tools/movietools.py +43 -2
- psychopy/tools/stringtools.py +33 -8
- psychopy/tools/versionchooser.py +1 -1
- psychopy/validation/audio.py +5 -1
- psychopy/validation/visual.py +5 -1
- psychopy/visual/basevisual.py +8 -7
- psychopy/visual/circle.py +2 -2
- psychopy/visual/helpers.py +3 -1
- psychopy/visual/image.py +29 -109
- psychopy/visual/movies/__init__.py +1800 -313
- psychopy/visual/polygon.py +4 -0
- psychopy/visual/shape.py +2 -2
- psychopy/visual/window.py +35 -12
- psychopy/voicekey/__init__.py +41 -669
- psychopy/voicekey/labjack_vks.py +7 -48
- psychopy/voicekey/parallel_vks.py +7 -42
- psychopy/voicekey/vk_tools.py +114 -263
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/METADATA +20 -13
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/RECORD +222 -190
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/WHEEL +1 -1
- psychopy/visual/movies/players/__init__.py +0 -62
- psychopy/visual/movies/players/ffpyplayer_player.py +0 -1401
- psychopy/voicekey/demo_vks.py +0 -12
- psychopy/voicekey/signal.py +0 -42
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/entry_points.txt +0 -0
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/licenses/LICENSE +0 -0
psychopy/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2025.1
|
|
1
|
+
2025.2.1
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
code: 4810
|
|
3
|
+
cat: Devices
|
|
4
|
+
msg: Could not find any config for device {deviceName}, please setup this device up in the Device Manager dialog (from Builder)."
|
|
5
|
+
|
|
6
|
+
# The following are typically used for online help pages, and support reStructured Text.
|
|
7
|
+
label: No config for named device
|
|
8
|
+
|
|
9
|
+
synopsis: |
|
|
10
|
+
Your experiment refers to a device by name which has not been setup in Builder's Device Manager dialog.
|
|
11
|
+
|
|
12
|
+
details: |
|
|
13
|
+
From 2025.2.0, devices are setup in a dedicated Device Manager dialog and then referred to by name in Components. If you're seeing this message, it means there's a Component in your experiment which refers to a named device which has not been setup. This is common when running experiments made by someone else, or made on a different computer, as they will have setup using their devices.
|
|
14
|
+
|
|
15
|
+
solutions: |
|
|
16
|
+
Setup the named device in Builder's Device Manager dialog
|
|
17
|
+
|
|
18
|
+
versions: |
|
|
19
|
+
2025.2.0
|
|
@@ -85,6 +85,10 @@
|
|
|
85
85
|
cat: Loops
|
|
86
86
|
4705: Column name from conditions file clashes with variable name
|
|
87
87
|
4710: Column name from conditions file likely to clash with derived variable names
|
|
88
|
+
|
|
89
|
+
4800:
|
|
90
|
+
cat: Devices
|
|
91
|
+
4810: No config for named device
|
|
88
92
|
|
|
89
93
|
5000:
|
|
90
94
|
cat: Online studies
|
|
@@ -27,6 +27,13 @@ _translate(
|
|
|
27
27
|
_translate(
|
|
28
28
|
"Your stimulus {type} time of {time} seconds cannot be accurately presented for {time} on a {Hz}Hz monitor.")
|
|
29
29
|
|
|
30
|
+
# Alert 3210
|
|
31
|
+
_translate("Speaker {deviceName} is set to \"Exclusive low latency\" mode. As resampling is enabled, this mode has little benefit over \"Shared low latency\" mode, with some drawbacks.")
|
|
32
|
+
|
|
33
|
+
# Alert 3610
|
|
34
|
+
_translate(
|
|
35
|
+
"Multiple Components in the same Routine are validated by {validator}, please ensure that the timing of these Components do not overlap.")
|
|
36
|
+
|
|
30
37
|
# Alert 4051
|
|
31
38
|
_translate(
|
|
32
39
|
"Experiment was built in a future version of PsychoPy ({version}), we recommend either updating PsychoPy or changing the \"Use Version\" setting in Experiment Settings to this version.")
|
|
@@ -51,6 +58,9 @@ _translate(
|
|
|
51
58
|
_translate(
|
|
52
59
|
"Microphone component `{name}` given blank stop time, using max duration allowed by buffer size ({stopVal}s).")
|
|
53
60
|
|
|
61
|
+
# Alert 4130
|
|
62
|
+
_translate("Static Component `{name}` given infinite stop time")
|
|
63
|
+
|
|
54
64
|
# Alert 4205
|
|
55
65
|
_translate(
|
|
56
66
|
"Python Syntax Error in '{codeTab}' tab. See '{code}' on line number {lineNumber} of the '{codeTab}' tab.")
|
|
@@ -76,7 +86,7 @@ _translate(
|
|
|
76
86
|
|
|
77
87
|
# Alert 4325
|
|
78
88
|
_translate(
|
|
79
|
-
"Font `{font} {style}` not available in weight `{weight}`, component `{name}` will default to
|
|
89
|
+
"Font `{font} {style}` not available in weight `{weight}`, component `{name}` will default to Open Sans Regular.")
|
|
80
90
|
|
|
81
91
|
# Alert 4330
|
|
82
92
|
_translate(
|
|
@@ -138,6 +148,10 @@ _translate(
|
|
|
138
148
|
# Alert 4710
|
|
139
149
|
_translate("Column name '{param}' is likely to cause name clashes. {msg}.")
|
|
140
150
|
|
|
151
|
+
# Alert 4810
|
|
152
|
+
_translate(
|
|
153
|
+
"Could not find any config for device {deviceName}, please setup this device up in the Device Manager dialog (from Builder).\"")
|
|
154
|
+
|
|
141
155
|
# Alert 5055
|
|
142
156
|
_translate(
|
|
143
157
|
"Device parameter of microphone component \"{name}\" will not be used online.")
|
|
@@ -3,11 +3,11 @@ from psychopy import core
|
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
5
|
write_mode = 'w'
|
|
6
|
-
|
|
6
|
+
new_line = '\n'
|
|
7
7
|
alertmsgFile = 'alertmsg.py'
|
|
8
8
|
|
|
9
9
|
try:
|
|
10
|
-
fp = open(alertmsgFile, write_mode)
|
|
10
|
+
fp = open(alertmsgFile, write_mode, newline=new_line)
|
|
11
11
|
fp.write('#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n')
|
|
12
12
|
fp.write('# This file was generated by generateAlertmsg.py.\n')
|
|
13
13
|
fp.write('# Following strings are used to localize alerts.\n')
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
psychopy/app/_psychopyApp.py
CHANGED
|
@@ -163,6 +163,8 @@ class _Showgui_Hack():
|
|
|
163
163
|
|
|
164
164
|
class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
165
165
|
_called_from_test = False # pytest needs to change this
|
|
166
|
+
# are we running a beta release?
|
|
167
|
+
beta = True
|
|
166
168
|
|
|
167
169
|
def __init__(self, arg=0, testMode=False, startView=None, profiling=False, **kwargs):
|
|
168
170
|
"""With a wx.App some things get done here, before App.__init__
|
|
@@ -417,7 +419,7 @@ class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
|
417
419
|
|
|
418
420
|
if showSplash:
|
|
419
421
|
# show splash screen
|
|
420
|
-
if
|
|
422
|
+
if self.beta:
|
|
421
423
|
splashFile = os.path.join(
|
|
422
424
|
self.prefs.paths['resources'], 'betasplash.png'
|
|
423
425
|
)
|
|
@@ -520,6 +522,10 @@ class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
|
520
522
|
if self.isRetina:
|
|
521
523
|
self._codeFont.SetPointSize(int(self._codeFont.GetPointSize()*fontScale))
|
|
522
524
|
self._mainFont.SetPointSize(int(self._mainFont.GetPointSize()*fontScale))
|
|
525
|
+
# apply calculated point size to themed font defaults
|
|
526
|
+
from psychopy.app.themes import fonts
|
|
527
|
+
fonts.AppFont.pointSize = self._mainFont.GetPointSize()
|
|
528
|
+
fonts.CodeFont.pointSize = self._codeFont.GetPointSize()
|
|
523
529
|
# that gets most of the properties of _codeFont but the FaceName
|
|
524
530
|
# FaceName is set in the setting of the theme:
|
|
525
531
|
self.theme = prefs.app['theme']
|
|
@@ -605,7 +611,7 @@ class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
|
605
611
|
).format(thisFile, err))
|
|
606
612
|
|
|
607
613
|
# if we started a busy cursor which never finished, finish it now
|
|
608
|
-
if wx.IsBusy():
|
|
614
|
+
if wx.IsBusy() and wx.Platform != '__WXGTK__':
|
|
609
615
|
wx.EndBusyCursor()
|
|
610
616
|
|
|
611
617
|
# send anonymous info to https://usage.psychopy.org
|
|
@@ -821,13 +827,18 @@ class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
|
821
827
|
# have to reimport because it is only local to __init__ so far
|
|
822
828
|
from . import coder
|
|
823
829
|
if self.coder is None:
|
|
824
|
-
title = "PsychoPy Coder (
|
|
825
|
-
|
|
830
|
+
title = "PsychoPy Coder (v{version}{beta})".format(
|
|
831
|
+
version=self.version,
|
|
832
|
+
beta="beta" if self.beta else ""
|
|
833
|
+
)
|
|
834
|
+
if wx.Platform != '__WXGTK__':
|
|
835
|
+
wx.BeginBusyCursor()
|
|
826
836
|
self.coder = coder.CoderFrame(None, -1,
|
|
827
|
-
title=title
|
|
837
|
+
title=title,
|
|
828
838
|
files=fileList, app=self)
|
|
829
839
|
self.updateWindowMenu()
|
|
830
|
-
wx.
|
|
840
|
+
if wx.Platform != '__WXGTK__':
|
|
841
|
+
wx.EndBusyCursor()
|
|
831
842
|
else:
|
|
832
843
|
# set output window and standard streams
|
|
833
844
|
self.coder.setOutputWindow(True)
|
|
@@ -844,17 +855,22 @@ class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
|
844
855
|
|
|
845
856
|
def newBuilderFrame(self, event=None, fileName=None):
|
|
846
857
|
# have to reimport because it is only local to __init__ so far
|
|
847
|
-
wx.
|
|
858
|
+
if wx.Platform != '__WXGTK__':
|
|
859
|
+
wx.BeginBusyCursor()
|
|
848
860
|
from .builder.builder import BuilderFrame
|
|
849
|
-
title = "PsychoPy Builder (v
|
|
861
|
+
title = "PsychoPy Builder (v{version}{beta})".format(
|
|
862
|
+
version=self.version,
|
|
863
|
+
beta="beta" if self.beta else ""
|
|
864
|
+
)
|
|
850
865
|
self.builder = BuilderFrame(None, -1,
|
|
851
|
-
title=title
|
|
866
|
+
title=title,
|
|
852
867
|
fileName=fileName, app=self)
|
|
853
868
|
self.builder.Show(True)
|
|
854
869
|
self.builder.Raise()
|
|
855
870
|
self.SetTopWindow(self.builder)
|
|
856
871
|
self.updateWindowMenu()
|
|
857
|
-
wx.
|
|
872
|
+
if wx.Platform != '__WXGTK__':
|
|
873
|
+
wx.EndBusyCursor()
|
|
858
874
|
|
|
859
875
|
return self.builder
|
|
860
876
|
|
|
@@ -908,14 +924,20 @@ class PsychoPyApp(wx.App, handlers.ThemeMixin):
|
|
|
908
924
|
def newRunnerFrame(self, event=None):
|
|
909
925
|
# have to reimport because it is only local to __init__ so far
|
|
910
926
|
from .runner.runner import RunnerFrame
|
|
911
|
-
|
|
912
|
-
|
|
927
|
+
|
|
928
|
+
title = 'PsychoPy Runner (v{version}{beta})'.format(
|
|
929
|
+
version=self.version,
|
|
930
|
+
beta="beta" if self.beta else ""
|
|
931
|
+
)
|
|
932
|
+
if wx.Platform != '__WXGTK__':
|
|
933
|
+
wx.BeginBusyCursor()
|
|
913
934
|
self.runner = RunnerFrame(parent=None,
|
|
914
935
|
id=-1,
|
|
915
936
|
title=title,
|
|
916
937
|
app=self)
|
|
917
938
|
self.updateWindowMenu()
|
|
918
|
-
wx.
|
|
939
|
+
if wx.Platform != '__WXGTK__':
|
|
940
|
+
wx.EndBusyCursor()
|
|
919
941
|
return self.runner
|
|
920
942
|
|
|
921
943
|
def OnDrop(self, x, y, files):
|
psychopy/app/builder/builder.py
CHANGED
|
@@ -30,12 +30,14 @@ from wx.lib import platebtn
|
|
|
30
30
|
from wx.html import HtmlWindow
|
|
31
31
|
|
|
32
32
|
import psychopy.app.plugin_manager.dialog
|
|
33
|
+
from .dialogs.paramCtrls import EVT_PARAM_CHANGED
|
|
33
34
|
from .validators import WarningManager
|
|
34
35
|
from ..pavlovia_ui import sync, PavloviaMiniBrowser
|
|
35
36
|
from ..pavlovia_ui.project import ProjectFrame
|
|
36
37
|
from ..pavlovia_ui.search import SearchFrame
|
|
37
38
|
from ..pavlovia_ui.user import UserFrame
|
|
38
39
|
from ..pavlovia_ui.functions import logInPavlovia
|
|
40
|
+
from ..deviceManager import DeviceManagerDlg
|
|
39
41
|
from ...experiment import getAllElements, getAllCategories
|
|
40
42
|
from ...experiment.routines import Routine, BaseStandaloneRoutine
|
|
41
43
|
from psychopy.tools.versionchooser import parseVersionSafely, psychopyVersion
|
|
@@ -76,7 +78,11 @@ from psychopy.scripts.psyexpCompile import generateScript
|
|
|
76
78
|
|
|
77
79
|
# Components which are always hidden
|
|
78
80
|
alwaysHidden = [
|
|
79
|
-
'BaseComponent',
|
|
81
|
+
'BaseComponent',
|
|
82
|
+
'BaseDeviceComponent',
|
|
83
|
+
'BaseStandaloneRoutine',
|
|
84
|
+
'BaseDeviceRoutine',
|
|
85
|
+
'BaseValidatorRoutine',
|
|
80
86
|
]
|
|
81
87
|
|
|
82
88
|
|
|
@@ -132,37 +138,45 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
132
138
|
self.generateScript = generateScript
|
|
133
139
|
|
|
134
140
|
# default window title
|
|
135
|
-
self.winTitle =
|
|
141
|
+
self.winTitle = title
|
|
136
142
|
|
|
143
|
+
# get last frame information, or default
|
|
137
144
|
if fileName in self.appData['frames']:
|
|
138
145
|
self.frameData = self.appData['frames'][fileName]
|
|
139
|
-
else:
|
|
140
|
-
|
|
141
|
-
default
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
else:
|
|
147
|
+
self.frameData = dict(self.appData['defaultFrame'])
|
|
148
|
+
# work out best default size from screen size
|
|
149
|
+
i = wx.Display.GetFromPoint(wx.Point(
|
|
150
|
+
int(self.frameData['winX']), int(self.frameData['winY'])
|
|
151
|
+
))
|
|
152
|
+
try:
|
|
153
|
+
disp = wx.Display(max(i, 0))
|
|
154
|
+
except:
|
|
155
|
+
disp = wx.Display(0)
|
|
156
|
+
dispW, dispH = list(disp.GetGeometry())[2:]
|
|
157
|
+
# set in frameData array
|
|
158
|
+
self.frameData['winW'] = dispW * 0.75
|
|
159
|
+
self.frameData['winH'] = dispH * 0.75
|
|
149
160
|
# increment default for next frame
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
self
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
self.frameData['winX'] += 10
|
|
162
|
+
self.frameData['winY'] += 10
|
|
163
|
+
# handle when last open frame was minimised or invalid
|
|
164
|
+
for key in ("winH", "winW", "winX", "winY"):
|
|
165
|
+
self.frameData[key] = max(self.frameData[key], 20)
|
|
166
|
+
# initialise
|
|
167
|
+
BaseAuiFrame.__init__(
|
|
168
|
+
self,
|
|
169
|
+
parent=parent,
|
|
170
|
+
id=id,
|
|
171
|
+
size=(
|
|
172
|
+
int(self.frameData['winW']), int(self.frameData['winH'])
|
|
173
|
+
),
|
|
174
|
+
pos=(
|
|
175
|
+
int(self.frameData['winX']), int(self.frameData['winY'])
|
|
176
|
+
),
|
|
177
|
+
title=title,
|
|
178
|
+
style=style
|
|
179
|
+
)
|
|
166
180
|
# detect retina displays (then don't use double-buffering)
|
|
167
181
|
self.isRetina = \
|
|
168
182
|
self.GetContentScaleFactor() != 1 and wx.Platform == '__WXMAC__'
|
|
@@ -191,7 +205,7 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
191
205
|
self.SetAcceleratorTable(accelTable)
|
|
192
206
|
|
|
193
207
|
# setup a default exp
|
|
194
|
-
if self.filename.is_file():
|
|
208
|
+
if fileName is not None and self.filename.is_file():
|
|
195
209
|
self.fileOpen(filename=fileName, closeCurrent=False)
|
|
196
210
|
else:
|
|
197
211
|
self.lastSavedCopy = None
|
|
@@ -242,7 +256,11 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
242
256
|
self._mgr.Update()
|
|
243
257
|
# self.SetSizer(self.mainSizer) # not necessary for aui type controls
|
|
244
258
|
if self.frameData['auiPerspective']:
|
|
245
|
-
self._mgr.
|
|
259
|
+
backup = self._mgr.SavePerspective()
|
|
260
|
+
try:
|
|
261
|
+
self._mgr.LoadPerspective(self.frameData['auiPerspective'])
|
|
262
|
+
except:
|
|
263
|
+
self._mgr.LoadPerspective(backup)
|
|
246
264
|
self.SetMinSize(wx.Size(600, 400)) # min size for the whole window
|
|
247
265
|
self.SetSize(
|
|
248
266
|
(int(self.frameData['winW']), int(self.frameData['winH'])))
|
|
@@ -437,6 +455,11 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
437
455
|
_translate("To set information about your monitor"))
|
|
438
456
|
self.Bind(wx.EVT_MENU, self.app.openMonitorCenter, item)
|
|
439
457
|
|
|
458
|
+
item = menu.Append(wx.ID_ANY,
|
|
459
|
+
_translate("Device Manager"),
|
|
460
|
+
_translate("Setup named devices for your Components to refer to"))
|
|
461
|
+
self.Bind(wx.EVT_MENU, self.openDeviceManager, item)
|
|
462
|
+
|
|
440
463
|
item = menu.Append(wx.ID_ANY,
|
|
441
464
|
_translate("Compile\t%s") % keys['compileScript'],
|
|
442
465
|
_translate("Compile the exp to a script"))
|
|
@@ -599,6 +622,12 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
599
622
|
self.Bind(wx.EVT_MENU, self.app.showNews, id=item.GetId())
|
|
600
623
|
|
|
601
624
|
self.SetMenuBar(menuBar)
|
|
625
|
+
|
|
626
|
+
def openDeviceManager(self, evt=None):
|
|
627
|
+
# create a device manager dialog
|
|
628
|
+
dlg = DeviceManagerDlg(self)
|
|
629
|
+
# show it modal to this window
|
|
630
|
+
dlg.ShowModal()
|
|
602
631
|
|
|
603
632
|
def commandCloseFrame(self, event):
|
|
604
633
|
"""Defines Builder Frame Closing Event"""
|
|
@@ -1571,6 +1600,19 @@ class BuilderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
1571
1600
|
return True
|
|
1572
1601
|
|
|
1573
1602
|
def openPluginManager(self, evt=None):
|
|
1603
|
+
# check if the package index is currently being updated, show a message
|
|
1604
|
+
# to tell the user to wait before opening the plugin manager
|
|
1605
|
+
import psychopy.app.plugin_manager.packageIndex as packageIndex
|
|
1606
|
+
if packageIndex.isIndexing():
|
|
1607
|
+
msg = _translate("The package index is currently being updated. "
|
|
1608
|
+
"Please try again later.")
|
|
1609
|
+
wx.MessageBox(
|
|
1610
|
+
msg,
|
|
1611
|
+
_translate("Package indexing in progress"),
|
|
1612
|
+
style=wx.OK | wx.ICON_INFORMATION
|
|
1613
|
+
)
|
|
1614
|
+
return
|
|
1615
|
+
|
|
1574
1616
|
dlg = psychopy.app.plugin_manager.dialog.EnvironmentManagerDlg(self)
|
|
1575
1617
|
dlg.Show()
|
|
1576
1618
|
|
|
@@ -2725,7 +2767,9 @@ class StandaloneRoutineCanvas(scrolledpanel.ScrolledPanel):
|
|
|
2725
2767
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
|
2726
2768
|
self.SetSizer(self.sizer)
|
|
2727
2769
|
# Setup categ notebook
|
|
2770
|
+
self.warnings = WarningManager(self)
|
|
2728
2771
|
self.ctrls = ParamNotebook(self, experiment=self.frame.exp, element=routine)
|
|
2772
|
+
self.ctrls.Bind(EVT_PARAM_CHANGED, self.updateExperiment)
|
|
2729
2773
|
self.paramCtrls = self.ctrls.paramCtrls
|
|
2730
2774
|
self.sizer.Add(self.ctrls, border=12, proportion=1, flag=wx.ALIGN_CENTER | wx.TOP)
|
|
2731
2775
|
# Make buttons
|
|
@@ -2734,10 +2778,9 @@ class StandaloneRoutineCanvas(scrolledpanel.ScrolledPanel):
|
|
|
2734
2778
|
self.helpBtn.Bind(wx.EVT_BUTTON, self.onHelp)
|
|
2735
2779
|
self.btnsSizer.Add(self.helpBtn, border=6, flag=wx.ALL | wx.EXPAND)
|
|
2736
2780
|
self.btnsSizer.AddStretchSpacer(1)
|
|
2737
|
-
#
|
|
2738
|
-
self.warnings = WarningManager(self)
|
|
2781
|
+
# add warnings to sizer
|
|
2739
2782
|
self.sizer.Add(self.warnings.output, border=3, flag=wx.EXPAND | wx.ALL)
|
|
2740
|
-
#
|
|
2783
|
+
# add buttons to sizer
|
|
2741
2784
|
self.sizer.Add(self.btnsSizer, border=3, proportion=0, flag=wx.EXPAND | wx.ALL)
|
|
2742
2785
|
# Style
|
|
2743
2786
|
self.SetupScrolling(scroll_y=True)
|
|
@@ -2757,12 +2800,15 @@ class StandaloneRoutineCanvas(scrolledpanel.ScrolledPanel):
|
|
|
2757
2800
|
for name, routine in routines.items():
|
|
2758
2801
|
if routine == self.routine:
|
|
2759
2802
|
# Update the routine dict keys to use the current name for this routine
|
|
2760
|
-
self.frame.exp.routines[self.routine.
|
|
2803
|
+
self.frame.exp.routines[self.routine.name] = self.frame.exp.routines.pop(name)
|
|
2804
|
+
# update experiment namespace
|
|
2805
|
+
self.frame.exp.namespace.remove(name)
|
|
2806
|
+
self.frame.exp.namespace.add(self.routine.name)
|
|
2761
2807
|
# Redraw the flow panel
|
|
2762
2808
|
self.frame.flowPanel.canvas.draw()
|
|
2763
2809
|
# Rename this page
|
|
2764
2810
|
page = self.frame.routinePanel.GetPageIndex(self)
|
|
2765
|
-
self.frame.routinePanel.SetPageText(page, self.routine.
|
|
2811
|
+
self.frame.routinePanel.SetPageText(page, self.routine.name)
|
|
2766
2812
|
# Update save button
|
|
2767
2813
|
self.frame.setIsModified(True)
|
|
2768
2814
|
|
|
@@ -4546,6 +4592,13 @@ class BuilderRibbon(ribbon.FrameRibbon):
|
|
|
4546
4592
|
tooltip=_translate("Monitor settings and calibration"),
|
|
4547
4593
|
callback=parent.app.openMonitorCenter
|
|
4548
4594
|
)
|
|
4595
|
+
# device manager
|
|
4596
|
+
self.addButton(
|
|
4597
|
+
section="experiment", name='devices', label=_translate('Device manager'),
|
|
4598
|
+
icon="devices",
|
|
4599
|
+
tooltip=_translate("Map devices from this machine to names in your experiment"),
|
|
4600
|
+
callback=parent.openDeviceManager
|
|
4601
|
+
)
|
|
4549
4602
|
# settings
|
|
4550
4603
|
self.addButton(
|
|
4551
4604
|
section="experiment", name='expsettings', label=_translate('Experiment settings'), icon="expsettings",
|