示例#1
0
    def wait(self, codes=None, duration=None, no_clear_buffer=False,
             bitwise_comparison=False, check_for_control_keys=True):
        """Wait for responses defined as codes.

        Notes
        -----
        If bitwise_comparision = True, the function performs a bitwise
        comparison (logical and) between codes and received input and waits
        until a certain bit pattern is set.

        This will also by default check for control keys (quit and pause).
        Thus, keyboard events will be cleared from the cue and cannot be
        received by a Keyboard().check() anymore!

        Parameters
        ----------
        codes : int or list, optional
            bit pattern to wait for
            if codes is not set (None) the function returns for any
            event that differs from the baseline
        duration : int, optional
            maximal time to wait in ms
        no_clear_buffer : bool, optional
            do not clear the buffer (default = False)
        bitwise_comparison : bool, optional
            make a bitwise comparison (default = False)
        check_for_control_keys : bool, optional
            checks if control key has been pressed (default=True)

        Returns
        -------
        key : int
            key code (or None) that quitted waiting
        rt : int
            reaction time

        """

        start = Clock._cpu_time()
        rt = None
        if not no_clear_buffer:
            self.clear()
        while True:
            expyriment._active_exp._execute_wait_callback()
            if duration is not None:
                if int((Clock._cpu_time() - start) * 1000) > duration:
                    return None, None
            found = self.check(codes, bitwise_comparison)
            if found is not None:
                rt = int((Clock._cpu_time() - start) * 1000)
                break
            if check_for_control_keys:
                if Keyboard.process_control_keys():
                    break
        if self._logging:
            expyriment._active_exp._event_file_log(
                                "{0},received,{1},wait".format(
                                                self.__class__.__name__,
                                                found))
        return found, rt
示例#2
0
    def wait_press(self, buttons=None, duration=None):
        """Wait for gamepad button press.

        Returns the found button and the reaction time.

        Parameters
        ----------
        buttons : int or list, optional
            specific buttons to wait for
        duration : int, optional
            maximal time to wait in ms

        Returns
        -------
        button : int
            button _id of the pressed button
        rt : int
            reaction time in ms

        """

        start = get_time()
        rt = None
        _button = None
        self.clear()
        if buttons is None:
            buttons = range(self.get_numbuttons())
        if type(buttons) is not list:
            buttons = [buttons]
        done = False
        while not done:
            expyriment._active_exp._execute_wait_callback()
            for button in buttons:
                if self.get_button(button):
                    _button = button
                    rt = int((get_time() - start) * 1000)
                    done = True
                    break
                if _button is not None or Keyboard.process_control_keys():
                    done = True
                    break
                if duration:
                    if int((get_time() - start) * 1000) >= duration:
                        done = True
                        break

            time.sleep(0.0005)

        if self._logging:
            expyriment._active_exp._event_file_log(
                            "Gamepad,received,{0},wait_press".format(_button))
        return _button, rt
示例#3
0
    def wait(self, code=None, bitwise_comparison=False):
        """Wait for a trigger.

        Returns the code received and the reaction time [code, rt].

        If bitwise_comparison = True, the function performs a bitwise
        comparison (logical and) between code and received input and waits
        until a certain bit pattern is set.

        Parameters
        code -- a specific code to wait for (int) (optional)
        bitwise_comparison -- make a bitwise comparison (default=False)

        See Also
        --------
        design.experiment.register_wait_callback_function

       """

        if expyriment.control.defaults._skip_wait_functions:
            return None, None
        start = get_time()
        found = None
        rt = None
        if code is None:
            code = self._default_code
        self.interface.clear()
        while True:
            rtn_callback = expyriment._active_exp._execute_wait_callback()
            if isinstance(rtn_callback, expyriment.control.CallbackQuitEvent):
                return rtn_callback, int((get_time() - start) * 1000)
            read = self.interface.poll()
            if read is not None:
                if code is None:  #return for every event
                    rt = int((get_time() - start) * 1000)
                    found = read
                    break
                elif compare_codes(read, code, bitwise_comparison):
                    rt = int((get_time() - start) * 1000)
                    found = read
                    break
            if Keyboard.process_control_keys():
                break
        if self._logging:
            expyriment._active_exp._event_file_log(
                "TriggerInput,received,{0},wait".format(found))
        return found, rt
