def __init__(self): OpenModeless.__init__(self, command=_openCB, filters=[("Chimera session", ["*.py"])], defaultFilter="Chimera session", addAll=False, historyID="SimpleSession")
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) self.deleteExistingVar = Tkinter.IntVar(parent) self.deleteExistingVar.set(False) Tkinter.Checkbutton(self.clientArea, variable=self.deleteExistingVar, text="Delete existing labels").grid()
def __init__(self): from fileInfo import fileType, suffixes OpenModeless.__init__(self, clientPos='s', defaultFilter=fileType, filters=[(fileType, ['*' + suf for suf in suffixes])])
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) import Tkinter self.defaultVar = Tkinter.IntVar(parent) self.defaultVar.set(True) Tkinter.Checkbutton(self.clientArea, variable=self.defaultVar, text="Make this scheme the default").grid()
def _chimeraAdd(self): from OpenSave import OpenModeless if not hasattr(self, "_addDialog"): self._addDialog = OpenModeless(command=self._addCB, default='Add', **self.__addKw) self._addDialog.enter()
def __init__(self, title, grid_objects_cb): self.grid_objects_cb = grid_objects_cb OpenModeless.__init__(self, title = title, filters = file_type_filters(), defaultFilter="all (guess type)")
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) self.colorStructureVar = Tkinter.IntVar(self.clientArea) self.colorStructureVar.set(colorStructuresDefault) Tkinter.Checkbutton(self.clientArea, text="Color structures also", variable=self.colorStructureVar).grid()
def __init__(self, title, grid_objects_cb): self.grid_objects_cb = grid_objects_cb OpenModeless.__init__(self, title=title, filters=file_type_filters(), defaultFilter="all (guess type)")
class OrderedFileListOption(OrderedListOption): """OrderedFileListOption keeps track of an ordered list of file names""" def __init__(self, *args, **kw): self.__pathStyle = kw.pop('pathStyle') self.__addKw = kw.pop('addKw', {}) apply(OrderedListOption.__init__, (self,)+args, kw) def add(self): try: import OpenSave except ImportError: self._tkAdd() else: self._chimeraAdd() def _tkAdd(self): from tkFileDialog import askopenfilename filename = askopenfilename() if not filename: return if self.__pathStyle == 'normal': self.addItem(filename, filename) else: import os.path dir, name = os.path.split(filename) if not dir: dir = "(current directory)" self.addItem('%s - %s' % (name, dir), filename) def _chimeraAdd(self): from OpenSave import OpenModeless if not hasattr(self, "_addDialog"): self._addDialog = OpenModeless(command=self._addCB, default='Add', **self.__addKw) self._addDialog.enter() def _addCB(self, okayed, dialog): if not okayed: return for path in dialog.getPaths(): if self.__pathStyle == 'normal': self.addItem(path, path) else: import os.path dir, name = os.path.split(path) if not dir: dir = "(current directory)" self.addItem('%s - %s' % (name, dir), path)
class OrderedFileListOption(OrderedListOption): """OrderedFileListOption keeps track of an ordered list of file names""" def __init__(self, *args, **kw): self.__pathStyle = kw.pop('pathStyle') self.__addKw = kw.pop('addKw', {}) apply(OrderedListOption.__init__, (self, ) + args, kw) def add(self): try: import OpenSave except ImportError: self._tkAdd() else: self._chimeraAdd() def _tkAdd(self): from tkFileDialog import askopenfilename filename = askopenfilename() if not filename: return if self.__pathStyle == 'normal': self.addItem(filename, filename) else: import os.path dir, name = os.path.split(filename) if not dir: dir = "(current directory)" self.addItem('%s - %s' % (name, dir), filename) def _chimeraAdd(self): from OpenSave import OpenModeless if not hasattr(self, "_addDialog"): self._addDialog = OpenModeless(command=self._addCB, default='Add', **self.__addKw) self._addDialog.enter() def _addCB(self, okayed, dialog): if not okayed: return for path in dialog.getPaths(): if self.__pathStyle == 'normal': self.addItem(path, path) else: import os.path dir, name = os.path.split(path) if not dir: dir = "(current directory)" self.addItem('%s - %s' % (name, dir), path)
def startExtension(): filters = [] fileTypes = extensions.keys() fileTypes.sort(lambda a, b: cmp(a.lower(), b.lower())) for fileType in fileTypes: exts = extensions[fileType] filters.append((fileType, map(lambda x: '*' + x, exts))) global _openDialog if not _openDialog: from OpenSave import OpenModeless _openDialog = OpenModeless(title="Open Sequence Alignment File", help="ContributedSoftware/multalignviewer/framemav.html", command=_openFile, filters=filters, historyID="MultAlign open file") _openDialog.enter()
def browse(self): from OpenSave import OpenModeless if hasattr(self, '_openDialog'): self._openDialog.enter() return filters = [] addAll = 0 if self.filetypes: for name, glob in self.filetypes: if glob == '*': addAll = 1 continue if glob[0] == '.': glob = '*' + glob filters.append((name, glob)) if self.default: initialfile = self.default else: initialfile = None self._openDialog = OpenModeless(command=self._openCB, initialfile=initialfile, title='Select %s' % self.name, filters=filters, initialdir=self.startLocation(), defaultFilter=0, multiple=0, addAll=addAll, historyID="Delphi input %s" % self.name, compressed=self.compressed)
def HearDockCB(): from OpenSave import OpenModeless OpenModeless(command=_openHDCB, title="Open Dock Results", filters=Filters, dialogKw={'oneshot': 1}, historyID="ViewDock")
def browse(self): if self.menuOption.var.get() == self.menuoptions[0]: modellist = chimera.openModels.list(modelTypes=[chimera.Molecule]) # if no molecules (and i mean MOLECULES) # are open in chimera... if not modellist: replyobj.error('There are no molecules open') return if len(modellist) > 1: modellist = chooseModels(self.parent, modelTypes=[chimera.Molecule]) if modellist: #print 'writing pdb to file...' # make a pdb file for the model self._removeTempFile() self.var.set(self._writeTempFile(modellist)) self.displayVar.set(modellist[0].name) #print 'set file name.' else: if hasattr(self, '_openDialog'): self._openDialog.enter() return from OpenSave import OpenModeless self._openDialog = OpenModeless(command=self._openCB, title='Select %s' % self.name, multiple=0, historyID="Delphi PDB", compressed=False)
def startExtension(): filters = [] fileTypes = extensions.keys() fileTypes.sort(lambda a, b: cmp(a.lower(), b.lower())) for fileType in fileTypes: exts = extensions[fileType] filters.append((fileType, map(lambda x: '*' + x, exts))) global _openDialog if not _openDialog: from OpenSave import OpenModeless _openDialog = OpenModeless( title="Open Sequence Alignment File", help="ContributedSoftware/multalignviewer/framemav.html", command=_openFile, filters=filters, historyID="MultAlign open file") _openDialog.enter()
def chooseDemo(): from OpenSave import OpenModeless OpenModeless(command=_chooseCB, title="Choose Demo File", historyID="Demo", defaultFilter=0, filters=[("Demo", ["*.src"])], dialogKw={'oneshot': 1})
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) group = Pmw.Group(self.clientArea, tag_text='Further info') group.grid(row=0, column=0, sticky='nsew') self.catName = StringOption(group.interior(), 0, "group name", None, None) class PBLineWidthOption(LineWidthOption): default = prefs["line width"] balloon = "Width of pseudobonds (in pixels)" self.lineWidth = PBLineWidthOption(group.interior(), 1, None, None, None) self.clearCat = BooleanOption(group.interior(), 2, "clear group of previous pseudobonds", 1, None) self.leftModel = IntOption(group.interior(), 3, "first column specifiers default to model", 0, None) self.rightModel = IntOption(group.interior(), 4, "second column specifiers default to model", 0, None)
def gui(self): from OpenSave import OpenModeless globs = [] for ext in self.exts: globs.append('*' + ext) OpenModeless(title='Open Bild File', command=self._openCB, filters=[(self.fileType, globs)], defaultFilter=self.fileType, historyID='bild open file', dialogKw={'oneshot': 1})
def Open(self): close_it = self.checkIfDirty() if not close_it: return from OpenSave import OpenModeless OpenModeless(command=self._openCB, title="Choose Demo to Open", dialogKw={'oneshot': 1}, historyID="Demo editor open", defaultFilter=0, filters=[("Demo", ["*.src"])])
def show_open_dialog(dir, callback): def open(okay, dialog): if okay: paths_types = dialog.getPathsAndTypes() if paths_types: callback(paths_types) from OpenSave import OpenModeless OpenModeless(title='Open Segmentation', initialdir=dir, filters=[('Segmentation', ['*.seg']), ('Old regions file', ['*_regions'])], defaultFilter='Segmentation', command=open)
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) group = Pmw.Group(self.clientArea, tag_text='Further info') group.grid(row=0, column=0, sticky='nsew') self.catName = StringOption(group.interior(), 0, "group name", None, None) class PBLineWidthOption(LineWidthOption): default = prefs["line width"] balloon = "Width of pseudobonds (in pixels)" self.lineWidth = PBLineWidthOption(group.interior(), 1, None, None, None) self.clearCat = BooleanOption(group.interior(), 2, "clear group of previous pseudobonds", 1, None) self.leftModel = IntOption(group.interior(), 3, "first column specifiers default to model", 0, None) self.rightModel = IntOption( group.interior(), 4, "second column specifiers default to model", 0, None)
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) from chimera.widgets import MoleculeScrolledListBox self.molListBox = MoleculeScrolledListBox(self.clientArea, listbox_selectmode="extended", labelpos="w", label_text="Restrict to models:") self.molListBox.grid(row=0, column=0, sticky="nsew") self.clientArea.rowconfigure(0, weight=1) self.clientArea.columnconfigure(0, weight=1) checkButtonFrame = Tkinter.Frame(self.clientArea) checkButtonFrame.grid(row=1, column=0) self.openDialog = Tkinter.IntVar(parent) self.openDialog.set(True) Tkinter.Checkbutton(checkButtonFrame, variable=self.openDialog, text="Open Render/Select by Attribute").grid( row=0, column=0, sticky='w') self.doLog = Tkinter.IntVar(parent) self.doLog.set(False) Tkinter.Checkbutton(checkButtonFrame, text="Send match info to Reply Log", variable=self.doLog).grid(row=1, column=0, sticky='w')
class TextureDialog(ModelessDialog): name = '2D Texture Editor' help = '2dTexture.html' buttons = ('New', 'Close') defaultTexture = None createdTextures = [] def __init__(self, master=None, *args, **kw): self.texture = None self.newPanel = None apply(ModelessDialog.__init__, (self, master) + args, kw) def fillInUI(self, master): # TextureEditor top = Tkinter.Frame(master) top.pack(side=Tkinter.TOP, anchor=Tkinter.W, fill=Tkinter.X, padx=2, pady=2) te = TextureEditor.TextureEditor(top, TextureMap=ChimeraTextureMap) te.map.panel = self te.pack(side=Tkinter.TOP, expand=1, fill=Tkinter.BOTH) self.editor = te # Texture option menu self.names = Tkinter.Menubutton(te, width=10, bd=2, indicatoron=1, relief=Tkinter.RAISED, anchor='c') self.names.pack(side=Tkinter.TOP, expand=1, fill=Tkinter.X) self.menu = Tkinter.Menu(self.names) self.names['menu'] = self.menu # Texture background b = Tkinter.Button(te, text='Load Background', command=self.__loadBackground) b.pack(side=Tkinter.TOP, fill=Tkinter.X) self.reloadTextures() self.monitorHandler = chimera.triggers.addHandler( 'Texture', self.__textureHandler, None) def __del__(self): chimera.triggers.deleteHandler('Texture', self.monitorHandler) def New(self): if not self.newPanel: self.newPanel = NewPanel(self.uiMaster()) if not self.newPanel.run(self.uiMaster()): return name, width, height = self.newPanel.values() if len(name) == 0: tkMessageBox.showerror(title='Error', message='No texture name specified') return if chimera.Texture.lookup(name): tkMessageBox.showerror(title='Error', message='Texture "%s" already exists' % name) return t = chimera.Texture(name, chimera.Texture.RGBA, chimera.Texture.UnsignedByte, width, height) t.editorState = { 'size': (width, height), 'xFactor': 1, 'yFactor': 1 } self.__selectTexture(name) TextureDialog.createdTextures.append(t) def __selectTexture(self, textureName): if self.texture: state = self.editor.map.saveState() if not hasattr(self.texture, 'editorState'): self.texture.editorState = state else: self.texture.editorState.update(state) self.texture = chimera.Texture.lookup(textureName) if self.texture is None: raise NameError, 'Cannot find texture named "%s"' \ % textureName self.editor.map.changeTexture() self.names.config(text=textureName) def __loadBackground(self): if not hasattr(self, '_loadBGDialog'): from OpenSave import OpenModeless self._loadBGDialog = OpenModeless( title='Load Background', command=self._loadBGCB) self._loadBGDialog.enter() def _loadBGCB(self, okayed, dialog): if not okayed: return for path in dialog.getPaths(): self.editor.map.setBackground(Image.open(path)) def reloadTextures(self): cursel = self.names['text'] tList = chimera.Texture.list().items() if tList: nList = [] for n, t in tList: if t.type() != t.UnsignedByte: continue w, h, depth, nc, nb = t.sizes() if w not in goodSizes or h not in goodSizes: continue if depth != 1 or nc < 3: continue nList.append(n) tList = nList tList.sort() if TextureDialog.defaultTexture is None: name = '2dTexture' x = chimera.Texture(name, chimera.Texture.RGBA, chimera.Texture.UnsignedByte, 128, 128) x.editorState = { 'size': (128, 128), 'xFactor': 1, 'yFactor': 1 } tList.append(name) TextureDialog.defaultTexture = x tList.sort() self.menu.delete(0, Tkinter.END) for t in tList: self.menu.add_command(label=t, command=lambda s=self, t=t: s.__selectTexture(t)) if cursel not in tList: cursel = None if not cursel: cursel = tList[0] self.__selectTexture(cursel) def updateTexture(self, image): if not self.texture: return w, h, depth, nc, nb = self.texture.sizes() if image.size[0] != w or image.size[1] != h: raise ValueError, 'image/texture size mismatch' self.texture.image = image def __textureHandler(self, trigger, closure, textures): if textures.created or textures.deleted: self.reloadTextures() return for t in textures.modified: if t == self.texture: self.editor.map.redrawIfNeeded()
def __loadBackground(self): if not hasattr(self, '_loadBGDialog'): from OpenSave import OpenModeless self._loadBGDialog = OpenModeless( title='Load Background', command=self._loadBGCB) self._loadBGDialog.enter()
def __init__(self): from fileInfo import fileType, suffixes OpenModeless.__init__(self, clientPos='s', defaultFilter=fileType, filters=[(fileType, ['*'+suf for suf in suffixes])])
def __init__(self): OpenModeless.__init__(self, title="Pseudobond File to Read", historyID="PBReader open", clientPos='s')
def fillInUI(self, parent): OpenModeless.fillInUI(self, parent) self.attrFrame = AttrFrame(self.clientArea) self.attrFrame.grid()
def __init__(self): OpenModeless.__init__(self, clientPos='s', clientSticky='nsew', historyID="AddAttr")
def __init__(self, mav): self.mav = mav OpenModeless.__init__(self, historyID="MAV phylogeny")
def __init__(self, colorStructuresDefault, **kw): kw['filters'] = [("SCF", ["*.scf", "*.seqsel"])] kw['defaultFilter'] = 0 kw['clientPos'] = 's' OpenModeless.__init__(self, **kw)
def __init__(self, mav): self.mav = mav self.title = "Load Header Line for %s" % mav.title OpenModeless.__init__(self, historyID="mav header")
def __init__(self, mainDialog): self.mainDialog = mainDialog self.mainDialog.subdialogs.append(self) OpenModeless.__init__(self, multiple=False, **self.mainDialog.ensemble.AddTrajKw)
class TextureDialog(ModelessDialog): name = '2D Texture Editor' help = '2dTexture.html' buttons = ('New', 'Close') defaultTexture = None createdTextures = [] def __init__(self, master=None, *args, **kw): self.texture = None self.newPanel = None apply(ModelessDialog.__init__, (self, master) + args, kw) def fillInUI(self, master): # TextureEditor top = Tkinter.Frame(master) top.pack(side=Tkinter.TOP, anchor=Tkinter.W, fill=Tkinter.X, padx=2, pady=2) te = TextureEditor.TextureEditor(top, TextureMap=ChimeraTextureMap) te.map.panel = self te.pack(side=Tkinter.TOP, expand=1, fill=Tkinter.BOTH) self.editor = te # Texture option menu self.names = Tkinter.Menubutton(te, width=10, bd=2, indicatoron=1, relief=Tkinter.RAISED, anchor='c') self.names.pack(side=Tkinter.TOP, expand=1, fill=Tkinter.X) self.menu = Tkinter.Menu(self.names) self.names['menu'] = self.menu # Texture background b = Tkinter.Button(te, text='Load Background', command=self.__loadBackground) b.pack(side=Tkinter.TOP, fill=Tkinter.X) self.reloadTextures() self.monitorHandler = chimera.triggers.addHandler( 'Texture', self.__textureHandler, None) def __del__(self): chimera.triggers.deleteHandler('Texture', self.monitorHandler) def New(self): if not self.newPanel: self.newPanel = NewPanel(self.uiMaster()) if not self.newPanel.run(self.uiMaster()): return name, width, height = self.newPanel.values() if len(name) == 0: tkMessageBox.showerror(title='Error', message='No texture name specified') return if chimera.Texture.lookup(name): tkMessageBox.showerror(title='Error', message='Texture "%s" already exists' % name) return t = chimera.Texture(name, chimera.Texture.RGBA, chimera.Texture.UnsignedByte, width, height) t.editorState = {'size': (width, height), 'xFactor': 1, 'yFactor': 1} self.__selectTexture(name) TextureDialog.createdTextures.append(t) def __selectTexture(self, textureName): if self.texture: state = self.editor.map.saveState() if not hasattr(self.texture, 'editorState'): self.texture.editorState = state else: self.texture.editorState.update(state) self.texture = chimera.Texture.lookup(textureName) if self.texture is None: raise NameError, 'Cannot find texture named "%s"' \ % textureName self.editor.map.changeTexture() self.names.config(text=textureName) def __loadBackground(self): if not hasattr(self, '_loadBGDialog'): from OpenSave import OpenModeless self._loadBGDialog = OpenModeless(title='Load Background', command=self._loadBGCB) self._loadBGDialog.enter() def _loadBGCB(self, okayed, dialog): if not okayed: return for path in dialog.getPaths(): self.editor.map.setBackground(Image.open(path)) def reloadTextures(self): cursel = self.names['text'] tList = chimera.Texture.list().items() if tList: nList = [] for n, t in tList: if t.type() != t.UnsignedByte: continue w, h, depth, nc, nb = t.sizes() if w not in goodSizes or h not in goodSizes: continue if depth != 1 or nc < 3: continue nList.append(n) tList = nList tList.sort() if TextureDialog.defaultTexture is None: name = '2dTexture' x = chimera.Texture(name, chimera.Texture.RGBA, chimera.Texture.UnsignedByte, 128, 128) x.editorState = {'size': (128, 128), 'xFactor': 1, 'yFactor': 1} tList.append(name) TextureDialog.defaultTexture = x tList.sort() self.menu.delete(0, Tkinter.END) for t in tList: self.menu.add_command( label=t, command=lambda s=self, t=t: s.__selectTexture(t)) if cursel not in tList: cursel = None if not cursel: cursel = tList[0] self.__selectTexture(cursel) def updateTexture(self, image): if not self.texture: return w, h, depth, nc, nb = self.texture.sizes() if image.size[0] != w or image.size[1] != h: raise ValueError, 'image/texture size mismatch' self.texture.image = image def __textureHandler(self, trigger, closure, textures): if textures.created or textures.deleted: self.reloadTextures() return for t in textures.modified: if t == self.texture: self.editor.map.redrawIfNeeded()
def fillInUI(self, parent): items = [SCRIPT_PYTHON, SCRIPT_CHIMERA] if prefs[SCRIPT_TYPE] in items: initialitem = prefs[SCRIPT_TYPE] else: initialitem = SCRIPT_PYTHON self.scriptType = Pmw.OptionMenu(parent, items=items, command=self._setFrameSubst, initialitem=initialitem, labelpos="w", label_text="Interpret script as") self.scriptType.grid(row=0, column=0, sticky="w") self.pythonFrame = Tkinter.Frame(parent) self.varField = Pmw.EntryField(self.pythonFrame, labelpos='w', label_text="Initialize dictionary", entry_width=len(prefs[DICT_NAME]), value=prefs[DICT_NAME]) self.varField.grid(row=0, column=0, sticky='e') Tkinter.Label(self.pythonFrame, text="with").grid(row=0, column=1) tableFrame = Tkinter.Frame(self.pythonFrame, relief="solid", bd=1) tableFrame.grid(row=0, column=2, sticky='w') Tkinter.Label(tableFrame, text="Key", relief="ridge").grid(row=0, column=0, sticky='ew') Tkinter.Label(tableFrame, text="Value", relief="ridge").grid(row=0, column=1, sticky='ew') for i, kv in enumerate([("frame", "frame number"), ("mol", "Molecule instance")]): Tkinter.Label(tableFrame, text=kv[0]).grid(row=i + 1, column=0) Tkinter.Label(tableFrame, text=kv[1]).grid(row=i + 1, column=1) Tkinter.Label(tableFrame, text="startFrame").grid(row=i + 2, column=0) Tkinter.Label(tableFrame, text="endFrame").grid(row=i + 3, column=0) Tkinter.Label(tableFrame, text="starting/ending\nframe number").grid(row=i + 2, rowspan=2, column=1) self.chimeraFrame = Tkinter.Frame(parent) self.textField = Pmw.EntryField(self.chimeraFrame, labelpos='w', label_text="Substitute text", entry_width=len(prefs[FRAME_TEXT]) + 1, value=prefs[FRAME_TEXT]) self.textField.grid(row=0, column=0, sticky='e') self.entryWidgets = [self.varField, self.textField] Tkinter.Label(self.chimeraFrame, text="with frame number").grid(row=0, column=1, sticky='w') self.zeroPadVar = Tkinter.IntVar(self.chimeraFrame) self.zeroPadVar.set(prefs[ZERO_PAD]) self.zeroPadButton = Tkinter.Checkbutton( self.chimeraFrame, text="Use leading zeroes so all frame numbers" " are equal length", variable=self.zeroPadVar) self.zeroPadButton.grid(row=1, column=0, columnspan=2) Tkinter.Label(self.chimeraFrame, text="Commands prefixed with" " #N: will be executed at frame N").grid(row=2, column=0, columnspan=2) self._setFrameSubst(initialitem) grp = Pmw.Group(parent, tag_text="Script") grp.grid(row=2, column=0, padx=4, sticky="nsew") parent.rowconfigure(2, weight=1) parent.columnconfigure(0, weight=1) self.scriptText = Tkinter.Text(grp.interior(), spacing1=2, height=20, width=80, wrap='word') self.scriptText.grid(row=0, column=0, sticky='nsew') grp.interior().rowconfigure(0, weight=1) grp.interior().columnconfigure(0, weight=1) self.readScriptDialog = None self.saveDialog = None f = Tkinter.Frame(parent) f.grid(row=3, column=0, sticky="w") from OpenSave import OpenModeless, SaveModeless Tkinter.Button(f, command=lambda: (self.readScriptDialog or setattr( self, 'readScriptDialog', OpenModeless(command=self.readScriptFile, historyID="Movie script"))) and self. readScriptDialog.enter(), pady=0, text="Insert text file...").grid(row=0, column=0) filters = [] for typeName in items: exts = chimera.fileInfo.extensions(typeName) if exts: extension = exts[0] else: extension = None filters.append((typeName, map(lambda e: "*" + e, exts), extension)) Tkinter.Button(f, command=lambda: (self.saveDialog or setattr( self, 'saveDialog', SaveModeless(command=self.saveFile, historyID="Movie script", filters=filters, defaultFilter=self.scriptType.getvalue( )))) and self.saveDialog.enter(), pady=0, text="Save to file...").grid(row=0, column=1)
def __loadBackground(self): if not hasattr(self, '_loadBGDialog'): from OpenSave import OpenModeless self._loadBGDialog = OpenModeless(title='Load Background', command=self._loadBGCB) self._loadBGDialog.enter()
def __init__(self, mav): self.mav = mav OpenModeless.__init__(self, clientPos='s', historyID="MAV residue colors")