def test_color(self): colors = [['red', 'blue', 'yellow'], ['blue', 'yellow', 'red'], ['yellow', 'red', 'blue']] for color in colors: s = Slider(self.win, color=color[0], fillColor=color[1], borderColor=color[2]) for l in s.labelObjs: assert l._foreColor == Color(color[0], s.colorSpace) assert s.marker._fillColor == Color(color[1], s.colorSpace) assert s.line._foreColor == Color(color[2], s.colorSpace) assert s.tickLines._colors == Color(color[2], s.colorSpace)
def test_color(self): colors = ['black', 'red'] for color in colors: s = Slider(self.win, color=color) assert s.line._foreColor == Color(color, s.colorSpace) assert s.tickLines._colors == Color(color, s.colorSpace) for l in s.labelObjs: assert l.color == color
def setFillRGB(self, value, operation=''): """DEPRECATED since v1.60.05: Please use :meth:`~ShapeStim.fillColor` """ if operation in ['', '=']: self.fillColor = Color(value, 'rgb255') elif operation in ['+']: self._fillColor += Color(value, 'rgb255') elif operation in ['-']: self._fillColor -= Color(value, 'rgb255') else: logging.error(f"Operation '{operation}' not recognised.")
def __init__(self, parent): wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Color Picker", pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE) # Set main params self.color = Color((0,0,0,1), 'rgba') self.sizer = wx.GridBagSizer() # Add colourful top bar self.preview = ColorPreview(color=self.color, parent=self) self.sizer.Add(self.preview, pos=(0,0), span=wx.GBSpan(2,1), border=5, flag=wx.RIGHT | wx.EXPAND) # Add notebook of controls self.ctrls = aui.AuiNotebook(self, wx.ID_ANY, size=wx.Size(400, 400)) self.sizer.Add(self.ctrls, pos=(0,1), border=5, flag=wx.ALL) self.ctrls.AddPage(ColorPage(self.ctrls, self, 'rgba'), 'RGB (-1 to 1)') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'rgba1'), 'RGB (0 to 1)') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'rgba255'), 'RGB (0 to 255)') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'hsva'), 'HSV') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'hex'), 'Hex') # Add array of named colours self.presets = ColorPresets(parent=self) self.sizer.Add(self.presets, pos=(0,2), border=5, flag=wx.ALL) # Add buttons self.buttons = wx.BoxSizer(wx.HORIZONTAL) self.closeButton = wx.Button(self, label="Close") self.closeButton.Bind(wx.EVT_BUTTON, self.Close) self.buttons.Add(self.closeButton, border=5, flag=wx.ALL) # Add insert buttons # self.insertValueButton = wx.Button(self, label="Insert As Value") # self.insertValueButton.Bind(wx.EVT_BUTTON, self.insertValue) # self.buttons.Add(self.insertValueButton, border=5, flag=wx.ALL) # self.insertObjectButton = wx.Button(self, label="Insert As Object") # self.insertObjectButton.Bind(wx.EVT_BUTTON, self.insertObject) # self.buttons.Add(self.insertObjectButton, border=5, flag=wx.ALL) # Add copy buttons self.copyValueButton = wx.Button(self, label="Copy As Value") self.copyValueButton.Bind(wx.EVT_BUTTON, self.copyValue) self.buttons.Add(self.copyValueButton, border=5, flag=wx.ALL) self.copyObjectButton = wx.Button(self, label="Copy As Object") self.copyObjectButton.Bind(wx.EVT_BUTTON, self.copyObject) self.buttons.Add(self.copyObjectButton, border=5, flag=wx.ALL) self.sizer.Add(self.buttons, pos=(1,1), span=wx.GBSpan(1,2), border=5, flag=wx.ALL | wx.ALIGN_RIGHT) # Configure sizer self.sizer.AddGrowableRow(0) self.sizer.AddGrowableCol(1) self.SetSizerAndFit(self.sizer) self._applyAppTheme() self._applyAppTheme(self.ctrls) self.Layout() self.Centre(wx.BOTH) self.Show(True)
def test_ColorSets(): for colorSet in sets: # Construct matrix of space pairs spaceMatrix = [] for space1 in colorSet: spaceMatrix.extend([[space1, space2] for space2 in colorSet if space2 != space1]) # Compare each space pair for consistency for space1, space2 in spaceMatrix: col1 = Color(colorSet[space1], space1) col2 = Color(colorSet[space2], space2) closeEnough = all( abs(col1.rgba[i] - col2.rgba[i]) < 0.02 for i in range(4)) # Check setters assert col1 == col2 or closeEnough
def _createColorButtons(self): """Generate color buttons based on the presets defined in the `colors` module. When a user clicks on the buttons, it changes the current color the colorspace page is displaying. """ # create buttons for each preset color colorList = list(colorNames) btnSize = wx.Size(120, 24) for color in colorList: btn = GenButton(self, size=btnSize, label=color, name=color) btn.colorData = col = Color(color, 'named') btn.SetOwnBackgroundColour(col.rgba255) # Compute the (perceived) luminance of the color, used to set the # foreground text to ensure it's legible on the background. Uses the # the luminance part of formula to convert RGB1 to YIQ. luminance = np.sum(np.asarray((0.299, 0.587, 0.114)) * col.rgb1) if luminance < 0.5: btn.SetForegroundColour(wx.WHITE) else: btn.SetForegroundColour(wx.BLACK) btn.SetBezelWidth(0) btn.SetUseFocusIndicator(False) btn.Bind(wx.EVT_BUTTON, self.onClick) self.sizer.Add(btn, 1, wx.ALL | wx.EXPAND, 0)
def color(self, value): if value is None: value = Color((0., 0., 0., 1.), space='rgba') self._color = value self.updateRGBPage() self.updateHSVPage() self.updateDialog()
def onChange(self, event): if self.space in Color.getSpace(event.String, True): self.SetStyle(0, len(event.String), wx.TextAttr(wx.Colour((0, 0, 0)))) self.parent.dlg.setColor(event.String, self.space) else: self.SetStyle(0, len(event.String), wx.TextAttr(wx.Colour((255, 0, 0))))
def color(self, value): if value is None: value = Color('none', space='named') global LAST_COLOR self.pnlColorPreview.color = self._color = value LAST_COLOR = self._color.copy() self._updateColorSpacePage()
def OnPresetSelect(self, event): """Called when the user selects a preset from the list. """ idxSelection = self.lstColorPresets.GetSelection() if idxSelection == -1: # event occurred with no valid selection event.Skip() presetColorKey = self.lstColorPresets.GetString(idxSelection) presetColor = Color(colorNames[presetColorKey], space='rgb') self.color = presetColor
def _createStim(self): """ outer_diameter: 35 outer_stroke_width: 5 outer_fill_color: [255,255,255] outer_line_color: [255,255,255] inner_diameter: 5 inner_stroke_width: 0 inner_color: [0,0,0] inner_fill_color: [0,0,0] inner_line_color: [0,0,0] calibration_prefs=self._eyetracker.getConfiguration()['calibration']['target_attributes'] """ color_type = self.getCalibSetting('color_type') unit_type = self.getCalibSetting('unit_type') self.calibrationPoint = visual.TargetStim( self.window, name="CP", style="circles", radius=self.getCalibSetting(['target_attributes', 'outer_diameter']) / 2.0, fillColor=self.getCalibSetting(['target_attributes', 'outer_fill_color']), borderColor=self.getCalibSetting(['target_attributes', 'outer_line_color']), lineWidth=self.getCalibSetting(['target_attributes', 'outer_stroke_width']), innerRadius=self.getCalibSetting(['target_attributes', 'inner_diameter']) / 2.0, innerFillColor=self.getCalibSetting(['target_attributes', 'inner_fill_color']), innerBorderColor=self.getCalibSetting(['target_attributes', 'inner_line_color']), innerLineWidth=self.getCalibSetting(['target_attributes', 'inner_stroke_width']), pos=(0, 0), units=unit_type, colorSpace=color_type, autoLog=False ) self.calibrationPointINNER = self.calibrationPoint.inner self.calibrationPointOUTER = self.calibrationPoint.outer tctype = color_type tcolor = self.getCalibSetting(['text_color']) if tcolor is None: # If no calibration text color provided, base it on the window background color from psychopy.iohub.util import complement sbcolor = self.getCalibSetting(['screen_background_color']) if sbcolor is None: sbcolor = self.window.color from psychopy.colors import Color tcolor_obj = Color(sbcolor, color_type) tcolor = complement(*tcolor_obj.rgb255) tctype = 'rgb255' instuction_text = 'Press SPACE to Start Calibration; ESCAPE to Exit.' self.textLineStim = visual.TextStim(self.window, text=instuction_text, pos=(0, 0), height=36, color=tcolor, colorSpace=tctype, units='pix', wrapWidth=self.width * 0.9)
def getTextColorAndType(self): color_type = self.getCalibSetting('color_type') if color_type is None: color_type = self.window.colorSpace tcolor = self.getCalibSetting(['text_color']) if tcolor is None: # If no calibration text color provided, base it on the window background color from psychopy.iohub.util import complement sbcolor = self.getCalibSetting(['screen_background_color']) if sbcolor is None: sbcolor = self.window.color from psychopy.colors import Color tcolor_obj = Color(sbcolor, color_type) tcolor = complement(*tcolor_obj.rgb255) color_type = 'rgb255' return tcolor, color_type
def onHexChanged(self, event): """Called when the user manually enters a hex value into the field. If the color value is valid, the new value will appear and the channels will update. """ dlgColor = self.GetTopLevelParent().color try: dlgColor.rgba = Color(self.txtHex.GetValue(), space='hex').rgba except ValueError: pass self.updateHex() self.updateChannels() self.updateDialog() event.Skip()
def __init__(self, parent): ScrolledPanel.__init__(self, parent, size=(120,400), style=wx.VSCROLL | wx.BORDER_NONE) self.sizer = wx.GridBagSizer() self.parent = parent for i in range(len(colorNames)): color = list(colorNames)[i] btn = GenButton(self, size=(100, 30), label=color, name=color) btn.SetOwnBackgroundColour(Color(color, 'named').rgba255) btn.SetBezelWidth(0) btn.SetUseFocusIndicator(False) btn.colorData = color #btn.SetBackgroundColour(wx.Colour(Color(color, 'named').rgba1)) btn.Bind(wx.EVT_BUTTON, self.onClick) self.sizer.Add(btn, pos=(i,0)) self.SetSizer(self.sizer) self.SetupScrolling()
def rgb2lms(rgb_Nx3, conversionMatrix=None): """Convert from RGB to cone space (LMS). Requires a conversion matrix, which will be generated from generic Sony Trinitron phosphors if not supplied (note that you will not get an accurate representation of the color space unless you supply a conversion matrix) usage:: lms_Nx3 = rgb2lms(rgb_Nx3(el,az,radius), conversionMatrix) """ col = Color(tuple(rgb_Nx3)) if len(rgb_Nx3) == 3: return unpackColors(col.lms) elif len(rgb_Nx3) == 4: return unpackColors(col.lms)
def OnHexRGBKeyDown(self, event): """Called when the user manually enters a hex value into the field. If the color value is valid, the new value will appear and the channels will update. If not, the box will revert back to the last valid value. """ # keydown need to be processed like this on MacOS if event.GetKeyCode() == wx.WXK_RETURN: oldHexColor = self.color.hex try: self.color.rgba = Color(self.txtHexRGB.GetValue(), space='hex').rgba self.updateRGBPage() self.updateHSVPage() self.updateDialog() except ValueError: self.txtHexRGB.SetValue(oldHexColor) else: event.Skip()
def __init__(self, win, tex="sin", mask="none", units="", pos=(0.0, 0.0), size=None, sf=None, ori=0.0, phase=(0.0, 0.0), texRes=128, rgb=None, dkl=None, lms=None, color=(1.0, 1.0, 1.0), colorSpace='rgb', contrast=1.0, opacity=1.0, depth=0, rgbPedestal=(0.0, 0.0, 0.0), interpolate=False, blendmode='avg', name=None, autoLog=None, autoDraw=False, maskParams=None): """ """ # Empty docstring. All doc is in attributes # what local vars are defined (these are the init params) for use by # __repr__ self._initParams = dir() for unecess in ['self', 'rgb', 'dkl', 'lms']: self._initParams.remove(unecess) # initialise parent class super(GratingStim, self).__init__(win, units=units, name=name, autoLog=False) # use shaders if available by default, this is a good thing self.__dict__['useShaders'] = win._haveShaders # UGLY HACK: Some parameters depend on each other for processing. # They are set "superficially" here. # TO DO: postpone calls to _createTexture, setColor and # _calcCyclesPerStim whin initiating stimulus self.__dict__['contrast'] = 1 self.__dict__['size'] = 1 self.__dict__['sf'] = 1 self.__dict__['tex'] = tex self.__dict__['maskParams'] = maskParams # initialise textures and masks for stimulus self._texID = GL.GLuint() GL.glGenTextures(1, ctypes.byref(self._texID)) self._maskID = GL.GLuint() GL.glGenTextures(1, ctypes.byref(self._maskID)) self.__dict__['texRes'] = texRes # must be power of 2 self.interpolate = interpolate # NB Pedestal isn't currently being used during rendering - this is a # place-holder self.rgbPedestal = val2array(rgbPedestal, False, length=3) # No need to invoke decorator for color updating. It is done just # below. self.colorSpace = colorSpace self.color = color if rgb != None: logging.warning("Use of rgb arguments to stimuli are deprecated." " Please use color and colorSpace args instead") self.color = Color(rgb, 'rgb') elif dkl != None: logging.warning("Use of dkl arguments to stimuli are deprecated." " Please use color and colorSpace args instead") self.color = Color(dkl, 'dkl') elif lms != None: logging.warning("Use of lms arguments to stimuli are deprecated." " Please use color and colorSpace args instead") self.color = Color(lms, 'lms') # set other parameters self.ori = float(ori) self.phase = val2array(phase, False) self._origSize = None # updated if an image texture is loaded self._requestedSize = size self.size = val2array(size) self.sf = val2array(sf) self.pos = val2array(pos, False, False) self.depth = depth self.tex = tex self.mask = mask self.contrast = float(contrast) self.opacity = float(opacity) self.autoLog = autoLog self.autoDraw = autoDraw self.blendmode = blendmode # fix scaling to window coords self._calcCyclesPerStim() # generate a displaylist ID self._listID = GL.glGenLists(1) # JRG: doing self._updateList() here means MRO issues for RadialStim, # which inherits from GratingStim but has its own _updateList code. # So don't want to do the update here (= ALSO the init of RadialStim). # Could potentially define a BaseGrating class without # updateListShaders code, and have GratingStim and RadialStim # inherit from it and add their own _updateList stuff. # Seems unnecessary. Instead, simply defer the update to the # first .draw(), should be fast: # self._updateList() # ie refresh display list self._needUpdate = True # set autoLog now that params have been initialised wantLog = autoLog is None and self.win.autoLog self.__dict__['autoLog'] = autoLog or wantLog if self.autoLog: logging.exp("Created {} = {}".format(self.name, self))
def _createStim(self): """ outer_diameter: 35 outer_stroke_width: 5 outer_fill_color: [255,255,255] outer_line_color: [255,255,255] inner_diameter: 5 inner_stroke_width: 0 inner_color: [0,0,0] inner_fill_color: [0,0,0] inner_line_color: [0,0,0] calibration_prefs=self._eyetrackerinterface.getConfiguration()['calibration']['target_attributes'] """ color_type = self.getCalibSetting('color_type') unit_type = self.getCalibSetting('unit_type') self.calibrationPoint = visual.TargetStim( self.window, name="CP", style="circles", radius=self.getCalibSetting( ['target_attributes', 'outer_diameter']) / 2.0, fillColor=self.getCalibSetting( ['target_attributes', 'outer_fill_color']), borderColor=self.getCalibSetting( ['target_attributes', 'outer_line_color']), lineWidth=self.getCalibSetting( ['target_attributes', 'outer_stroke_width']), innerRadius=self.getCalibSetting( ['target_attributes', 'inner_diameter']) / 2.0, innerFillColor=self.getCalibSetting( ['target_attributes', 'inner_fill_color']), innerBorderColor=self.getCalibSetting( ['target_attributes', 'inner_line_color']), innerLineWidth=self.getCalibSetting( ['target_attributes', 'inner_stroke_width']), pos=(0, 0), units=unit_type, colorSpace=color_type, autoLog=False) self.calibrationPointINNER = self.calibrationPoint.inner self.calibrationPointOUTER = self.calibrationPoint.outer tctype = color_type tcolor = self.getCalibSetting(['text_color']) if tcolor is None: # If no calibration text color provided, base it on the window background color from psychopy.iohub.util import complement sbcolor = self.getCalibSetting(['screen_background_color']) if sbcolor is None: sbcolor = self.window.color from psychopy.colors import Color tcolor_obj = Color(sbcolor, color_type) tcolor = complement(*tcolor_obj.rgb255) tctype = 'rgb255' instuction_text = 'Press SPACE to Start Calibration; ESCAPE to Exit.' self.textLineStim = visual.TextStim(self.window, text=instuction_text, pos=self.TEXT_POS, height=self.TEXT_HEIGHT, color=tcolor, colorSpace=tctype, units='pix', wrapWidth=self.width * 0.9) # create Tobii eye position feedback graphics # sw, sh = self.screenSize self.hbox_bar_length = hbox_bar_length = sw / 4 hbox_bar_height = 6 marker_diameter = 7 self.marker_heights = (-sh / 2.0 * .7, -sh / 2.0 * .75, -sh / 2.0 * .8, -sh / 2.0 * .7, -sh / 2.0 * .75, -sh / 2.0 * .8) bar_vertices = ([-hbox_bar_length / 2, -hbox_bar_height / 2 ], [hbox_bar_length / 2, -hbox_bar_height / 2 ], [hbox_bar_length / 2, hbox_bar_height / 2], [-hbox_bar_length / 2, hbox_bar_height / 2]) self.feedback_resources = OrderedDict() self.feedback_resources['hbox_bar_x'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='Firebrick', vertices=bar_vertices, units='pix', pos=(0, self.marker_heights[0])) self.feedback_resources['hbox_bar_y'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='DarkSlateGray', vertices=bar_vertices, units='pix', pos=(0, self.marker_heights[1])) self.feedback_resources['hbox_bar_z'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='GoldenRod', vertices=bar_vertices, units='pix', pos=(0, self.marker_heights[2])) marker_vertices = [-marker_diameter, 0], [0, marker_diameter], [marker_diameter, 0], [0, -marker_diameter] self.feedback_resources['left_hbox_marker_x'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='Black', vertices=marker_vertices, units='pix', pos=(0, self.marker_heights[0])) self.feedback_resources['left_hbox_marker_y'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='Black', units='pix', vertices=marker_vertices, pos=(0, self.marker_heights[1])) self.feedback_resources['left_hbox_marker_z'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='Black', units='pix', vertices=marker_vertices, pos=(0, self.marker_heights[2])) self.feedback_resources['right_hbox_marker_x'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='DimGray', units='pix', vertices=marker_vertices, pos=(0, self.marker_heights[0])) self.feedback_resources['right_hbox_marker_y'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='DimGray', units='pix', vertices=marker_vertices, pos=(0, self.marker_heights[1])) self.feedback_resources['right_hbox_marker_z'] = visual.ShapeStim( win=self.window, lineColor='White', fillColor='DimGray', units='pix', vertices=marker_vertices, pos=(0, self.marker_heights[2]))
'aqua', None, 'blue', None, 'fuchsia', None, 'red' ] # Combine expected values into one dict expected = { 'named': expectedNamed, 'hex': expectedHex, 'rgb': expectedRGB, 'rgb1': expectedRGB1, 'rgb255': expectedRGB255, 'hsv': expectedHSV } # Construct matrix of space pairs spaceMatrix = [] for space1 in expected: spaceMatrix.extend([[space1, space2] for space2 in expected if space2 != space1]) # Begin test if __name__ == '__main__': for space1, space2 in spaceMatrix: calc = [] for i in range(len(expected[space1])): # For each color in each pair of spaces... col1 = expected[space1][i] col2 = expected[space2][i] if col1 == None or col2 == None: # Skip unnamed colors continue # ...compare the same color in both spaces assert Color(col1, space1) == Color(col2, space2)
class PsychoColorPicker(wx.Dialog, ThemeMixin): def __init__(self, parent): wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Color Picker", pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE) # Set main params self.color = Color((0, 0, 0, 1), 'rgba') self.sizer = wx.GridBagSizer() # Add colourful top bar self.preview = ColorPreview(color=self.color, parent=self) self.sizer.Add(self.preview, pos=(0, 0), span=wx.GBSpan(2, 1), border=5, flag=wx.RIGHT | wx.EXPAND) # Add notebook of controls self.ctrls = aui.AuiNotebook(self, wx.ID_ANY, size=wx.Size(400, 400), agwStyle=0) self.sizer.Add(self.ctrls, pos=(0, 1), border=5, flag=wx.ALL) self.ctrls.AddPage(ColorPage(self.ctrls, self, 'rgba'), 'RGB (-1 to 1)') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'rgba1'), 'RGB (0 to 1)') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'rgba255'), 'RGB (0 to 255)') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'hsva'), 'HSV') self.ctrls.AddPage(ColorPage(self.ctrls, self, 'hex'), 'Hex') # Add array of named colours self.presets = ColorPresets(parent=self) self.sizer.Add(self.presets, pos=(0, 2), border=5, flag=wx.ALL) # Add buttons self.buttons = wx.BoxSizer(wx.HORIZONTAL) self.closeButton = wx.Button(self, label="Close") self.closeButton.Bind(wx.EVT_BUTTON, self.Close) self.buttons.Add(self.closeButton, border=5, flag=wx.ALL) # Add insert buttons # self.insertValueButton = wx.Button(self, label="Insert As Value") # self.insertValueButton.Bind(wx.EVT_BUTTON, self.insertValue) # self.buttons.Add(self.insertValueButton, border=5, flag=wx.ALL) # self.insertObjectButton = wx.Button(self, label="Insert As Object") # self.insertObjectButton.Bind(wx.EVT_BUTTON, self.insertObject) # self.buttons.Add(self.insertObjectButton, border=5, flag=wx.ALL) # Add copy buttons self.copyValueButton = wx.Button(self, label="Copy As Value") self.copyValueButton.Bind(wx.EVT_BUTTON, self.copyValue) self.buttons.Add(self.copyValueButton, border=5, flag=wx.ALL) self.copyObjectButton = wx.Button(self, label="Copy As Object") self.copyObjectButton.Bind(wx.EVT_BUTTON, self.copyObject) self.buttons.Add(self.copyObjectButton, border=5, flag=wx.ALL) self.sizer.Add(self.buttons, pos=(1, 1), span=wx.GBSpan(1, 2), border=5, flag=wx.ALL | wx.ALIGN_RIGHT) # Configure sizer self.sizer.AddGrowableRow(0) self.sizer.AddGrowableCol(1) self.SetSizerAndFit(self.sizer) self._applyAppTheme() self._applyAppTheme(self.ctrls) self.Layout() self.Centre(wx.BOTH) self.Show(True) def setColor(self, color, space): self.color.set(color, space) self.preview.color = self.color for i in range(self.ctrls.GetPageCount()): page = self.ctrls.GetPage(i) page.setColor(self.color) def insertValue(self, event): print(self.color) def insertObject(self, event): print(self.color) def copyValue(self, event): if wx.TheClipboard.Open(): # Get color rounded col = getattr(self.color, self.ctrls.GetCurrentPage().space) if isinstance(col, tuple): col = tuple(round(c, 2) for c in col) # Copy to clipboard wx.TheClipboard.SetData(wx.TextDataObject(str(col))) wx.TheClipboard.Close() def copyObject(self, event): if wx.TheClipboard.Open(): # Get color rounded col = getattr(self.color, self.ctrls.GetCurrentPage().space) if isinstance(col, tuple): col = tuple(round(c, 2) for c in col) # Copy to clipboard wx.TheClipboard.SetData( wx.TextDataObject("colors.Color(" + str(col) + ", \'" + self.ctrls.GetCurrentPage().space + "\')")) wx.TheClipboard.Close() def Close(self, event): self.Destroy()
def test_ColorTykes(): for colorSet in tykes: for space in colorSet: assert bool(Color(colorSet[space], space))
space : int Last RGB colorspace specified. rgbInputMode : int RGB input mode selected by the user. """ def __init__(self, color, space, rgbInputMode): self.color = color self.space = space self.rgbInputMode = rgbInputMode # Store the state of the color picker here for persistance. Here we define the # defaults for when the colorpicker is first invoked. COLORPICKER_STATE = ColorPickerState( color=Color((0, 0, 0, 1), space='rgba'), space=0, rgbInputMode=0 # PsychopPy RGB ) class PsychoColorPicker(ColorPickerDialog): """Class for the color picker dialog. This dialog is used to standardize color selection across platforms. It also supports PsychoPy's RGB representation directly. This is a subclass of the auto-generated `ColorPickerDialog` class. Parameters ----------
def validate(obj, valType): val = str(obj.GetValue()) valid = True if val.startswith("$"): # If indicated as code, treat as code valType = "code" # Validate string if valType == "str": if re.findall(r"(?<!\\)\"", val): # If there are unescaped " valid = False if re.findall(r"(?<!\\)\'", val): # If there are unescaped ' valid = False # Validate code if valType == "code": # Replace unescaped curly quotes if re.findall(r"(?<!\\)[\u201c\u201d]", val): pt = obj.GetInsertionPoint() obj.SetValue(re.sub(r"(?<!\\)[\u201c\u201d]", "\"", val)) obj.SetInsertionPoint(pt) # For now, ignore pass # Validate num if valType == "num": try: # Try to convert value to a float float(val) except ValueError: # If conversion fails, value is invalid valid = False # Validate bool if valType == "bool": if val not in ["True", "False"]: # If value is not True or False, it is invalid valid = False # Validate list if valType == "list": empty = not bool(val) # Is value empty? fullList = re.fullmatch(r"[\(\[].*[\]\)]", val) # Is value full list with parentheses? partList = "," in val and not re.match(r"[\(\[].*[\]\)]", val) # Is value list without parentheses? singleVal = not " " in val or re.match(r"[\"\'].*[\"\']", val) # Is value a single value? if not any([empty, fullList, partList, singleVal]): # If value is not any of valid types, it is invalid valid = False # Validate color if valType == "color": # Strip function calls if re.fullmatch(r"\$?(Advanced)?Color\(.*\)", val): val = re.sub(r"\$?(Advanced)?Color\(", "", val[:-1]) try: # Try to create a Color object from value obj.color = Color(val, False) if not obj.color: # If invalid object is created, input is invalid valid = False except: # If object creation fails, input is invalid valid = False if valType == "file": if not os.path.isfile(os.path.abspath(val)): # Is value a valid filepath? valid = False if hasattr(obj, "validExt"): if not val.endswith(tuple(obj.validExt)): # If control has specified list of ext, does value end in correct ext? valid = False # If additional allowed values are defined, override validation if hasattr(obj, "allowedVals"): if val in obj.allowedVals: valid = True # Apply valid status to object obj.valid = valid if hasattr(obj, "showValid"): obj.showValid(valid) # Update code font obj.updateCodeFont(valType)
def test_init_scales(self): # ideally: give default, non-default, and bad values for all params # defaults: --------- r = copy.copy(self.r) assert (r.low, r.high, r.precision) == (1, 7, 1) assert (r.markerStyle, r.markerStart, r.markerPlaced) == ('triangle', None, False) # non-defaults and some bad: --------- r = RatingScale(self.win, low=-10., high=10., autoLog=False) assert (r.low, r.high) == (-10, 10) assert (type(r.low), type(r.high)) == (int, int) r = RatingScale(self.win, low='a', high='s', autoLog=False) # bad vals assert (r.low, r.high) == (1, 2) r = RatingScale(self.win, low=10, high=2, autoLog=False) assert r.high == r.low + 1 == 11 assert r.precision == 100 ch = ['a', 'b'] r = RatingScale(self.win, choices=ch, precision=10, autoLog=False) assert r.precision == 1 # because choices assert r.respKeys == list(map(str, list(range(len(ch))))) r = RatingScale(self.win, choices=['a'], autoLog=False) r = RatingScale(self.win, tickMarks=[1, 2, 3], labels=['a', 'b'], autoLog=False) for i in [-1, 0.3, 1.2, 9, 12, 100, 1000]: r = RatingScale(self.win, precision=i, autoLog=False) assert r.precision in [1, 10, 100] r = RatingScale(self.win, textSize=3, textColor=0.3, autoLog=False) #r = RatingScale(self.win, textFont=utils.TESTS_FONT, autoLog=False) #assert r.accept.font == r.scaleDescription.font == utils.TESTS_FONT r = RatingScale(self.win, showValue=False, showAccept=False, acceptKeys=[], autoLog=False) r = RatingScale(self.win, showAccept=False, mouseOnly=True, singleClick=False, autoLog=False) assert r.mouseOnly == False r = RatingScale(self.win, acceptKeys='a', autoLog=False) r = RatingScale(self.win, acceptKeys=['a', 'b'], autoLog=False) r = RatingScale(self.win, acceptPreText='a', acceptText='a', acceptSize=2.1, autoLog=False) r = RatingScale(self.win, leftKeys=['a'], rightKeys=['a'], autoLog=False) assert r.respKeys == list(map(str, list(range(1, 8)))) r = RatingScale(self.win, respKeys=['a'], acceptKeys=['a'], autoLog=False) r = RatingScale(self.win, acceptKeys=['1'], autoLog=False) r = RatingScale(self.win, tickHeight=-1, autoLog=False) r = RatingScale(self.win, markerStart=3, tickHeight=False, autoLog=False) r = RatingScale(self.win, markerStart='a', choices=['a', 'b'], autoLog=False) assert r.choices == ['a', 'b'] r = RatingScale(self.win, markerColor='dark red', lineColor='Black', autoLog=False) assert r.marker._fillColor == r.marker._borderColor == Color('darkred') assert r.line._borderColor == Color('Black') r = RatingScale(self.win, marker='glow', markerExpansion=0, autoLog=False) r.markerPlaced = True r.draw() r.markerExpansion = 10 r.draw() r = RatingScale(self.win, skipKeys=None, mouseOnly=True, singleClick=True, autoLog=False) r = RatingScale(self.win, pos=(0, .5), skipKeys='space', autoLog=False) r = RatingScale(self.winpix, pos=[1], autoLog=False) r = RatingScale(self.winpix, pos=['a', 'x'], autoLog=False) assert r.pos == [0.0, old_div(-50.0, r.win.size[1])] x, y = -3, 17 r = RatingScale(self.winpix, pos=(x, y), size=.2, stretch=2, autoLog=False) assert r.offsetHoriz == 2. * x / r.win.size[0] assert r.offsetVert == 2. * y / r.win.size[1] assert r.stretch == 2 assert r.size == 0.2 * 0.6 # internal rescaling by 0.6 r = RatingScale(self.win, stretch='foo', size='foo', autoLog=False) assert r.stretch == 1 assert r.size == 0.6 r = RatingScale(self.win, size=5, autoLog=False) assert r.size == 3 r = RatingScale(self.win, minTime=0.001, maxTime=1, autoLog=False) assert r.minTime == 0.001 and r.maxTime == 1 r = RatingScale(self.win, minTime='x', maxTime='s', name='name', autoLog=False) assert r.minTime == 1.0 and r.maxTime == 0. assert r.name == 'name' and r.autoLog == False
def __init__(self, win, text="Hello World", font="", pos=(0.0, 0.0), depth=0, rgb=None, color=(1.0, 1.0, 1.0), colorSpace='rgb', opacity=1.0, contrast=1.0, units="", ori=0.0, height=None, antialias=True, bold=False, italic=False, alignHoriz=None, alignVert=None, alignText='center', anchorHoriz='center', anchorVert='center', fontFiles=(), wrapWidth=None, flipHoriz=False, flipVert=False, languageStyle='LTR', name=None, autoLog=None, autoDraw=False): """ **Performance OBS:** in general, TextStim is slower than many other visual stimuli, i.e. it takes longer to change some attributes. In general, it's the attributes that affect the shapes of the letters: ``text``, ``height``, ``font``, ``bold`` etc. These make the next .draw() slower because that sets the text again. You can make the draw() quick by calling re-setting the text (``myTextStim.text = myTextStim.text``) when you've changed the parameters. In general, other attributes which merely affect the presentation of unchanged shapes are as fast as usual. This includes ``pos``, ``opacity`` etc. The following attribute can only be set at initialization (see further down for a list of attributes which can be changed after initialization): **languageStyle** Apply settings to correctly display content from some languages that are written right-to-left. Currently there are three (case- insensitive) values for this parameter: - ``'LTR'`` is the default, for typical left-to-right, Latin-style languages. - ``'RTL'`` will correctly display text in right-to-left languages such as Hebrew. By applying the bidirectional algorithm, it allows mixing portions of left-to-right content (such as numbers or Latin script) within the string. - ``'Arabic'`` applies the bidirectional algorithm but additionally will _reshape_ Arabic characters so they appear in the cursive, linked form that depends on neighbouring characters, rather than in their isolated form. May also be applied in other scripts, such as Farsi or Urdu, that use Arabic-style alphabets. :Parameters: """ # what local vars are defined (these are the init params) for use by # __repr__ self._initParams = dir() self._initParams.remove('self') """ October 2018: In place to remove the deprecation warning for pyglet.font.Text. Temporary fix until pyglet.text.Label use is identical to pyglet.font.Text. """ warnings.filterwarnings(message='.*text.Label*', action='ignore') super(TextStim, self).__init__(win, units=units, name=name, autoLog=False) if win.blendMode == 'add': logging.warning("Pyglet text does not honor the Window setting " "`blendMode='add'` so 'avg' will be used for the " "text (but objects drawn after can be added)") self._needUpdate = True self._needVertexUpdate = True # use shaders if available by default, this is a good thing self.__dict__['antialias'] = antialias self.__dict__['font'] = font self.__dict__['bold'] = bold self.__dict__['italic'] = italic # NB just a placeholder - real value set below self.__dict__['text'] = '' self.__dict__['depth'] = depth self.__dict__['ori'] = ori self.__dict__['flipHoriz'] = flipHoriz self.__dict__['flipVert'] = flipVert self.__dict__['languageStyle'] = languageStyle self._pygletTextObj = None self.pos = pos # deprecated attributes if alignVert: self.__dict__['alignVert'] = alignVert logging.warning("TextStim.alignVert is deprecated. Use the " "anchorVert attribute instead") # for compatibility, alignText was historically 'left' anchorVert = alignHoriz if alignHoriz: self.__dict__['alignHoriz'] = alignHoriz logging.warning("TextStim.alignHoriz is deprecated. Use alignText " "and anchorHoriz attributes instead") # for compatibility, alignText was historically 'left' alignText, anchorHoriz = alignHoriz, alignHoriz # alignment and anchors self.alignText = alignText self.anchorHoriz = anchorHoriz self.anchorVert = anchorVert # generate the texture and list holders self._listID = GL.glGenLists(1) # pygame text needs a surface to render to: if not self.win.winType in ["pyglet", "glfw"]: self._texID = GL.GLuint() GL.glGenTextures(1, ctypes.byref(self._texID)) # Color stuff self.colorSpace = colorSpace self.color = color if rgb != None: logging.warning( "Use of rgb arguments to stimuli are deprecated. Please " "use color and colorSpace args instead") self.color = Color(rgb, 'rgb') self.__dict__['fontFiles'] = [] self.fontFiles = list(fontFiles) # calls attributeSetter self.setHeight(height, log=False) # calls setFont() at some point # calls attributeSetter without log setAttribute(self, 'wrapWidth', wrapWidth, log=False) self.opacity = opacity self.contrast = contrast # self.width and self._fontHeightPix get set with text and # calcSizeRendered is called self.setText(text, log=False) self._needUpdate = True self.autoDraw = autoDraw # set autoLog now that params have been initialised wantLog = autoLog is None and self.win.autoLog self.__dict__['autoLog'] = autoLog or wantLog if self.autoLog: logging.exp("Created %s = %s" % (self.name, str(self)))
# -*- coding: utf-8 -*- """Classes for the color picker.""" # Part of the PsychoPy library # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019 Open Science Tools Ltd. # Distributed under the terms of the GNU General Public License (GPL). import wx from .panels import ColorPresets, ColorPreview from .pages import ColorPickerPageHSV, ColorPickerPageRGB from psychopy.colors import Color from psychopy.localization import _translate LAST_COLOR = Color((0, 0, 0, 1), space='rgba') LAST_OUTPUT_SPACE = 0 class PsychoColorPicker(wx.Dialog): """Class for the color picker dialog. This dialog is used to standardize color selection across platforms. It also supports PsychoPy's RGB representation directly. Parameters ---------- parent : object Reference to a :class:`~wx.Frame` which owns this dialog. """ def __init__(self, parent): wx.Dialog.__init__(