示例#4
0
    def wait(self, code=None, bitwise_comparison=False):
        """Wait for a trigger.

        Returns the code received and the reaction time [code, rt].

        If bitwise_comparison = True, the function performs a bitwise
        comparison (logical and) between code and received input and waits
        until a certain bit pattern is set.

        Parameters
        code -- a specific code to wait for (int) (optional)
        bitwise_comparison -- make a bitwise comparison (default=False)

        See Also
        --------
        design.experiment.register_wait_callback_function

       """

        if expyriment.control.defaults._skip_wait_functions:
            return None, None
        start = get_time()
        found = None
        rt = None
        if code is None:
            code = self._default_code
        self.interface.clear()
        while True:
            rtn_callback = expyriment._active_exp._execute_wait_callback()
            if isinstance(rtn_callback, expyriment.control.CallbackQuitEvent):
                return rtn_callback, int((get_time() - start) * 1000)
            read = self.interface.poll()
            if read is not None:
                if code is None:  # return for every event
                    rt = int((get_time() - start) * 1000)
                    found = read
                    break
                elif compare_codes(read, code, bitwise_comparison):
                    rt = int((get_time() - start) * 1000)
                    found = read
                    break
            if Keyboard.process_control_keys():
                break
        if self._logging:
            expyriment._active_exp._event_file_log("TriggerInput,received,{0},wait".format(found))
        return found, rt
示例#5
0
    def wait_press(self, buttons=None, duration=None):
        """Wait for gamepad button press.

        Returns the found button and the reaction time.

        Parameters
        ----------
        buttons : int or list, optional
            specific buttons to wait for
        duration : int, optional
            maximal time to wait in ms

        Returns
        -------
        button : int
            button _id of the pressed button
        rt : int
            reaction time in ms

        See Also
        --------
        design.experiment.register_wait_callback_function

        """

        if expyriment.control.defaults._skip_wait_functions:
            return None, None
        start = get_time()
        rt = None
        _button = None
        self.clear()
        if buttons is None:
            buttons = range(self.get_numbuttons())
        try:
            buttons = list(buttons)
        except:
            buttons = [buttons]
        done = False
        while not done:
            rtn_callback = expyriment._active_exp._execute_wait_callback()
            if isinstance(rtn_callback, expyriment.control.CallbackQuitEvent):
                _button = rtn_callback
                rt = int((get_time() - start) * 1000)
                done = True

            for button in buttons:
                if self.get_button(button):
                    _button = button
                    rt = int((get_time() - start) * 1000)
                    done = True
                    break
                if _button is not None or Keyboard.process_control_keys():
                    done = True
                    break
                if duration:
                    if int((get_time() - start) * 1000) >= duration:
                        done = True
                        break

            time.sleep(0.0005)

        if self._logging:
            expyriment._active_exp._event_file_log(
                "Gamepad,received,{0},wait_press".format(_button))
        return _button, rt
示例#6
0
    def process_quit_event(click_position=None):
        """Check if mouse exit action has been performed

        If Mouse.quit_rect_location is defined (i.e. 0, 1, 2 or 3), clicking
        quickly three times (i.e., within 1 second) in one of the corners of
        the screen forces the experiment to quit.

        The function is called automatically by all mouse get event and wait
        methods (similar to Keyboard.process_control_keys).  If no mouse
        functions are called by your program, this function can be polled to
        ensure quitting experiment by mouse.

        Mouse quit events are especially useful for experiments on devices
        without hardware keyboard, such as tablet PCs or smartphones.

        Parameters
        ----------
        click_position : tuple of int (x,y), optional
            clicked location to be processed. If not defined, the Pygame event
            queue will be checked for mouse down events and the current
            position is taken

        Returns
        -------
        out : bool, optional
            True if exit action has been performed
            False otherwise

        Notes
        -----
        To switch on or off the detection of mouse quit events, please use the
        static class property `quit_rect_location' (see below).

        The detection of mouse quit events is activated by default under
        Android.

        Static class properties
        ~~~~~~~~~~~~~~~~~~~~~~~

        `Mouse.quit_rect_location` = int, optional
            Location of the quit click action field or None.

            0 = upper left corner,  1 = upper right corner   (0) (1)
            2 = lower right corner, 3 = lower left corner    (3) (2)
            otherwise the detection of mouse quit events is deactivated.

            Default value under Android is 1, otherwise  None

        `Mouse.quit_click_rect_size` : tuple (int, int)
            size of the field (rect) that detects the quit action by
            triple clicking in one corner of the screen. (default = (30, 30))

        Changing the static class properties affects always all mouse
        instances.

        """

        if Mouse.quit_rect_location not in [0,1,2,3] or \
            expyriment._active_exp is None:
            return False

        if click_position is None:
            # check Pygame queu
            pos = None
            pygame.event.pump()
            screen_size = expyriment._active_exp.screen.surface.get_size()
            for event in pygame.event.get(pygame.MOUSEBUTTONDOWN):
                if event.button > 0:
                    pos = pygame.mouse.get_pos()
                    pos = (pos[0] - screen_size[0] / 2,
                          -pos[1] + screen_size[1] / 2)
                    break
            if pos is None:
                return False
            else:
                return Mouse.process_quit_event(click_position=pos)

        # determine threshold x & y
        if Mouse.quit_rect_location == 0 or Mouse.quit_rect_location == 3: # left
            threshold_x = -expyriment._active_exp.screen.center_x + \
                    Mouse.quit_click_rect_size[0]
        else:# right
            threshold_x = expyriment._active_exp.screen.center_x - \
                    Mouse.quit_click_rect_size[0]
        if Mouse.quit_rect_location == 0 or Mouse.quit_rect_location == 1: # upper
            threshold_y = expyriment._active_exp.screen.center_y - \
                    Mouse.quit_click_rect_size[1]
        else:# lower
            threshold_y = -expyriment._active_exp.screen.center_y + \
                    Mouse.quit_click_rect_size[1]
        # check
        if (Mouse.quit_rect_location == 0 and \
                click_position[0] < threshold_x and\
                click_position[1] > threshold_y) \
           or (Mouse.quit_rect_location == 1 and \
                click_position[0] > threshold_x and \
                click_position[1] > threshold_y) \
           or (Mouse.quit_rect_location == 2 and \
                click_position[0] > threshold_x and \
                click_position[1] < threshold_y) \
           or (Mouse.quit_rect_location == 3 and \
                click_position[0] < threshold_x and \
                click_position[1] < threshold_y):

            Mouse._quit_action_events.append(get_time())
            if len(Mouse._quit_action_events)>=3:
                diff = get_time()-Mouse._quit_action_events.pop(0)
                if (diff < 1):
                    # simulate quit key
                    simulated_key = pygame.event.Event(pygame.KEYDOWN,\
                                {'key': Keyboard.get_quit_key()})
                    return Keyboard.process_control_keys(
                        key_event=simulated_key)
        return False
