def _gen_inst_objects( self ) -> typing.Tuple[visual.ImageStim, visual.ImageStim, visual.ImageStim]: """Draw the instructions slide and matching confirmation button. """ inst_img = visual.ImageStim(win=self.win, size=self.win.size, units='pix') inst_confirm_button = Rect(win=self.win, units='pix', size=self.win.size * params.INST_ACCEPT_BUTTON_SIZE, lineColor=None) return inst_img, inst_confirm_button
def test_elements(self): s = Slider(self.win, size=(1, 0.1)) assert type(s.line) == type(GratingStim(self.win)) assert type(s.tickLines) == type(ElementArrayStim(self.win)) assert type(s.marker) == type(Circle(self.win)) assert type(s.validArea) == type(Rect(self.win))
def _initialize_elements(self, win, stimulus_a, stimulus_b): stimulus_a.pos = (0, -stimulus_a.size[0] / 2 - 90) stimulus_b.pos = (0, +stimulus_b.size[0] / 2 + 90) self.stimulus_a = stimulus_a self.stimulus_b = stimulus_b self._elements.append(stimulus_a) self._elements.append(stimulus_b) # create arrows for confidence rating # create vertices for the arrow arrow_shape_vertices = [ (0, 0), (230, 0), (220, 8), (230, 0), (220, -8), ] self.arrow_a_shape = ShapeStim( win, vertices=arrow_shape_vertices, size=1, lineColor="black", lineWidth=3, closeShape=False, pos=(-112, 25), ) self.arrow_b_shape = ShapeStim( win, vertices=arrow_shape_vertices, size=1, lineColor="black", lineWidth=3, closeShape=False, pos=(-112, -25), ) self._elements.append(self.arrow_a_shape) # hide the rectangles until they are needed (opacity=0) self.choice_text_rectangle = Rect(win, 40, 40, lineWidth=5, lineColor="black", opacity=0.0) self.choice_stimulus_rectangle = Rect( win, stimulus_a.size[1], stimulus_a.size[0], lineWidth=5, lineColor="black", opacity=0.0, ) self.correct_rectangle = Rect( win, stimulus_a.size[1] + 7.5, stimulus_a.size[0] + 7.5, lineWidth=5, lineColor="green", opacity=0.0, ) self._elements.append(self.choice_text_rectangle) self._elements.append(self.choice_stimulus_rectangle) self._elements.append(self.correct_rectangle) self.arrow_a_text = TextStim( win, text="More confident", color="black", height=25, anchorHoriz="center", alignText="center", pos=(0, +0), ) self.arrow_b_text = self.arrow_a_text self._elements.append(self.arrow_a_text) self.arrow_levels_text: List[TextStim] = [] arrow_levels_values = [1, 2, 3, -1, -2, -3] arrow_levels_texts = [ str(x) if x > 0 else str(-x) for x in arrow_levels_values ] arrow_levels_positions = [(-100, 60), (0, 60), (+100, 60), (-100, -60), (0, -60), (+100, -60)] for (position_x, position_y), text, value in zip(arrow_levels_positions, arrow_levels_texts, arrow_levels_values): item = TextStim(win, text=text, color="black", height=25, pos=(position_x, position_y)) rect = Rect(win, width=25, height=25, lineWidth=0.0, pos=(position_x, position_y)) item.value = value item.clickable_area = rect self.arrow_levels_text.append(item) self._elements.append(item) self._elements.append(rect)
def __init__( self, win, text='Hello World', pos=(0.0, 0.0), width=None, height=None, padx=2, pady=2, units="", checked=False, name=None, autoLog=None, autoDraw=False, ): """ Button accepts all input parameters, that `~psychopy.visual.BaseVisualStim` accept, except for vertices and closeShape. :Parameters: width : int or float Width of the Rectangle (in its respective units, if specified) height : int or float Height of the Rectangle (in its respective units, if specified) """ # what local vars are defined (these are the init params) for use by # __repr__ self._initParams = dir() self._initParams.remove('self') super(Button, self).__init__(win, units=units, name=name, autoLog=False) self.__dict__['pos'] = pos self.__dict__['text'] = text self.textStim = TextStim(win, text=text, pos=self.pos, wrapWidth=width, color='Black', units=units, autoLog=autoLog) # TODO: expose content_width via TextStim autoWidth = (self.textStim._pygletTextObj._layout.content_width + 2 * padx) autoHeight = self.textStim.height + 2 * pady if width is not None and width > autoWidth: self.__dict__['width'] = width else: self.__dict__['width'] = autoWidth if height is not None and height > autoHeight: self.__dict__['height'] = height else: self.__dict__['height'] = autoHeight self.rectStim = Rect(win, pos=self.pos, width=self.width, height=self.height, units=units, autoLog=autoLog) self.normalStyle = ButtonStyle() self.checkedStyle = ButtonStyle(fillColor='#2E2EFE', borderColor='White', textColor='White') self.checked = checked # this will set style self.autoDraw = autoDraw self.__dict__['autoLog'] = (autoLog or autoLog is None and self.win.autoLog) if self.autoLog: logging.exp("Created %s = %s" % (self.name, str(self)))
class Button(BaseVisualStim): """Creates a button of given width and height, by combining a TextStim and a Rect (New in version 1.80.99 FIXME) """ def __init__( self, win, text='Hello World', pos=(0.0, 0.0), width=None, height=None, padx=2, pady=2, units="", checked=False, name=None, autoLog=None, autoDraw=False, ): """ Button accepts all input parameters, that `~psychopy.visual.BaseVisualStim` accept, except for vertices and closeShape. :Parameters: width : int or float Width of the Rectangle (in its respective units, if specified) height : int or float Height of the Rectangle (in its respective units, if specified) """ # what local vars are defined (these are the init params) for use by # __repr__ self._initParams = dir() self._initParams.remove('self') super(Button, self).__init__(win, units=units, name=name, autoLog=False) self.__dict__['pos'] = pos self.__dict__['text'] = text self.textStim = TextStim(win, text=text, pos=self.pos, wrapWidth=width, color='Black', units=units, autoLog=autoLog) # TODO: expose content_width via TextStim autoWidth = (self.textStim._pygletTextObj._layout.content_width + 2 * padx) autoHeight = self.textStim.height + 2 * pady if width is not None and width > autoWidth: self.__dict__['width'] = width else: self.__dict__['width'] = autoWidth if height is not None and height > autoHeight: self.__dict__['height'] = height else: self.__dict__['height'] = autoHeight self.rectStim = Rect(win, pos=self.pos, width=self.width, height=self.height, units=units, autoLog=autoLog) self.normalStyle = ButtonStyle() self.checkedStyle = ButtonStyle(fillColor='#2E2EFE', borderColor='White', textColor='White') self.checked = checked # this will set style self.autoDraw = autoDraw self.__dict__['autoLog'] = (autoLog or autoLog is None and self.win.autoLog) if self.autoLog: logging.exp("Created %s = %s" % (self.name, str(self))) def _setStyle(self, style): self.rectStim.lineColor = style.borderColor self.rectStim.fillColor = style.fillColor self.textStim.color = style.textColor @attributeSetter def text(self, value): """Changes the text of the Button""" self.__dict__['text'] = value # TODO: change this to attributeSetters with 1.80.99 self.textStim.setText(value) @attributeSetter def pos(self, value): """Changes the position of the Button""" self.__dict__['pos'] = value self.rectStim.pos = value self.textStim.pos = value @attributeSetter def width(self, value): """Changes the width of the Button""" self.__dict__['width'] = value # TODO: change this to attributeSetters with 1.80.99 self.rectStim.setWidth(value) # this won't work, need to construct new or wait for 1.80.99 self.textStim.wrapWidth = value @attributeSetter def height(self, value): """Changes the height of the Button""" self.__dict__['height'] = value # TODO: change this to attributeSetters with 1.80.99 self.rectStim.setHeight(value) # don't set height of text as it will change font size # self.textStim.setHeight(value) @attributeSetter def checked(self, value): self.__dict__['checked'] = value if self.checked: self._setStyle(self.checkedStyle) else: self._setStyle(self.normalStyle) def setColor(self, color, colorSpace=None, operation=''): """For Button use :meth:`~Button.fillColor` or :meth:`~Button.borderColor` or :meth:`~Button.textColor` """ raise AttributeError('Button does not support setColor method.' 'Please use fillColor, borderColor, or textColor') def contains(self, x, y=None, units=None): return self.rectStim.contains(x, y, units) def draw(self, win=None): """ Draw the stimulus in its relevant window. You must call this method after every MyWin.flip() if you want the stimulus to appear on that frame and then update the screen again. If win is specified then override the normal window of this stimulus. """ if win is None: win = self.win self.rectStim.draw(win) self.textStim.draw(win)
# calculate area of interest if stimulus.chars_of_interest is not None: coi_start = stimulus.chars_of_interest[0] coi_end = stimulus.chars_of_interest[1] aoi_top_left = textbox.verticesPix[coi_start * 4 + 1] + (-7, -15) aoi_bottom_right = textbox.verticesPix[coi_end * 4 - 1] + (7, 15) aoi_width = aoi_bottom_right[0] - aoi_top_left[0] aoi_height = aoi_bottom_right[1] - aoi_top_left[1] aoi_center = (aoi_top_left + aoi_bottom_right) / 2 # visualize area of interest aoi_rect = Rect( pygaze.expdisplay, width=aoi_width, height=aoi_height, pos=aoi_center, fillColor="red", ) # only show the AOI in red when in Dummy (debug) mode if constants.DUMMYMODE: stimulus_screen.screen.append(aoi_rect) disp_center = np.array(constants.DISPSIZE) / 2 aoi = AOI("rectangle", tuple(aoi_top_left + disp_center), (aoi_width, aoi_height)) else: aoi = None stimulus_screen.screen.append(textbox) # draw "irrelevant" fixation point