コード例 #1
0
ファイル: _mouse.py プロジェクト: Dannnno/expyriment
    def __init__(self, show_cursor=True, track_button_events=None,
                 track_motion_events=None):
        """Initialize a mouse input.

        Notes
        -----
        It is strongly suggest to avoid tracking of motions events,
        (track_motion_events=True), because it quickly causes an overflow in
        the Pygame event queue and you might consequently loose important
        events.

        Parameters
        ----------
        show_cursor : bool, optional
            shows mouse cursor (default = True)
        track_button_events : bool, optional
            track button events via Pygame queue (default = True)
        track_motion_events : bool, optional
            track motion events via Pygame queue (default = False)

        """

        Input.__init__(self)
        if show_cursor is None:
            show_cursor = defaults.mouse_show_cursor
        if track_button_events is None:
            track_button_events = defaults.mouse_track_button_events
        if track_motion_events is None:
            track_motion_events = defaults.mouse_track_motion_events

        if show_cursor:
            self.show_cursor(track_button_events, track_motion_events)
        else:
            self.track_button_events = track_button_events
            self.track_motion_events = track_motion_events
コード例 #2
0
    def __init__(self,
                 gamepad_id,
                 track_button_events=True,
                 track_motion_events=False):
        """Create a gamepad/joystick input.

        Parameters
        ----------
        gamepad_id : int
            id of the gamepad
        track_button_events : bool, optional
            Track button events (default=True)
        track_motion_events : bool, optional
            Track motion events (default=False)

        """

        if not expyriment._active_exp.is_initialized:
            raise RuntimeError(
                "Cannot create GamePad before expyriment.initialize()!")
        Input.__init__(self)
        Output.__init__(self)
        self.track_button_events = track_button_events
        self.track_motion_events = track_motion_events
        self._joystick = pygame.joystick.Joystick(gamepad_id)
        self._joystick.init()
コード例 #3
0
    def __init__(self, default_keys=None):
        """Create a keyboard input.

        Parameters
        ----------
        default_keys : int or list, optional
            a default key or list of default keys

        """

        if default_keys is not None:
            self._default_keys = default_keys
        else:
            self._default_keys = defaults.keyboard_default_keys
        Input.__init__(self)
コード例 #4
0
ファイル: _keyboard.py プロジェクト: fnielsen/expyriment
    def __init__(self, default_keys=None):
        """Create a keyboard input.

        Parameters
        ----------
        default_keys : int or list, optional
            a default key or list of default keys

        """

        if default_keys is not None:
            self._default_keys = default_keys
        else:
            self._default_keys = defaults.keyboard_default_keys
        Input.__init__(self)
コード例 #5
0
ファイル: _triggerinput.py プロジェクト: fladd/expyriment
    def __init__(self, interface, default_code=None):
        """Create a trigger input.

        Parameters
        interface    -- the interface to use (expyrment.io.SerialPort or
                        expyriment.io.ParallelPort object)
        default_code -- the default code of the trigger (int) (optional)

        """

        Input.__init__(self)
        self._interface = interface
        if default_code is not None:
            self._default_code = default_code
        else:
            self._default_code = defaults.triggerinput_default_code
コード例 #6
0
    def __init__(self, interface, default_code=None):
        """Create a trigger input.

        Parameters
        interface    -- the interface to use (expyrment.io.SerialPort or
                        expyriment.io.ParallelPort object)
        default_code -- the default code of the trigger (int) (optional)

        """

        Input.__init__(self)
        self._interface = interface
        if default_code is not None:
            self._default_code = default_code
        else:
            self._default_code = defaults.triggerinput_default_code
コード例 #7
0
    def __init__(self, button_fields, stimuli=[], background_stimulus=None):
        """Initialize a touchscreen button box.

        Parameters
        ----------
        button_fields : visual Expyriment stimulus or list of stimuli
            The button fields defines the area on which a click action will be
            registered.
        stimuli : visual Expyriment stimulus or list of stimuli, optional
            Additional visual stimuli that will be presented together with the
            button fields. Stimuli are plotted on top of the button_fields.
        background_stimulus : visual Expyriment stimulus, optional
            The background stimulus on which the touschscreen button fields
            are presented. Importantly, background_stimulus has to have
            size of the screen.

        Notes
        -----
        Every visual Expyriment stimulus can serve as a touchscreen button
        field.
        If the TouchScreenButtonBox is presented, it can be checked for events
        using the methods 'check' and 'wait'.

        """

        Input.__init__(self)

        try:
            button_fields = list(button_fields)
        except:
            button_fields = [button_fields]
        try:
            stimuli = list(stimuli)
        except:
            stimuli = [stimuli]

        self._mouse = expyriment._active_exp.mouse
        self._last_touch_position = None
        self._canvas = None
        self._button_fields = []
        self._stimuli = []
        self.background_stimulus = background_stimulus
        map(self.add_button_field, button_fields)
        map(self.add_stimulus, stimuli)