示例#7
0
    def wait_event(self, wait_button=True, wait_motion=True, buttons=None,
                   duration=None, wait_for_buttonup=False):
        """Wait for a mouse event (i.e., motion, button press or wheel event)

        Parameters
        ----------
        wait_button : bool, optional
            set 'False' to ignore for a button presses (default=True)
        wait_motion : bool, optional
            set 'False' to ignore for a mouse motions (default=True)
        buttons : int or list, optional
            a specific button or list of buttons to wait for
        duration : int, optional
            the maximal time to wait in ms
        wait_for_buttonup : bool, optional
            if True it waits for button-up default=False)

        Returns
        -------
        event_id : int
            id of the event that quited waiting
        move : bool
            True if a motion occured
        pos : (int, int)
            mouse position (tuple)
        rt : int
            reaction time

        Notes
        ------
        button id coding

        - None    for no mouse button event or
        - 0,1,2   for left. middle and right button or
        - 3       for wheel up or
        - 4       for wheel down (wheel works only for keydown events).

        See Also
        --------
        design.experiment.register_wait_callback_function

        """

        if expyriment.control.defaults._skip_wait_functions:
            return None, None, None, None
        start = get_time()
        self.clear()
        old_pos = pygame.mouse.get_pos()
        btn_id = None
        rt = None
        motion_occured = False
        if buttons is None:
            buttons = [0, 1, 2, 3, 4]
        else:
            try:
                buttons = list(buttons)
            except:
                buttons = [buttons]
        while True:
            rtn_callback = expyriment._active_exp._execute_wait_callback()
            if isinstance(rtn_callback, expyriment.control.CallbackQuitEvent):
                btn_id = rtn_callback
                rt = int((get_time() - start) * 1000)
                break
            if wait_motion:
                motion_occured = old_pos != pygame.mouse.get_pos()
            if wait_button:
                if wait_for_buttonup:
                    btn_id = self.get_last_button_up_event()
                else:
                    btn_id = self.get_last_button_down_event()
            if btn_id ==-1:
                btn_id = None
                break
            elif btn_id in buttons or motion_occured:
                rt = int((get_time() - start) * 1000)
                break
            elif Keyboard.process_control_keys() or (duration is not None and \
                    int((get_time() - start) * 1000) >= duration):
                break

        position_in_expy_coordinates = self.position

        if self._logging:
            expyriment._active_exp._event_file_log(
            "Mouse,received,{0}-{1},wait_event".format(btn_id, motion_occured))
        return btn_id, motion_occured, position_in_expy_coordinates, rt
