class ButtonStim(BaseShapeStim): """A class for putting a button into your experiment. """ def __init__(self, win, borderThickness=.003, labelSize=0.03, pos=(0, 0), labelText="text for button", textColor='blue', borderColor='blue', buttonColor='white', buttonEnabled=False, ): # local variables super(ButtonStim, self).__init__(win) button_width = len(labelText) * .025 button_x_inner_margin = .02 button_x_outer_margin = button_x_inner_margin + borderThickness button_y_inner_margin = labelSize button_y_outer_margin = labelSize + borderThickness button_x_range = (0 - button_width / 2 + pos[0], 0 + button_width / 2 + pos[0]) self.win = win self.borderThickness = borderThickness self.labelSize = labelSize self.pos = pos self.labelText = labelText self.textColor = textColor self.borderColor = borderColor self.buttonColor = buttonColor self.buttonEnabled = buttonEnabled self._dragging = False self.mouse = event.Mouse() self.buttonSelected = False self.buttonItems = [] self.buttonBorder = BaseShapeStim(self.win, fillColor=self.borderColor, vertices=( (button_x_range[0] - button_x_outer_margin, -button_y_outer_margin + self.pos[1]), (button_x_range[0] - button_x_outer_margin, button_y_outer_margin + self.pos[1]), (button_x_range[1] + button_x_outer_margin, button_y_outer_margin + self.pos[1]), (button_x_range[1] + button_x_outer_margin, -button_y_outer_margin + self.pos[1]))) self.buttonInner = BaseShapeStim(self.win, fillColor=self.buttonColor, vertices=( (button_x_range[0] - button_x_inner_margin, -button_y_inner_margin + self.pos[1]), (button_x_range[0] - button_x_inner_margin, button_y_inner_margin + self.pos[1]), (button_x_range[1] + button_x_inner_margin, button_y_inner_margin + self.pos[1]), (button_x_range[1] + button_x_inner_margin, -button_y_inner_margin + self.pos[1]))) self.buttonInnerText = TextStim(self.win, text=self.labelText, color=self.textColor, pos=self.pos, height=self.labelSize) self.buttonItems.append(self.buttonBorder) self.buttonItems.append(self.buttonInner) self.buttonItems.append(self.buttonInnerText) def draw(self): self.getMouseResponses() for item in self.buttonItems: item.draw() def buttonSwitch(self, switch): if switch: self.buttonBorder.color = self.buttonColor self.buttonInner.color = self.borderColor self.buttonInnerText.color = self.buttonColor else: self.buttonBorder.color = self.borderColor self.buttonInner.color = self.buttonColor self.buttonInnerText.color = self.borderColor def buttonContains(self, mouse): return self.buttonBorder.contains(mouse) def buttonClicked(self, mouse): self.buttonSelected = bool(self.buttonContains(mouse) and mouse.getPressed()[0]) return self.buttonSelected def buttonGuard(self, condition): if not self.buttonEnabled: self.buttonBorder.color = 'dimgrey' self.buttonInner.color = 'darkgrey' self.buttonInnerText.color = 'dimgrey' else: self.buttonBorder.color = self.buttonColor self.buttonInner.color = self.borderColor self.buttonInnerText.color = self.buttonColor def getMouseResponses(self): self.buttonGuard(self.buttonEnabled) if not self.buttonEnabled: return if not self.buttonClicked(self.mouse): # hovering self.buttonSwitch(self.buttonContains(self.mouse)) if self.buttonClicked(self.mouse): self._dragging = True # Update current but don't set Rating (mouse is still down) # Dragging has to start inside a "valid" area (i.e., on the # slider), but may continue even if the mouse moves away from # the slider, as long as the mouse button is not released. else: # mouse is up - check if it *just* came up if self._dragging: if self.buttonContains(self.mouse): self.buttonSelected = True self._dragging = False else: # is up and was already up - move along return None
class Button(BaseShapeStim): """A class for putting a button into your experiment. As of 18/9/2018 the only type of button available is "surveySubmit" See Coder Demos -> surveys -> aq_form.py for an example of a button used like this :Authors: - 2018: Anthony Haffey """ def __init__(self, win, border_thickness=.003, button_text_sz=0.03, buttonPos=(-.5, 0), buttonText="text for button", survey="", thisExp="", type="surveySubmit", **kwargs): #local variables button_width = len(buttonText) * .025 button_x_inner_margin = .02 button_x_outer_margin = button_x_inner_margin + border_thickness button_y_inner_margin = button_text_sz button_y_outer_margin = button_text_sz + border_thickness button_x_range = (0 - button_width / 2 + buttonPos[0], 0 + button_width / 2 + buttonPos[0]) self.thisExp = thisExp self._dragging = False self.survey = survey self.type = type # this needs to be dynamic self.mouse = event.Mouse() self.button_selected = False self.buttonItems = [] self.buttonColor = "blue" self.button_border = BaseShapeStim( win, fillColor="blue", vertices=((button_x_range[0] - button_x_outer_margin, -button_y_outer_margin + buttonPos[1]), (button_x_range[0] - button_x_outer_margin, button_y_outer_margin + buttonPos[1]), (button_x_range[1] + button_x_outer_margin, button_y_outer_margin + buttonPos[1]), (button_x_range[1] + button_x_outer_margin, -button_y_outer_margin + buttonPos[1]))) #edges=4 self.button_inner = BaseShapeStim( win, fillColor="white", vertices=((button_x_range[0] - button_x_inner_margin, -button_y_inner_margin + buttonPos[1]), (button_x_range[0] - button_x_inner_margin, button_y_inner_margin + buttonPos[1]), (button_x_range[1] + button_x_inner_margin, button_y_inner_margin + buttonPos[1]), (button_x_range[1] + button_x_inner_margin, -button_y_inner_margin + buttonPos[1]))) #edges=4 self.button_inner_text = visual.TextStim(win, text=buttonText, color="blue", pos=buttonPos, height=button_text_sz) self.buttonItems.append(self.button_border) self.buttonItems.append(self.button_inner) self.buttonItems.append(self.button_inner_text) def draw(self): self.getMouseResponses() for item in self.buttonItems: item.draw() ### This code has been used to change the color when a button is clicked on or hovered over. Been unable to implement without disrupting the form def getMouseResponses(self): click = bool(self.mouse.getPressed()[0]) #hover = bool(self.button_border.contains(self.mouse)) #if hover: if (self.button_selected == False): if self.button_border.contains(self.mouse): self.button_border.color = self.buttonColor self.button_inner.color = self.buttonColor self.button_inner_text.color = "white" else: self.button_border.color = self.buttonColor self.button_inner.color = "white" self.button_inner_text.color = self.buttonColor else: if self.button_border.contains(self.mouse): self.button_border.color = self.buttonColor self.button_inner.color = "white" self.button_inner_text.color = self.buttonColor else: self.button_border.color = self.buttonColor self.button_inner.color = self.buttonColor self.button_inner_text.color = "white" if click: self._dragging = True # Update current but don't set Rating (mouse is still down) # Dragging has to start inside a "valid" area (i.e., on the # slider), but may continue even if the mouse moves away from # the slider, as long as the mouse button is not released. else: # mouse is up - check if it *just* came up if self._dragging: if self.type == "surveySubmit": if self.button_border.contains(self.mouse): itemsFailed = surveys.saveScores( self.survey, self.thisExp) if len(itemsFailed) > 0: self.buttonColor = "red" elif self.type == "surveyItem": print("Will code what to do with you later") if self.button_border.contains(self.mouse): if (self.button_selected == True): self.button_selected = False else: self.button_selected = True self._dragging = False else: # is up and was already up - move along return None