コード例 #8
0
    def __init__(self, button_fields, stimuli=[], background_stimulus=None):
        """Initialize a touchscreen button box.

        Parameters
        ----------
        button_fields : visual Expyriment stimulus or list of stimuli
            The button fields defines the area on which a click action will be
            registered.
        stimuli : visual Expyriment stimulus or list of stimuli, optional
            Additional visual stimuli that will be presented together with the
            button fields. Stimuli are plotted on top of the button_fields.
        background_stimulus : visual Expyriment stimulus, optional
            The background stimulus on which the touschscreen button fields
            are presented. Importantly, background_stimulus has to have
            size of the screen.

        Notes
        -----
        Every visual Expyriment stimulus can serve as a touchscreen button
        field.
        If the TouchScreenButtonBox is presented, it can be checked for events
        using the methods 'check' and 'wait'.

        """

        Input.__init__(self)

        try:
            button_fields = list(button_fields)
        except:
            button_fields = [button_fields]
        try:
            stimuli = list(stimuli)
        except:
            stimuli = [stimuli]

        self._mouse = expyriment._active_exp.mouse
        self._last_touch_position = None
        self._canvas = None
        self._button_fields = []
        self._stimuli = []
        self.background_stimulus = background_stimulus
        map(self.add_button_field, button_fields)
        map(self.add_stimulus, stimuli)
コード例 #9
0
    def __init__(self, interface, baseline):
        """Create a streaming button box input.

        Parameters
        ----------
        interface : io.SerialPort or io.ParallelPort
            an interface object
        baseline : int
            code that is sent when nothing is pressed (int)

        """

        Input.__init__(self)
        Output.__init__(self)
        self._interface = interface
        if baseline is not None:
            self._baseline = baseline
        else:
            self._baseline = defaults.streamingbuttonbox_baseline
コード例 #10
0
    def __init__(self, interface, baseline):
        """Create a streaming button box input.

        Parameters
        ----------
        interface : io.SerialPort or io.ParallelPort
            an interface object
        baseline : int
            code that is sent when nothing is pressed (int)

        """

        Input.__init__(self)
        Output.__init__(self)
        self._interface = interface
        if baseline is not None:
            self._baseline = baseline
        else:
            self._baseline = defaults.streamingbuttonbox_baseline
コード例 #11
0
ファイル: _mouse.py プロジェクト: mutlusun/expyriment
    def __init__(self,
                 show_cursor=True,
                 track_button_events=None,
                 track_motion_events=None,
                 quit_click_rect_size=None):
        """Initialize a mouse input.

        Parameters
        ----------
        show_cursor : bool, optional
            shows mouse cursor (default = True)
        track_button_events : bool, optional
            track button events via Pygame queue (default = True)
        track_motion_events : bool, optional
            track motion events via Pygame queue (default = False)

        Notes
        -----
        (a) It is strongly suggest to avoid tracking of motions events,
        (track_motion_events=True), because it quickly causes an overflow in
        the Pygame event queue and you might consequently loose important
        events.

        (b) See `process_quit_event` for the forced quitting of experiments
        via mouse events.

        """

        Input.__init__(self)
        if expyriment.control.is_android_running():
            Mouse.quit_rect_location = 1
        if show_cursor is None:
            show_cursor = defaults.mouse_show_cursor
        if track_button_events is None:
            track_button_events = defaults.mouse_track_button_events
        if track_motion_events is None:
            track_motion_events = defaults.mouse_track_motion_events
        if show_cursor:
            self.show_cursor(track_button_events, track_motion_events)
        else:
            self.track_button_events = track_button_events
            self.track_motion_events = track_motion_events