示例#8
0
    def wait(self,
             codes=None,
             duration=None,
             no_clear_buffer=False,
             bitwise_comparison=False,
             check_for_control_keys=True):
        """Wait for responses defined as codes.

        Notes
        -----
        If bitwise_comparision = True, the function performs a bitwise
        comparison (logical and) between codes and received input and waits
        until a certain bit pattern is set.

        This will also by default check for control keys (quit and pause).
        Thus, keyboard events will be cleared from the cue and cannot be
        received by a Keyboard().check() anymore!

        Parameters
        ----------
        codes : int or list, optional
            bit pattern to wait for
            if codes is not set (None) the function returns for any
            event that differs from the baseline
        duration : int, optional
            maximal time to wait in ms
        no_clear_buffer : bool, optional
            do not clear the buffer (default = False)
        bitwise_comparison : bool, optional
            make a bitwise comparison (default = False)
        check_for_control_keys : bool, optional
            checks if control key has been pressed (default=True)

        Returns
        -------
        key : int
            key code (or None) that quitted waiting
        rt : int
            reaction time

        See Also
        --------
        design.experiment.register_wait_callback_function

        """

        if expyriment.control.defaults._skip_wait_functions:
            return None, None
        start = get_time()
        rt = None
        if not no_clear_buffer:
            self.clear()
        while True:
            rtn_callback = expyriment._active_exp._execute_wait_callback()
            if isinstance(rtn_callback, expyriment.control.CallbackQuitEvent):
                found = rtn_callback
                rt = int((get_time() - start) * 1000)
                break
            if duration is not None:
                if int((get_time() - start) * 1000) > duration:
                    return None, None
            found = self.check(codes, bitwise_comparison)
            if found is not None:
                rt = int((get_time() - start) * 1000)
                break
            if check_for_control_keys:
                if Keyboard.process_control_keys():
                    break
        if self._logging:
            expyriment._active_exp._event_file_log(
                "{0},received,{1},wait".format(self.__class__.__name__, found))
        return found, rt
示例#9
0
    def wait_press(self, buttons=None, duration=None):
        """Wait for gamepad button press.

        Returns the found button and the reaction time.

        Parameters
        ----------
        buttons : int or list, optional
            specific buttons to wait for
        duration : int, optional
            maximal time to wait in ms

        Returns
        -------
        button : int
            button _id of the pressed button
        rt : int
            reaction time in ms

        See Also
        --------
        design.experiment.register_wait_callback_function

        """

        if expyriment.control.defaults._skip_wait_functions:
            return None, None
        start = get_time()
        rt = None
        _button = None
        self.clear()
        if buttons is None:
            buttons = range(self.get_numbuttons())
        try:
            buttons = list(buttons)
        except:
            buttons = [buttons]
        done = False
        while not done:
            rtn_callback = expyriment._active_exp._execute_wait_callback()
            if isinstance(rtn_callback, expyriment.control.CallbackQuitEvent):
                _button = rtn_callback
                rt = int((get_time() - start) * 1000)
                done = True

            for button in buttons:
                if self.get_button(button):
                    _button = button
                    rt = int((get_time() - start) * 1000)
                    done = True
                    break
                if _button is not None or Keyboard.process_control_keys():
                    done = True
                    break
                if duration:
                    if int((get_time() - start) * 1000) >= duration:
                        done = True
                        break

            time.sleep(0.0005)

        if self._logging:
            expyriment._active_exp._event_file_log(
                            "Gamepad,received,{0},wait_press".format(_button))
        return _button, rt
示例#10
0
    def get(self, preselected_item=0):
        """Present the menu and return the selected item.

        Parameters
        ----------
        preselected_item : int, optional
            item that is preselected when showing menu

        Returns
        -------
        selected : int
            integer representing the selected item in the list

        """

        selected = preselected_item
        # Keyboard
        if self._mouse is None:
            while True:
                self._redraw(selected)
                key = Keyboard().wait()[0]
                if key == expyriment.misc.constants.K_UP:
                    selected -= 1
                elif key == expyriment.misc.constants.K_DOWN:
                    selected += 1
                elif key in expyriment.misc.constants.K_ALL_DIGITS and\
                        key > expyriment.misc.constants.K_0:
                    selected = key - expyriment.misc.constants.K_1
                elif key == expyriment.misc.constants.K_RETURN:
                    break
                if selected < 0:
                    selected = 0
                elif selected >= len(self._menu_items):
                    selected = len(self._menu_items) - 1
            return selected
        # Mouse
        else:
            pressed = None
            while True:
                pressed = None
                self._redraw(selected)
                event, pos, rt = self._mouse.wait_press()
                if self._scroll_menu == 0:
                    for cnt in range(len(self._menu_items)):
                        if 0 <= cnt < len(self._menu_items):
                            if self._menu_items[cnt].overlapping_with_position(
                                    pos):
                                pressed = cnt
                else:
                    for cnt in range(selected - self._scroll_menu / 2,
                                     selected + 1 + self._scroll_menu / 2):
                        if 0 <= cnt < len(self._menu_items):
                            if self._menu_items[cnt].overlapping_with_position(
                                    pos):
                                pressed = cnt
                if pressed is not None:
                    if pressed == selected:
                        break
                    else:
                        selected = pressed
            return self._original_items[pressed]