コード例 #12
0
ファイル: _gamepad.py プロジェクト: smathot/expyriment
    def __init__(self, gamepad_id, track_button_events=True, track_motion_events=False):
        """Create a gamepad/joystick input.

        Parameters
        ----------
        gamepad_id : int
            id of the gamepad
        track_button_events : bool, optional
            Track button events (default=True)
        track_motion_events : bool, optional
            Track motion events (default=False)

        """

        if not expyriment._active_exp.is_initialized:
            raise RuntimeError("Cannot create GamePad before expyriment.initialize()!")
        Input.__init__(self)
        Output.__init__(self)
        self.track_button_events = track_button_events
        self.track_motion_events = track_motion_events
        self._joystick = pygame.joystick.Joystick(gamepad_id)
        self._joystick.init()
コード例 #13
0
ファイル: _mouse.py プロジェクト: takashiyamauchi/expyriment
    def __init__(self, show_cursor=True, track_button_events=None,
                 track_motion_events=None, quit_click_rect_size=None):
        """Initialize a mouse input.

        Parameters
        ----------
        show_cursor : bool, optional
            shows mouse cursor (default = True)
        track_button_events : bool, optional
            track button events via Pygame queue (default = True)
        track_motion_events : bool, optional
            track motion events via Pygame queue (default = False)

        Notes
        -----
        (a) It is strongly suggest to avoid tracking of motions events,
        (track_motion_events=True), because it quickly causes an overflow in
        the Pygame event queue and you might consequently loose important
        events.

        (b) See `process_quit_event` for the forced quitting of experiments
        via mouse events.

        """

        Input.__init__(self)
        if expyriment.control.is_android_running():
            Mouse.quit_rect_location = 1
        if show_cursor is None:
            show_cursor = defaults.mouse_show_cursor
        if track_button_events is None:
            track_button_events = defaults.mouse_track_button_events
        if track_motion_events is None:
            track_motion_events = defaults.mouse_track_motion_events
        if show_cursor:
            self.show_cursor(track_button_events, track_motion_events)
        else:
            self.track_button_events = track_button_events
            self.track_motion_events = track_motion_events
コード例 #14
0
ファイル: _parallelport.py プロジェクト: smathot/expyriment
    def __init__(self):
        """Create a parallel port input and output.

        """

        import types

        if type(parallel) is not types.ModuleType:
            message = """ParallelPort can not be initialized.
The Python package 'pyParallel' is not installed."""
            raise ImportError(message)

        if float(parallel.VERSION) < 0.2:
            raise ImportError(
                "Expyriment {0} ".format(__version__)
                + "is not compatible with PyParallel {0}.".format(parallel.VERSION)
                + "\nPlease install PyParallel 0.2 or higher."
            )

        Input.__init__(self)
        Output.__init__(self)
        self._parallel = parallel.Parallel()
        self.input_history = False  # dummy
コード例 #15
0
    def __init__(self,
                 port,
                 baudrate=None,
                 bytesize=None,
                 parity=None,
                 stopbits=None,
                 timeout=None,
                 xonxoff=None,
                 rtscts=None,
                 dsrdtr=None,
                 input_history=None,
                 os_buffer_size=None,
                 clock=None):
        """Create a serial port input and output.

        The port argument will accept the number of the port (e.g. 0 for COM1)
        as well as a string describing the full port location ("COM1" or
        "/dev/ttyS0").

        Notes
        -----
        An input_history can be used to overcome the size limitation of the
        receive buffer of the operating system. An input_history consists of a
        misc.ByteBuffer instance.
        In order to not miss any input, the serial port has to be updated
        regularly (i.e. calling read_input() or clear() before the receive
        buffer will be full). If the receive buffer size is set correctly, a
        warning will be given, when the input_history was not updated fast
        enough.
        Importantly, the fuller the receive buffer is, the longer clearing
        and polling will take (this can be more than 1 ms!), since all the
        bytes have to be transfered to the input_history.

        Parameters
        ----------
        port : int or str
            port to use
        baudrate : int, optional
        bytesize : int, optional
        parity : str, optional
            parity:'E'=even, 'O'=odd, 'N'=none
        stopbits : int, optional
        timeout : int, optional
            the timeout for read(): -1=block
        xonxoff : int, optional
        rtscts : int, optional
        dsrdtr : int, optional
        input_history : bool, optional
            True if an input_history should be used
        os_buffer_size : int, optional
            the size of the receive input_history provided by the operating
            system in bytes
        clock : misc.Clock, optional
            an experimental clock
                            (optional)

        """

        import types
        if type(serial) is not types.ModuleType:
            message = """SerialPort can not be initialized.
The Python package 'pySerial' is not installed."""
            raise ImportError(message)

        if float(serial.VERSION) < 2.5:
            raise ImportError(
                "Expyriment {0} ".format(__version__) +
                "is not compatible with PySerial {0}.".format(serial.VERSION) +
                "\nPlease install PySerial 2.5 or higher.")

        Input.__init__(self)
        Output.__init__(self)
        if baudrate is None:
            baudrate = defaults.serialport_baudrate
        if bytesize is None:
            bytesize = defaults.serialport_bytesize
        if parity is None:
            parity = defaults.serialport_parity
        if stopbits is None:
            stopbits = defaults.serialport_stopbits
        if timeout is None:
            timeout = defaults.serialport_timeout
        if timeout == -1:
            timeout = None
        if xonxoff is None:
            xonxoff = defaults.serialport_xonxoff
        if rtscts is None:
            rtscts = defaults.serialport_rtscts
        if dsrdtr is None:
            dsrdtr = defaults.serialport_dsrdtr
        if clock is not None:
            self._clock = clock
        else:
            if expyriment._active_exp.is_initialized:
                self._clock = expyriment._active_exp.clock
            else:
                self._clock = Clock()
        if input_history is None:
            input_history = defaults.serialport_input_history
        if input_history is True:
            self._input_history = ByteBuffer(
                name="SerialPortBuffer (Port {0})".format(repr(port)),
                clock=self._clock)
        else:
            self._input_history = False
        if os_buffer_size is None:
            os_buffer_size = defaults.serialport_os_buffer_size
        self._os_buffer_size = os_buffer_size

        self._serial = serial.Serial(port, baudrate, bytesize, parity,
                                     stopbits, timeout, xonxoff, rtscts,
                                     dsrdtr)
        if not self._serial.isOpen():
            raise IOError("Could not open serial port")

        atexit.register(self.close)
コード例 #16
0
ファイル: _serialport.py プロジェクト: fnielsen/expyriment
    def __init__(self, port, baudrate=None, bytesize=None, parity=None,
                 stopbits=None, timeout=None, xonxoff=None, rtscts=None,
                 dsrdtr=None, input_history=None, os_buffer_size=None,
                 clock=None):
        """Create a serial port input and output.

        The port argument will accept the number of the port (e.g. 0 for COM1)
        as well as a string describing the full port location ("COM1" or
        "/dev/ttyS0").

        Notes
        -----
        An input_history can be used to overcome the size limitation of the
        receive buffer of the operating system. An input_history consists of a
        misc.ByteBuffer instance.
        In order to not miss any input, the serial port has to be updated
        regularly (i.e. calling read_input() or clear() before the receive
        buffer will be full). If the receive buffer size is set correctly, a
        warning will be given, when the input_history was not updated fast
        enough.
        Importantly, the fuller the receive buffer is, the longer clearing
        and polling will take (this can be more than 1 ms!), since all the
        bytes have to be transfered to the input_history.

        Parameters
        ----------
        port : int or str
            port to use
        baudrate : int, optional
        bytesize : int, optional
        parity : str, optional
            parity:'E'=even, 'O'=odd, 'N'=none
        stopbits : int, optional
        timeout : int, optional
            the timeout for read(): -1=block
        xonxoff : int, optional
        rtscts : int, optional
        dsrdtr : int, optional
        input_history : bool, optional
            True if an input_history should be used
        os_buffer_size : int, optional
            the size of the receive input_history provided by the operating
            system in bytes
        clock : misc.Clock, optional
            an experimental clock
                            (optional)

        """

        import types
        if type(serial) is not types.ModuleType:
            message = """SerialPort can not be initialized.
The Python package 'pySerial' is not installed."""
            raise ImportError(message)

        if float(serial.VERSION) < 2.5:
            raise ImportError("Expyriment {0} ".format(__version__) +
                    "is not compatible with PySerial {0}.".format(
                        serial.VERSION) +
                      "\nPlease install PySerial 2.5 or higher.")

        Input.__init__(self)
        Output.__init__(self)
        if baudrate is None:
            baudrate = defaults.serialport_baudrate
        if bytesize is None:
            bytesize = defaults.serialport_bytesize
        if parity is None:
            parity = defaults.serialport_parity
        if stopbits is None:
            stopbits = defaults.serialport_stopbits
        if timeout is None:
            timeout = defaults.serialport_timeout
        if timeout == -1:
            timeout = None
        if xonxoff is None:
            xonxoff = defaults.serialport_xonxoff
        if rtscts is None:
            rtscts = defaults.serialport_rtscts
        if dsrdtr is None:
            dsrdtr = defaults.serialport_dsrdtr
        if clock is not None:
            self._clock = clock
        else:
            if expyriment._active_exp.is_initialized:
                self._clock = expyriment._active_exp.clock
            else:
                self._clock = Clock()
        if input_history is None:
            input_history = defaults.serialport_input_history
        if input_history is True:
            self._input_history = ByteBuffer(
                name="SerialPortBuffer (Port {0})".format(repr(port)),
                clock=self._clock)
        else:
            self._input_history = False
        if os_buffer_size is None:
            os_buffer_size = defaults.serialport_os_buffer_size
        self._os_buffer_size = os_buffer_size

        self._serial = serial.Serial(port, baudrate, bytesize, parity,
                                    stopbits, timeout, xonxoff, rtscts,
                                    dsrdtr)
        if not self._serial.isOpen():
            raise IOError("Could not open serial port")

        atexit.register(self.close)
コード例 #17
0
    def __init__(self,
                 message="",
                 position=None,
                 ascii_filter=None,
                 length=None,
                 message_text_size=None,
                 message_colour=None,
                 message_font=None,
                 message_bold=None,
                 message_italic=None,
                 user_text_size=None,
                 user_text_bold=None,
                 user_text_font=None,
                 user_text_colour=None,
                 background_colour=None,
                 frame_colour=None,
                 gap=None,
                 screen=None,
                 background_stimulus=None):
        """Create a text input box.

        Notes
        -----
        This stimulus is not optimized for timing accurate presentation!

        Parameters
        ----------
        message : str, optional
            message to show
        position : (int, int), optional
            position of the TextInput canvas
        length : int, optional
            the length of the text input frame in number of charaters
        ascii_filter : list, optional
            list of ASCII codes to filter for
        message_text_size : int, optional
            text size of the message
        message_colour : (int, int, int), optional
            text colour of the message
        message_font : str, optional
            text font of the message
        message_bold : bool, optional
            True if message text should be bold
        message_italic : bool, optional
            True if message text should be italic
        user_text_size : int, optional
            text size of the user input
        user_text_font : str, optional
            text font of the user input
        user_text_colour : (int, int ,int), optional
            text colour of the user input
        user_text_bold : bool, optional
            True if user text should be bold
        background_colour : (int, int, int), optional
        frame_colour : (int, int, int)
            colour of the frame
        gap : int, optional
            gap between message and user input
        screen : io.Screen, optional
            screen to present on
        background_stimulus : visual Expyriment stimulus, optional
            The background stimulus is a second stimulus that will be presented
            together with the TextInput. For both stimuli overlap TextInput
            will appear on top of the background_stimulus

        """

        if not expyriment._active_exp.is_initialized:
            raise RuntimeError(
                "Cannot create TextInput before expyriment.initialize()!")
        Input.__init__(self)
        self._message = message
        if position is not None:
            self._position = position
        else:
            self._position = defaults.textinput_position
        if ascii_filter is not None:
            self._ascii_filter = ascii_filter
        else:
            self._ascii_filter = defaults.textinput_ascii_filter
        if length is not None:
            self._length = length
        else:
            self._length = defaults.textinput_length
        if message_text_size is None:
            message_text_size = defaults.textinput_message_text_size
        if message_text_size is not None:
            self._message_text_size = message_text_size
        else:
            self._message_text_size = expyriment._active_exp.text_size
        if message_colour is None:
            message_colour = defaults.textinput_message_colour
        if message_colour is not None:
            self._message_colour = message_colour
        else:
            self._message_colour = expyriment._active_exp.foreground_colour
        if message_font is None:
            message_font = defaults.textinput_message_font
        if message_font is not None:
            self._message_font = find_font(message_font)
        else:
            self._message_font = find_font(expyriment._active_exp.text_font)
        try:
            _font = pygame.font.Font(unicode2str(self._message_font, fse=True),
                                     10)
        except:
            raise IOError("Font '{0}' not found!".format(message_font))
        if message_bold is not None:
            self._message_bold = message_bold
        else:
            self._message_bold = defaults.textinput_message_bold
        if message_italic is not None:
            self._message_italic = message_italic
        else:
            self._message_italic = defaults.textinput_message_italic
        if user_text_size is None:
            user_text_size = defaults.textinput_user_text_size
        if user_text_size is not None:
            self._user_text_size = user_text_size
        else:
            self._user_text_size = expyriment._active_exp.text_size

        if user_text_bold is not None:
            self._user_text_bold = user_text_bold
        else:
            self._user_text_bold = defaults.textinput_user_text_bold
        if user_text_font is None:
            user_text_font = defaults.textinput_user_text_font
        if user_text_font is not None:
            self._user_text_font = find_font(user_text_font)
        else:
            self._user_text_font = find_font(expyriment._active_exp.text_font)
        try:
            _font = pygame.font.Font(
                unicode2str(self._user_text_font, fse=True), 10)
        except:
            raise IOError("Font '{0}' not found!".format(user_text_font))
        if user_text_colour is None:
            user_text_colour = defaults.textinput_user_text_colour
        if user_text_colour is not None:
            self._user_text_colour = user_text_colour
        else:
            self._user_text_colour = expyriment._active_exp.foreground_colour
        if background_colour is None:
            background_colour = \
                defaults.textinput_background_colour
        if background_colour is not None:
            self._background_colour = background_colour
        else:
            self._background_colour = \
                expyriment._active_exp.background_colour
        if frame_colour is None:
            frame_colour = defaults.textinput_frame_colour
        if frame_colour is not None:
            self._frame_colour = frame_colour
        else:
            self._frame_colour = expyriment._active_exp.foreground_colour
        if gap is not None:
            self._gap = gap
        else:
            self._gap = defaults.textinput_gap
        if screen is not None:
            self._screen = screen
        else:
            self._screen = expyriment._active_exp.screen
        if background_stimulus is not None:
            # FIXME child of child of visual does not work as background stimulus, e.g. BlankScreen
            if background_stimulus.__class__.__base__ in \
                     [expyriment.stimuli._visual.Visual, expyriment.stimuli.Shape]:
                self._background_stimulus = background_stimulus
            else:
                raise TypeError("{0} ".format(type(background_stimulus)) +
                                "is not a valid background stimulus. " +
                                "Use an expyriment visual stimulus.")
        else:
            self._background_stimulus = None

        self._user = []
        self._user_text_surface_size = None
        self._max_size = None
        self._message_surface_size = None
        self._canvas = None
        self._canvas_size = None
コード例 #18
0
ファイル: _textinput.py プロジェクト: fnielsen/expyriment
    def __init__(
        self,
        message="",
        position=None,
        ascii_filter=None,
        length=None,
        message_text_size=None,
        message_colour=None,
        message_font=None,
        message_bold=None,
        message_italic=None,
        user_text_size=None,
        user_text_bold=None,
        user_text_font=None,
        user_text_colour=None,
        background_colour=None,
        frame_colour=None,
        gap=None,
        screen=None,
        background_stimulus=None,
    ):
        """Create a text input box.

        Notes
        -----
        This stimulus is not optimized for timing accurate presentation!

        Parameters
        ----------
        message : str, optional
            message to show
        position : (int, int), optional
            position of the TextInput canvas
        length : int, optional
            the length of the text input frame in number of charaters
        ascii_filter : list, optional
            list of ASCII codes to filter for
        message_text_size : int, optional
            text size of the message
        message_colour : (int, int, int), optional
            text colour of the message
        message_font : str, optional
            text font of the message
        message_bold : bool, optional
            True if message text should be bold
        message_italic : bool, optional
            True if message text should be italic
        user_text_size : int, optional
            text size of the user input
        user_text_font : str, optional
            text font of the user input
        user_text_colour : (int, int ,int), optional
            text colour of the user input
        user_text_bold : bool, optional
            True if user text should be bold
        background_colour : (int, int, int), optional
        frame_colour : (int, int, int)
            colour of the frame
        gap : int, optional
            gap between message and user input
        screen : io.Screen, optional
            screen to present on
        background_stimulus : visual Expyriment stimulus, optional
            The background stimulus is a second stimulus that will be presented
            together with the TextInput. For both stimuli overlap TextInput
            will appear on top of the background_stimulus

        """

        if not expyriment._active_exp.is_initialized:
            raise RuntimeError("Cannot create TextInput before expyriment.initialize()!")
        Input.__init__(self)
        self._message = message
        if position is not None:
            self._position = position
        else:
            self._position = defaults.textinput_position
        if ascii_filter is not None:
            self._ascii_filter = ascii_filter
        else:
            self._ascii_filter = defaults.textinput_ascii_filter
        if length is not None:
            self._length = length
        else:
            self._length = defaults.textinput_length
        if message_text_size is None:
            message_text_size = defaults.textinput_message_text_size
        if message_text_size is not None:
            self._message_text_size = message_text_size
        else:
            self._message_text_size = expyriment._active_exp.text_size
        if message_colour is None:
            message_colour = defaults.textinput_message_colour
        if message_colour is not None:
            self._message_colour = message_colour
        else:
            self._message_colour = expyriment._active_exp.foreground_colour
        if message_font is None:
            message_font = defaults.textinput_message_font
        if message_font is not None:
            self._message_font = find_font(message_font)
        else:
            self._message_font = find_font(expyriment._active_exp.text_font)
        try:
            _font = pygame.font.Font(unicode2str(self._message_font, fse=True), 10)
        except:
            raise IOError("Font '{0}' not found!".format(message_font))
        if message_bold is not None:
            self._message_bold = message_bold
        else:
            self._message_bold = defaults.textinput_message_bold
        if message_italic is not None:
            self._message_italic = message_italic
        else:
            self._message_italic = defaults.textinput_message_italic
        if user_text_size is None:
            user_text_size = defaults.textinput_user_text_size
        if user_text_size is not None:
            self._user_text_size = user_text_size
        else:
            self._user_text_size = expyriment._active_exp.text_size

        if user_text_bold is not None:
            self._user_text_bold = user_text_bold
        else:
            self._user_text_bold = defaults.textinput_user_text_bold
        if user_text_font is None:
            user_text_font = defaults.textinput_user_text_font
        if user_text_font is not None:
            self._user_text_font = find_font(user_text_font)
        else:
            self._user_text_font = find_font(expyriment._active_exp.text_font)
        try:
            _font = pygame.font.Font(unicode2str(self._user_text_font, fse=True), 10)
        except:
            raise IOError("Font '{0}' not found!".format(user_text_font))
        if user_text_colour is None:
            user_text_colour = defaults.textinput_user_text_colour
        if user_text_colour is not None:
            self._user_text_colour = user_text_colour
        else:
            self._user_text_colour = expyriment._active_exp.foreground_colour
        if background_colour is None:
            background_colour = defaults.textinput_background_colour
        if background_colour is not None:
            self._background_colour = background_colour
        else:
            self._background_colour = expyriment._active_exp.background_colour
        if frame_colour is None:
            frame_colour = defaults.textinput_frame_colour
        if frame_colour is not None:
            self._frame_colour = frame_colour
        else:
            self._frame_colour = expyriment._active_exp.foreground_colour
        if gap is not None:
            self._gap = gap
        else:
            self._gap = defaults.textinput_gap
        if screen is not None:
            self._screen = screen
        else:
            self._screen = expyriment._active_exp.screen
        if background_stimulus is not None:
            # FIXME child of child of visual does not work as background stimulus, e.g. BlankScreen
            if background_stimulus.__class__.__base__ in [expyriment.stimuli._visual.Visual, expyriment.stimuli.Shape]:
                self._background_stimulus = background_stimulus
            else:
                raise TypeError(
                    "{0} ".format(type(background_stimulus))
                    + "is not a valid background stimulus. "
                    + "Use an expyriment visual stimulus."
                )
        else:
            self._background_stimulus = None

        self._user = []
        self._user_text_surface_size = None
        self._max_size = None
        self._message_surface_size = None
        self._canvas = None
        self._canvas_size = None