示例#1
0
class AnimPlayer(Player, geomsChooser):
    """ provide a player to display/undisplay DejaVu object
    in a cylce making a animation.

    viewer: DejaVu viewer
    height,width are the property of the player gui
    startFrame: frame to begin
    endFrame: last frame to display
    stepSize: step between new frame
    playMode:                  #playMode options:
                               #   0   play once and stop
                               #   1   play continuously in 1 direction
                               #   2   play once in 2 directions
                               #   3   play continuously in 2 directions
    titleStr: title of the gui windows
    counter: gui with a counter on or not
    gui: #1 show the player gui
         #0 player gui not display
    framerate =15.             # number of frame per second to be display
    """
    def __init__(self,
                 viewer,
                 master=None,
                 root=None,
                 height=80,
                 width=200,
                 currentFrameIndex=0,
                 startFrame=0,
                 endFrame=0,
                 maxFrame=0,
                 stepSize=1,
                 playMode=1,
                 titleStr='AnimPlayer',
                 counter=1,
                 gui=1,
                 framerate=15.):

        if master is None:
            master = Tkinter.Toplevel()

        # viewer from which we get the geom to animate
        self.viewer = viewer
        # frame list, is a list of geom .
        # each frame is made of n DejaVu object to be display
        # it a list of tuple, each tuple is a {} and []
        # {} is: {'objname':['geom1','geom2'],'objname':['geom1','geom2']}
        # [] is list of DejaVu object per frame
        self.framelist = []

        Player.__init__(self,
                        master=master,
                        root=root,
                        height=height,
                        width=width,
                        currentFrameIndex=currentFrameIndex,
                        startFrame=startFrame,
                        endFrame=endFrame,
                        maxFrame=maxFrame,
                        stepSize=stepSize,
                        playMode=playMode,
                        titleStr=titleStr,
                        counter=counter,
                        gui=gui,
                        framerate=framerate)

    def nextFrame(self, id):
        """ id: index number of the frame to display.
        undisplay object from previous frame, display object
        of new frame.
        """
        if not self.framelist: return
        id = int(id)
        if id >= len(self.framelist): return

        i = self.currentFrameIndex
        ## undisplay previous object
        frame = self.framelist[i]
        for obj in frame[1]:
            obj.Set(visible=0, redo=0)

        if self.hasCounter and self.gui:
            self.form.ent2.delete(0, 'end')
            self.form.ent2.insert(0, str(id))

        ## display new frame
        currentframe = self.framelist[id]
        for obj in currentframe[1]:
            obj.Set(visible=1, redo=0)

        self.viewer.deleteOpenglList()
        self.viewer.Redraw()
        self.currentFrameIndex = id

#####################################################################
#### Animation Setting the frame

    def SetAnim_cb(self):
        self.showForm()

    def showForm(self):
        """create formdescr for setAnim
        form to set the animation:
        each frame is a list of geom to display
        """

        entryFrame = []
        for i in range(len(self.framelist)):
            val = 'frame_' + str(i)
            entryFrame.append((val, ))

        if not hasattr(self, 'form_Setanim'):
            ifd = InputFormDescr(title="SetAnimation")
            ifd.append({
                'widgetType': ListChooser,
                'name': 'availableGeom',
                'tooltip': 'geom available in viewer',
                'wcfg': {
                    'mode': 'extended',
                    'lbwcfg': {
                        'exportselection': 1
                    },
                    'command': [(self.toggleExpansion, '<Double-Button-1>')],
                    'commandEvent': None,
                    'title': 'availableGeom'
                },
                'gridcfg': {
                    'row': 0,
                    'column': 0,
                    'sticky': 'wens',
                    'rowspan': 3
                }
            })
            ifd.append({
                'name': 'newframe',
                'widgetType': Tkinter.Button,
                'tooltip': """ Add an empty frame to the animation""",
                'wcfg': {
                    'text': 'NewFrame',
                    'command': self.addframe_cb
                },
                'gridcfg': {
                    'row': 0,
                    'column': 1,
                    'rowspan': 1
                }
            })

            ifd.append({
                'name': 'add',
                'widgetType': Tkinter.Button,
                'tooltip': """ Add the selected geom to selected frame""",
                'wcfg': {
                    'text': 'AddGeom',
                    'command': self.add_cb
                },
                'gridcfg': {
                    'row': 1,
                    'column': 1,
                    'rowspan': 1
                }
            })

            ifd.append({
                'name': 'geomtoload',
                'widgetType': ListChooser,
                'tooltip': """list of frame  the user chose to
                        apply to the pattern""",
                'wcfg': {
                    'entries': entryFrame,
                    'mode': 'extended',
                    'lbwcfg': {
                        'exportselection': 0
                    },
                    'title': 'Frame(geom) to be display'
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 0,
                    'column': 2,
                    'rowspan': 3
                }
            })
            ifd.append({
                'name': 'remove',
                'widgetType': Tkinter.Button,
                'tooltip': """ Remove the selected entry from the
                        commands to be applied to the object when loaded in the application""",
                'wcfg': {
                    'text': 'REMOVE',
                    'width': 10,
                    'command': self.remove_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 0,
                    'column': 3
                }
            })

            ifd.append({
                'name': 'oneup',
                'widgetType': Tkinter.Button,
                'tooltip': """Move the selected entry up one entry""",
                'wcfg': {
                    'text': 'Move up',
                    'width': 10,
                    'command': self.moveup_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 1,
                    'column': 3
                }
            })

            ifd.append({
                'name': 'onedown',
                'widgetType': Tkinter.Button,
                'tooltip': """Move the selected entry down one entry""",
                'wcfg': {
                    'text': 'Move down',
                    'width': 10,
                    'command': self.movedown_cb
                },
                'gridcfg': {
                    'sticky': 'we',
                    'row': 2,
                    'column': 3
                }
            })

            self.form_Setanim = InputForm(self.master,
                                          None,
                                          descr=ifd,
                                          scrolledFrame=0)

            self.lc = self.form_Setanim.descr.entryByName['availableGeom'][
                'widget']
            self.lc2 = self.form_Setanim.descr.entryByName['geomtoload'][
                'widget']
            self.addObject(self.viewer.rootObject, None)
            val = self.form_Setanim.go()
            if val:
                self.assign()
                self.form_Setanim.withdraw()
        else:
            self.form_Setanim.deiconify()
            val = self.form_Setanim.go()
            if val:
                self.assign()
                self.form_Setanim.withdraw()

    def deleteAnim(self):
        """ Delete all frame from the player list."""

        self.Stop_cb()
        self.startFrame = 0
        self.endFrame = -1
        self.maxFrame = 0
        self.targetFrame = self.endFrame
        self.target = self.endFrame
        self.currentFrameIndex = 0

    def assign(self, list=None):
        """ assign the animation.
        framelist ; list of {}
        return a list of obj for each frame
        """
        self.deleteAnim()
        AllObjects = self.viewer.rootObject.AllObjects()
        if list:
            self.framelist = []
            for f in list:
                self.framelist.append((f, []))
        print "assign"
        print "self.framelist", self.framelist
        for frame in self.framelist:
            geomDic = frame[0]
            Namelist = []
            for parents in geomDic.keys():
                parentlist = filter(lambda x, name=parents: x.name == name,
                                    AllObjects)
                obj = parentlist[0]
                childrens = geomDic[obj.name]
                if len(childrens) > 0:
                    for namegeom in childrens:
                        child = filter(lambda x, name=namegeom: x.name == name,
                                       obj.children)[0]
                        if child.children != []:
                            for c in child.children:
                                frame[1].append(c)
                        else:
                            frame[1].append(child)
                else:
                    frame[1].append(obj)

            self.endFrame = self.endFrame + 1
            self.maxFrame = self.maxFrame + 1
            self.targetFrame = self.endFrame
            self.target = self.endFrame

    def movedown_cb(self):
        """ move entry one down """
        sel = self.lc2.get()
        index = self.lc2.getInd()
        if not sel: return
        sel = sel[0]
        if string.find(sel, "frame") < 0: return
        # get frame Index
        frameInd = int(string.split(sel, '_')[1])
        currentframe = self.framelist[frameInd]
        if (frameInd + 1) >= len(self.framelist): return
        # select next Frame.
        nextframe = self.framelist[frameInd + 1]
        # move current frame one down in list
        self.framelist[frameInd] = nextframe
        self.framelist[frameInd + 1] = currentframe
        self.updatelistchooser(self.framelist)

    def moveup_cb(self):
        """ move entry one up """
        sel = self.lc2.get()
        index = self.lc2.getInd()
        if not sel: return
        sel = sel[0]
        if string.find(sel, "frame") < 0: return
        # get frame Index
        frameInd = int(string.split(sel, '_')[1])
        currentframe = self.framelist[frameInd]
        if (frameInd - 1) < 0: return
        # select previous Frame
        prevframe = self.framelist[frameInd - 1]
        # move current frame one up in list
        self.framelist[frameInd] = prevframe
        self.framelist[frameInd - 1] = currentframe
        self.updatelistchooser(self.framelist)

    def addframe_cb(self):
        """ add a new frame entry"""
        frame = ({}, [])
        nb = len(self.framelist)
        #frame.number = nbframe
        value = 'frame_' + str(nb)
        self.framelist.append(frame)
        self.lc2.deselect(0, last='end')
        self.lc2.insert('end', value)
        self.lc2.select('end')

    def add_cb(self):
        listgeom = []
        # get the frame index to add new geom
        if len(self.lc2.entries) > 0:
            ind = self.lc2.getInd()
            if len(ind) == 0: return  # no entry selected so create a new frame
            # get geom name to load
            o = map(int, self.lc.lb.curselection())
            for Ind in o:
                fullName = self.getFullName(Ind)
                listgeom.append(fullName)
            # get frame instance
            for index in ind:
                value = self.lc2.entries[index][0]
                if string.find(value, "frame") < 0: return
                frameInd = int(string.split(value, '_')[1])
                frameGeom = self.framelist[frameInd][0]
                for geom in listgeom:
                    # strip the root
                    l = string.split(geom, '|')
                    if not frameGeom.has_key(l[1]):
                        frameGeom[l[1]] = []
                    for i in l[2:]:
                        if not (i in frameGeom[l[1]]):
                            frameGeom[l[1]].append(i)

            self.updatelistchooser(self.framelist)
        else:
            return

    def updatelistchooser(self, entry):
        """ update what is display in the list chooser """
        # save current selection
        sel = self.lc2.get()
        # remove current entry
        self.lc2.clear()
        prefix = '~'
        prefix2 = '~~'
        nb = 0
        for e in entry:
            v = 'frame_' + str(nb)
            nb = nb + 1
            # listchooser entry has to be a tuple(value,comment)
            self.lc2.add((v, ))
            for mol in e[0].keys():
                self.lc2.add((prefix + mol, ))
                for geom in e[0][mol]:
                    self.lc2.add((prefix2 + geom, ))
        # select the entry save as sel
        # keep the entry selected after the update
        for i in sel:
            self.lc2.select((i, ))

    def findFramefromGeomInd(self, index):
        """ return the frame number from  which the geom was selected """
        for i in range(index + 1):
            value = self.lc2.entries[index - i][0]
            if string.find(value, "frame") >= 0:
                frameInd = int(string.split(value, '_')[1])
                lcInd = index - i
                return (frameInd, lcInd)
        return 0

    def findParentGeom(self, index):
        """ find the parent value name from a geom ~~
        go up to find first value with onley ~ """
        parent = None
        for i in range(index + 1):
            parent = self.lc2.entries[index - i][0]
            if parent[0] == '~' and parent[1] != '~':
                parent = parent[1:]
                return parent
        return None

    def removeEntryGeom(self, value, index):
        """ the geom entry in the listchooser"""
        # first find from which frame we need to remove geom
        val = self.findFramefromGeomInd(index)
        if val:
            frameInd = val[0]
            lcInd = val[1]
            if value[1] == '~':
                parent = self.findParentGeom(index)
                if parent:
                    listgeom = self.framelist[frameInd][0][parent]
                    rindex = listgeom.index(value[2:])
                    del listgeom[rindex]

            elif self.framelist[frameInd][0].has_key(value[1:]):
                del self.framelist[frameInd][0][value[1:]]

            self.updatelistchooser(self.framelist)

    def removeEntryFrame(self, value, index):
        """ remove the frame entry in the listchooser"""
        # delete frame from framelist
        frameInd = int(string.split(value, '_')[1])
        del self.framelist[frameInd]
        # Update list chooser
        self.updatelistchooser(self.framelist)

    def remove_cb(self):
        """ remove entry in litschooser (geomtoload)"""
        selindex = self.lc2.getInd()
        for index in selindex:
            value = self.lc2.entries[index][0]
            if string.find(value, "frame") >= 0:
                self.removeEntryFrame(value, index)
            elif value[0] == '~':
                self.removeEntryGeom(value, index)
示例#2
0
class Recorder(Tkinter.Frame):
    """Implements GUI for recording movie clips( *.mpg)"""
    def __init__(self,
                 master=None,
                 height=80,
                 width=100,
                 title="Video recorder",
                 icondir=None,
                 filetypes=[("MPG", ".mpg")],
                 fileName=None,
                 camera=None,
                 gui=True):
        self.ifd = None
        self.form = None
        self.paramForm = None
        self.ifd2 = None
        self.fileName = fileName

        self.autoPauseDelay = 1  # auto pause after 1 second
        self.pauseLength = 30
        self.cameraw = 0
        self.camerah = 0
        self.camera = weakref.ref(camera)
        if self.camera():
            self.cameraw = camera.width
            self.camerah = camera.height

        if not icondir:
            icondir = findFilePath('icons', 'mglutil.gui.BasicWidgets.Tk')
        self.stopIcon = Tkinter.PhotoImage(file=os.path.join(
            icondir, "stop3.gif"),
                                           master=master)
        self.pauseIcon = Tkinter.PhotoImage(file=os.path.join(
            icondir, "stop2.gif"),
                                            master=master)
        self.recordIcon = Tkinter.PhotoImage(file=os.path.join(
            icondir, "record.gif"),
                                             master=master)
        self.record1Icon = Tkinter.PhotoImage(file=os.path.join(
            icondir, "record1.gif"),
                                              master=master)
        self.chmodIcon = Tkinter.PhotoImage(file=os.path.join(
            icondir, 'chmod.gif'),
                                            master=master)
        self.closeIcon = Tkinter.PhotoImage(file=os.path.join(
            icondir, 'close.gif'),
                                            master=master)
        self.fileTypes = filetypes
        if gui:
            self.RecVar = Tkinter.IntVar()
            self.RecVar.set(0)
            self.PauseVar = Tkinter.IntVar()
            self.PauseVar.set(0)
            form = self.buildForm(master=master,
                                  title=title,
                                  height=height,
                                  width=width)
            form.deiconify()

    def buildForm(self, master=None, width=100, height=80, title=None):
        if self.form:
            self.form.deiconify()
            self.createKeyBindings()
            return
        self.master = master
        ifd = self.ifd = InputFormDescr(title=title)
        ifd.append({
            'name': 'fileopen',
            'widgetType': Tkinter.Button,
            'tooltip': "Opens file browser",
            'wcfg': {
                'text': "Save As:",
                'command': self.browseFile,
                'width': 0,
                'height': 0,
            },
            'gridcfg': {
                'sticky': 'w',
                'column': 0
            }
        })
        ifd.append({
            'name': 'filename',
            'widgetType': Pmw.EntryField,
            'tooltip': "type filename",
            'gridcfg': {
                'sticky': 'w',
                #'columnspan': 3},
                'columnspan': 2,
                'row': -1
            },
            'wcfg': {
                'command': self.getFileName,
                #'label_text':'Save As',
                'entry_width': 12,
                'value': self.fileName,
                #'labelpos':'w'}})
            }
        })

        ## ifd.append({'name':'fileopen',
        ##                     'widgetType':Tkinter.Button,
        ##                     'tooltip': "Open file browser",
        ##                     'wcfg':{'text':"...",
        ##                             'command': self.browseFile,
        ##                             'width': 0, 'height': 0,},
        ##                     'gridcfg':{'sticky':'w', 'column':2, 'row':-1}
        ##                     })
        ifd.append({
            'name': 'recordB',
            'widgetType': Tkinter.Checkbutton,
            'tooltip': 'start/stop recording',
            'wcfg': {
                'variable': self.RecVar,
                'bd': 2,
                'image': self.record1Icon,
                'width': self.record1Icon.width(),
                'height': self.record1Icon.height(),
                'indicatoron': 0,
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1
            },
            'command': self.record_cb
        })

        ifd.append({
            'name': 'pauseB',
            'widgetType': Tkinter.Checkbutton,
            'tooltip': 'pause/start recording',
            'wcfg': {
                'variable': self.PauseVar,
                'bd': 2,
                'image': self.pauseIcon,
                'width': self.pauseIcon.width(),
                'height': self.pauseIcon.height(),
                'indicatoron': 0,
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1
            },
            'command': self.pause_cb
        })

        ifd.append({
            'name': 'stopB',
            'widgetType': Tkinter.Button,
            'tooltip': 'stop recording',
            'wcfg': {
                'bd': 2,
                'image': self.stopIcon,
                'width': self.stopIcon.width(),
                'height': self.stopIcon.height(),
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1
            },
            'command': self.stop_cb
        })

        ##         ifd.append({'name': 'recordB',
        ##                     'widgetType': Tkinter.Button,
        ##                     'tooltip':'start/pause recording',
        ##                     'wcfg':{'bd':4,
        ##                             'image':self.recordIcon,
        ##                             'width':self.recordIcon.width(),
        ##                             'height':self.recordIcon.height()
        ##                             },
        ##                     'gridcfg':{'sticky':'nesw','row':-1},
        ##                     'command':self.record_cb})

        ##         ifd.append({'name': 'pauseB',
        ##                     'widgetType': Tkinter.Button,
        ##                     'tooltip':'pause recording',
        ##                     'wcfg':{'bd':4,
        ##                             'image':self.pauseIcon,
        ##                             'width':self.pauseIcon.width(),
        ##                             'height':self.pauseIcon.height()
        ##                             },
        ##                     'gridcfg':{'sticky':'nesw', 'row':-1},
        ##                     'command':self.pause_cb})

        ##         ifd.append({'name': 'modeB',
        ##                     'widgetType': Tkinter.Button,
        ##                     'text':'Change Mode',
        ##                     'tooltip':'opens panel to change video parameters',
        ##                     'wcfg':{'bd':4,
        ##                             'image':self.chmodIcon,
        ##                             'width':self.chmodIcon.width(),
        ##                             'height':self.chmodIcon.height()
        ##                             },
        ##                     'gridcfg':{'sticky':'nesw','row':-1},
        ##                     'command':self.setparams_cb })

        ##         ifd.append({'name': 'closeB',
        ##             'widgetType': Tkinter.Button,
        ##             'text':'Close',
        ##             'tooltip':'closes video recorder',
        ##             'wcfg':{'bd':2,
        ##                     'image':self.closeIcon,
        ##                     'width':self.closeIcon.width(),
        ##                     'height':self.closeIcon.height(),
        ##                     },
        ##             'gridcfg':{'sticky':'nesw','row':-1},
        ##             'command':self.close_cb})
        form = self.form = InputForm(self.master,
                                     None,
                                     descr=ifd,
                                     modal=0,
                                     blocking=0,
                                     closeWithWindow=1,
                                     onDestroy=self.close_cb)
        self.createKeyBindings()
        return form

    def getFileName(self):
        """ Get file name from the input form's entry field."""
        if self.ifd:
            name = self.ifd.entryByName['filename']['widget'].get()
            if name:
                if self.fileName != name:
                    self.fileName = name

    def browseFile(self):
        """Opens file browser."""

        fileDir = None
        if self.fileName:
            if path.exists(self.fileName):
                fileDir = path.dirname(path.realpath(self.fileName))
            else:
                fileDir = os.getcwd()
        file = tkFileDialog.asksaveasfilename(filetypes=self.fileTypes,
                                              initialdir=fileDir,
                                              initialfile=None,
                                              title="Save file")
        if file:
            if self.fileName != file:
                self.fileName = file
                self.ifd.entryByName['filename']['widget'].setentry(file)

    def record_cb(self):

        #get the value of the Record checkbutton
        val = self.RecVar.get()
        if val:  #checked
            self.getFileName()
            res = 1
            if self.camera:
                if self.camera().videoRecordingStatus == "stopped":
                    #kw = {'filename':self.fileName, 'width':self.cameraw, 'hight':self.camerah,
                    #      'autoPauseDelay': self.autoPauseDelay,'pauseLength':self.pauseLength}
                    #kw = {'filename':self.fileName }
                    #apply(self.setVideoParams, (), kw)
                    if os.path.exists(self.fileName):
                        # ask the user if he wants to overwrite the existing file
                        from Dialog import Dialog
                        d = Dialog(
                            None, {
                                'title':
                                'File exisits',
                                'text':
                                'File "%s" already exists.'
                                ' Do you want to overwrite it ?' %
                                self.fileName,
                                'bitmap':
                                'warning',
                                'default':
                                1,
                                'strings': ('Yes', 'No')
                            })
                        ans = d.num
                        if ans == 1:  #no
                            self.RecVar.set(0)
                            return
                    res = self.setVideoParams(filename=self.fileName)
                if res:
                    #print "record_cb: recording"
                    self.camera().start()
            if self.ifd:
                b = self.ifd.entryByName['recordB']['widget']
                if res:
                    b.config(image=self.recordIcon)
                    pauseval = self.PauseVar.get()
                    if pauseval:
                        self.PauseVar.set(0)  #uncheck the Pause checkbutton
        else:  #unchecked
            if self.camera:
                #print "record_cb: stop recording"
                self.stop_cb()

    def stop_cb(self):
        #print "stop_cb"
        if self.camera:
            if not self.camera().videoRecordingStatus == 'stopped':
                #print "stop recording"
                self.camera().stop()
            if self.ifd:
                recval = self.RecVar.get()
                if recval:
                    self.RecVar.set(0)  #uncheck the Record checkbutton
                pauseval = self.PauseVar.get()
                if pauseval:
                    self.PauseVar.set(0)  #uncheck the Pause checkbutton
                b = self.ifd.entryByName['recordB']['widget']
                b.config(image=self.record1Icon)

    def pause_cb(self):
        #print "pause_cb"
        val = self.PauseVar.get()
        if self.camera:
            camerastatus = self.camera().videoRecordingStatus
            if val:  # the Pause button is checked
                if camerastatus == 'recording':
                    #print "pause recording"
                    self.camera().pause()
                    #if self.ifd:
                    #b = self.ifd.entryByName['recordB']['widget']
                    #b.config(command = self.record_cb, image=self.recordIcon)
            else:  # the Pause button is unchecked
                if camerastatus == 'paused':
                    #print "start recording after pause"
                    self.record_cb()

    def spacePress_cb(self, event):
        if self.camera:
            camerastatus = self.camera().videoRecordingStatus
            if camerastatus == "stopped" or camerastatus == "paused":
                self.RecVar.set(1)
                self.record_cb()
            elif camerastatus == "recording":
                self.PauseVar.set(1)
                self.pause_cb()

    def setparams_cb(self):
        """Opens a panel to set Video Parameters"""
        if self.paramForm:
            self.paramForm.deiconify()
            return
        self.ifd2 = ifd2 = InputFormDescr(title="Set video options")
        ifd2.append({
            'widgetType': Pmw.EntryField,
            'tooltip': 'Set camera width',
            'name': 'cameraw',
            'gridcfg': {
                'sticky': 'w',
                'columnspan': 2
            },
            'wcfg': {  #'command': self.setCameraWidth_cb,
                'label_text': 'width:',
                'entry_width': 10,
                'validate': {
                    'validator': 'real',
                    'min': 0
                },
                'value': str(self.cameraw),
                'labelpos': 'w'
            }
        })

        ifd2.append({
            'widgetType': Pmw.EntryField,
            'name': 'camerah',
            'tooltip': 'Set camera height',
            'gridcfg': {
                'sticky': 'w',
                'columnspan': 2
            },
            'wcfg': {  #'command': self.setCameraHeight_cb,
                'label_text': 'height',
                'entry_width': 10,
                'validate': {
                    'validator': 'real',
                    'min': 0
                },
                'value': str(self.camerah),
                'labelpos': 'w'
            }
        })
        ifd2.append({
            'name': 'autoPause',
            'wtype': ThumbWheel,
            'widgetType': ThumbWheel,
            'tooltip': 'set auto pause delay (seconds)',
            'wcfg': {
                'labCfg': {
                    'fg': 'black',
                    'side': 'left',
                    'text': 'AutoPause Delay'
                },
                'showLabel': 1,
                'width': 100,
                'min': 0,
                'value': self.autoPauseDelay,
                'oneTurn': 100,
                'type': 'int',
                'increment': 1,
                #'callback':self.setAutoPauseDelay_cb,
                'canvascfg': {
                    'bg': 'red'
                },
                'continuous': 0,
                'wheelPad': 1,
                'height': 15
            },
            'gridcfg': {
                'sticky': 'nesw',
                'columnspan': 2
            }
        })
        ifd2.append({
            'name': 'pauseLength',
            'wtype': ThumbWheel,
            'widgetType': ThumbWheel,
            'tooltip':
            'set number of frames to be added when\nrecording resumes after autopause',
            'wcfg': {
                'labCfg': {
                    'fg': 'black',
                    'side': 'left',
                    'text': 'AutoPause Length'
                },
                'showLabel': 1,
                'width': 100,
                'min': 0,
                'value': self.pauseLength,
                'oneTurn': 100,
                'type': 'int',
                'increment': 1,
                #'callback':self.setPauseLength_cb,
                'canvascfg': {
                    'bg': 'red'
                },
                'continuous': 0,
                'wheelPad': 1,
                'height': 15
            },
            'gridcfg': {
                'sticky': 'nesw',
                'columnspan': 2
            }
        })
        ifd2.append({
            'name': 'okB',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Apply',
                'command': self.apply_cb,
            },
            'gridcfg': {
                'sticky': 'nesw'
            }
        })
        ifd2.append({
            'name': 'cancelB',
            'widgetType': Tkinter.Button,
            'wcfg': {
                'text': 'Cancel',
                'command': self.cancel_cb,
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1,
                'column': 1
            }
        })
        self.paramForm = InputForm(self.master,
                                   None,
                                   descr=ifd2,
                                   modal=0,
                                   blocking=0)
        self.paramForm.deiconify()

        return self.paramForm

    def setCameraWidth_cb(self):
        """ 'Width' entry field callback of the video parameters form ."""
        w = int(self.ifd2.entryByName['cameraw']['widget'].get())
        if w != self.cameraw:
            self.cameraw = w

    def setCameraHeight_cb(self):
        """'Height' entry field callback of the video parameters form ."""
        h = int(self.ifd2.entryByName['camerah']['widget'].get())
        if h != self.camerah:
            self.camerah = h

    def setAutoPauseDelay_cb(self, val):
        """Callback of the autoPause thumbwheel widget (video parameters input form). """
        #print val
        d = int(val)
        if d != self.autoPauseDelay:
            self.autoPauseDelay = d

    def setPauseLength_cb(self, val):
        """Callback of the pauseLength thumbwheel widget (video parameters input form). """
        #print val
        l = int(val)
        if l != self.pauseLength:
            self.pauseLength = l

    def apply_cb(self):
        """Apply button callback of the video parameters input form."""
        kw = {}
        ebn = self.ifd2.entryByName
        w = float(ebn['cameraw']['widget'].get())
        if w != self.cameraw:
            self.cameraw = w
        kw['width'] = w
        h = float(ebn['camerah']['widget'].get())
        if h != self.camerah:
            self.camerah = h
        kw['height'] = h

        d = ebn['autoPause']['widget'].get()
        if d != self.autoPauseDelay:
            self.autoPauseDelay = d
        kw["autoPauseDelay"] = d

        l = ebn['pauseLength']['widget'].get()
        if l != self.pauseLength:
            self.pauseLength = l
        kw['pauseLength'] = l

        #apply(self.setVideoParams, (), kw)
        self.cancel_cb()

    def setVideoParams(self, **kw):
        """ Uses Recordable Camera methods to set file name and other video parameters"""
        #print kw
        if self.camera:
            filename = kw.get('filename')
            if filename:
                try:
                    self.camera().setVideoOutputFile(filename)
                except IOError:
                    button = tkMessageBox.showerror(
                        "IOError",
                        message="Could not open file %s\nfor writing a movie."
                        % filename,
                        parent=self.master)
                    return False
            ## params = {}
##             w = kw.get('width')
##             if w is not None:
##                 params['width'] = w
##             h = kw.get('height')
##             if h is not None:
##                 params['height']= h
##             pl = kw.get('pauseLength')
##             if pl is not None:
##                 params['pauseLength'] = pl
##             apd = kw.get('autoPauseDelay')
##             if apd is not None:
##                 params['autoPauseDelay'] = apd
##             if len(params):
##                 apply(self.camera().setVideoParameters, (), params)

#use default parameters for now
            self.camera().setVideoParameters()
            return True

    def createKeyBindings(self):
        self.master.bind('<KeyPress-space>', self.spacePress_cb)

    def removeKeyBindings(self):
        self.master.unbind('<KeyPress-space>')

    def cancel_cb(self):
        self.paramForm.withdraw()

    def close_cb(self, event=None):
        if hasattr(self, 'form'):
            self.form.withdraw()
        self.removeKeyBindings()
示例#3
0
class Player(Tkinter.Frame):
    """Widget to play sequence of frames.
    The GUI allows to specify direction and speed of playback.

    the nextFrame(number) methoid should be overridden and define how
    this player plays the animation
    
    the root constructor argument can be a Tkinter container in which to
    embde the control panel.
    
    required attributes:
        currentFrameIndex = 0
        startFrame = 0
        endFrame = 0
        maxFrame = 0
        stepSize = 1
        target = endFrame           #determines direction of play
        increment = 1               #implements decrementing vs incrementing
                                    #  in getNextFrameIndex
        playMode = 0                #playMode options:
                                    #   0   play once and stop
                                    #   1   play continuously in 1 direction
                                    #   2   play once in 2 directions
                                    #   3   play continuously in 2 directions
        framerate =15.              # number of frame per second to be display
        hasSlider = False           #adds Tkinter Scale Widget if True

    customization attributes:
        buttonMask is a dictionary that provides a button name as a key and
        a boolean as a value. For each button in the GUI if the name appears
        in self.buttonMask and the value is False the button willnot be
        addded. This only works when form2 is true. slider and counter
        are handle by the hasSlider and coutner keyword arguments

    required methods:
    #play methods:
        play                           #play according to play mode
        getNextFrameIndex              #returns index of next frame to
                                        play according to current index
                                        and playMode
        nextFrame                      #actually display the nextFrame
                                        ??possibly update widgets???

    #methods to regulate play
        Play_cb                        #play according to playMode
        PlayRev_cb                     #play backwards  
        FastForward_cb()               #play foward at max speed
        FastReverse_cb()               #play reverse at max speed
        Stop_cb                        #stop current play
        ?Pause_cb                      #stop at current frame??
        ?Loop_cb                       #???????


    #methods to set Frame to a specific frame
        SetState_cb                    #counter callback for random access
        GoToStart_cb                   #set to current startFrame
        GoToEnd_cb                     #set to current endFrame
        ?setCurrentFrameIndex          #set currentframe index???


    #methods for player gui
        showGUI                        #show the gui
        buildForm2                     #opens image-based gui
        buildForm                      #opens text-based gui
        Close_cb                       #withdraws gui

    #methods for pmw counter
        custom_validate                #used by pmw to check entry
        custom_counter                 #used by pmw for counter


    #methods for changing playMode
        SetMode_cb                     #opens playModeForm
        setPlayMode_cb                 #sets playMode, sets delay,
                                          startFrame, endFrame 
                                          AND closes playModeForm
        cancelPlayMode_cb              #closes playModeForm w/out changes

        #methods for end points:
            setStartFrame()            #set startFrame
            setEndFrame()              #set endFrame
            setStepSize()              #sets increment, def=1
        additional methods:
    """

    def __init__(
        self,
        master=None,
        root=None,
        height=80,
        width=200,
        currentFrameIndex=0,
        startFrame=0,
        endFrame=0,
        maxFrame=0,
        stepSize=1,
        playMode=0,
        ##afterDelay=50,
        titleStr="Player",
        gotoStartfile="go_to_start.gif",
        gotoEndfile="go_to_end.gif",
        ff_revfile="ff_rev.gif",
        ff_fwdfile="ff_fwd.gif",
        stopfile="stop.gif",
        playfile="play_fwd.gif",
        playRevfile="play_rev.gif",
        chmodfile="chmod.gif",
        closefile="close.gif",
        iconpath=None,
        counter=1,
        form2=1,
        gui=1,
        framerate=15.0,
        hasSlider=False,
        buttonMask=None,
    ):

        # frame rate in fps
        self.framerate = framerate
        self.gui = gui
        self.currentFrameIndex = currentFrameIndex
        self.startFrame = startFrame
        self.endFrame = endFrame
        self.targetFrame = self.endFrame
        self.maxFrame = maxFrame
        if not maxFrame:
            self.maxFrame = endFrame
        self.stepSize = stepSize
        # used for play once in 2 directions
        self.oneDirection = 0
        self.increment = 1
        self.target = self.endFrame
        self.hasSlider = hasSlider
        # used to coordinate switching icons
        # playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions and stop
        #   3   play continuously in 2 directions
        self.playMode = playMode
        ### replace by framerate
        # amt of time to sleep
        # self.delay = delay

        # amt of time for after
        # self.afterDelay = afterDelay

        self.afterID = None
        self.stop = 1
        self.hasCounter = 0
        # gui variable
        # self.master = master
        # self.root = root
        self.form2 = form2
        self.hasCounter = counter

        if buttonMask is None:
            self.buttonMask = {}
            # self.buttonMask provides a button name as a key and a boolean
            # as a value. For each button in the GUI if the name appears in
            # self.buttonMask and the value is False the button willnot be
            # addded
        else:
            self.buttonMask = buttonMask

        if gui:
            self.showGUI(master=master, root=root, titleStr=titleStr, height=height, width=width, iconpath=iconpath)

        # make sure we have a master as we will call master.update in play()
        if hasattr(master, "update"):
            self.masterForUpdate = self.master
        else:
            self.masterForUpdate = self.root

    def showGUI(
        self,
        master=None,
        root=None,
        width=200,
        height=80,
        titleStr="player",
        gotoStartfile="go_to_start.gif",
        gotoEndfile="go_to_end.gif",
        ff_revfile="ff_rev.gif",
        ff_fwdfile="ff_fwd.gif",
        stopfile="stop.gif",
        playfile="play_fwd.gif",
        playRevfile="play_rev.gif",
        chmodfile="chmod.gif",
        closefile="close.gif",
        iconpath=None,
    ):
        """ function to display the player gui."""

        if hasattr(self, "form"):
            if hasattr(self.form, "deiconify"):
                self.form.deiconify()
                return
        self.master = master
        self.root = root

        if not self.form2:
            self.form = self.buildForm(titleStr)  # pass some arguments here
            self.form2 = 0
        else:
            if iconpath is None:
                iconpath = ("mglutil.gui.BasicWidgets.Tk", "icons")
            ICONDIR = findFilePath(iconpath[1], iconpath[0])
            # if findFilePath failed, already returned
            gotoStartfile = os.path.join(ICONDIR, gotoStartfile)
            gotoEndfile = os.path.join(ICONDIR, gotoEndfile)
            ff_revfile = os.path.join(ICONDIR, ff_revfile)
            ff_fwdfile = os.path.join(ICONDIR, ff_fwdfile)
            stopfile = os.path.join(ICONDIR, stopfile)
            playfile = os.path.join(ICONDIR, playfile)
            playRevfile = os.path.join(ICONDIR, playRevfile)
            chmodfile = os.path.join(ICONDIR, chmodfile)
            closefile = os.path.join(ICONDIR, closefile)
            recordfile = os.path.join(ICONDIR, "record.gif")
            record1file = os.path.join(ICONDIR, "record1.gif")

            self.gotoStartIcon = Tkinter.PhotoImage(file=gotoStartfile, master=master)
            self.gotoEndIcon = Tkinter.PhotoImage(file=gotoEndfile, master=master)
            self.ff_revIcon = Tkinter.PhotoImage(file=ff_revfile, master=master)
            self.ff_fwdIcon = Tkinter.PhotoImage(file=ff_fwdfile, master=master)
            self.stopIcon = Tkinter.PhotoImage(file=stopfile, master=master)
            self.playIcon = Tkinter.PhotoImage(file=playfile, master=master)
            self.playRevIcon = Tkinter.PhotoImage(file=playRevfile, master=master)
            self.recIcon = Tkinter.PhotoImage(file=recordfile, master=master)
            self.rec1Icon = Tkinter.PhotoImage(file=record1file, master=master)
            self.chmodIcon = Tkinter.PhotoImage(file=chmodfile, master=master)
            self.closeIcon = Tkinter.PhotoImage(file=closefile, master=master)
            self.form = self.buildForm2(titleStr)  # pass some argument here

    # play methods:
    # play, waitTime, getNextFrameIndex, nextFrame
    def play(self, framerate, event=None):
        t1 = time.time()  # previous frame time
        timestamp = 1.0 / framerate  # rate to update frame
        self.stop = 0
        ind = self.currentFrameIndex

        # if player at the end we resume from begining
        if ind >= self.endFrame:
            self.GoToStart_cb()

        while not self.stop:  # this has to be more complex
            if self.stop:
                print "play stopped!"
                break

            # do something different here if ff_fwd or ff_rev
            if self.gui:
                # self.afterID = self.master.after(self.afterDelay, self.waitTime)
                self.masterForUpdate.update()

            t2 = time.time()  # current time
            t = t2 - t1  # time difference between current frame and previous

            if framerate > -1 and t < timestamp:
                pass
            else:
                id = self.getNextFrameIndex(self.currentFrameIndex)
                if id == None:
                    self.stop = 1
                    if self.gui:
                        self.Stop_cb()
                        break
                self.nextFrame(id)  # maybe set entry then call nextFrame??
                self.currentFrameIndex = id
                t1 = t2

    def getNextFrameIndex(self, index):
        newFrame = index + self.increment * self.stepSize
        # check if  newFrame in current range:
        #       if incrementing, has to be <=self.endFrame
        #       if decrementing, has to be >=self.startFrame
        #   NB: incPos indicates whether currently incrementing or decrementing
        # FORCE newFrame into range
        incPos = self.increment > 0
        if incPos and newFrame > self.endFrame:
            newFrame = self.endFrame
        elif not incPos and newFrame < self.startFrame:
            newFrame = self.startFrame
        # check whether reached current targetFrame
        #       if so, action depends on current playMode
        mode = self.playMode
        if index == self.targetFrame:
            # playModes 0 and 2 are play once and stop (in 1 or 2 directions)
            if not mode % 2:
                if mode == 0:
                    # None means stop
                    return None
                else:
                    # play once in 2 directions
                    #   check whether already reached halfway pt
                    if self.oneDirection:
                        return None
                    self.oneDirection = 1
                    # to reverse direction:
                    #   toggle increment
                    self.increment = -1 * self.increment
                    #   toggle targetFrame
                    if self.targetFrame == self.endFrame:
                        self.targetFrame = self.startFrame
                    else:
                        self.targetFrame = self.endFrame
                    return newFrame
            elif self.playMode == 1:
                # play continuously in 1 direction
                # toggle targetFrame to the opposite end
                if self.targetFrame == self.endFrame:
                    return self.startFrame
                else:
                    return self.endFrame
            elif self.playMode == 3:
                # loop continuously in 2 directions
                #   toggle increment
                self.increment = -1 * self.increment
                newFrame = self.targetFrame + self.stepSize * self.increment
                #   toggle targetFrame
                if self.targetFrame == self.endFrame:
                    self.targetFrame = self.startFrame
                else:
                    self.targetFrame = self.endFrame
                return newFrame
        return newFrame

    ##     def waitTime(self):
    ##         self.afterID = None
    ##         t1 = time.time()
    ##         delta = time.time() - t1
    ##         #curBut is either play or playRev button
    ##         hasCurBut = hasattr(self, 'curBut')
    ##         while delta < self.delay:
    ##             if hasCurBut:
    ##                 self.curBut.config(bg='red')
    ##             self.master.update()
    ##             time.sleep(self.delay/100)
    ##             delta = time.time() - t1
    ##         if hasCurBut:
    ##             self.curBut.config(bg='white')
    ##         if self.afterID is not None and hasCurBut:
    ##             self.curBut.after_cancel(self.afterID)
    ##             self.afterID = self.curBut.after(self.afterDelay, self.waitTime)

    def nextFrame(self, id):
        ##pass #must be overriden
        id = int(id)
        if id == self.currentFrameIndex:
            return
        if self.hasCounter and self.gui:
            self.form.ent2.delete(0, "end")
            self.form.ent2.insert(0, str(id))
            if self.hasSlider:
                self.form.ifd.entryByName["slider"]["widget"].set(id)
        print "playing ", id
        self.currentFrameIndex = int(id)

    # methods to call play
    # Play_cb, PlayRev_cb, FastForward_cb, FastReverse_cb
    # Stop_cb and possibly Pause_cb, Loop_cb
    def startRecording_cb(self, event=None):
        pass

    def stopRecording_cb(self, event=None):
        pass

    def Play_cb(self, framerate=None, event=None):
        # print 'Play_cb'
        self.form.ifd.entryByName["playB"]["widget"].grab_release()
        # this is a new call to Play_cb
        if framerate == None:
            framerate = self.framerate
        self.stop = 0
        self.oneDirection = 0
        self.targetFrame = self.endFrame
        self.increment = 1
        # print 'currentFrameIndex=', self.currentFrameIndex
        # possibly currently playing reverse
        if hasattr(self, "curBut") and self.curBut == self.form.playRevB:
            if self.form2:
                self.curBut.config(command=self.oldCmd, image=self.oldImage, bg="white")
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
        self.oldTT = self.form.playTT
        self.oldTTtext = "play forward according to current play mode"
        self.curBut = self.form.playB
        self.oldCmd = self.Play_cb
        self.oldImage = self.playIcon
        self.oldText = "Play"
        if self.form2:
            self.curBut.config(command=self.Stop_cb, image=self.stopIcon)
        else:
            self.curBut.config(command=self.Stop_cb, text="Stop")
        self.oldTT.bind(self.curBut, "stop play")
        # self.master.update()
        self.play(framerate)
        self.stopRecording_cb()

    def PlayRev_cb(self, framerate=None, event=None):
        # figure out current number and then play backwards
        # print 'currentFrameIndex=', self.currentFrameIndex
        self.form.ifd.entryByName["playRevB"]["widget"].grab_release()
        if framerate == None:
            framerate = self.framerate
        self.increment = -1
        self.targetFrame = self.startFrame
        self.oneDirection = 0
        self.stop = 0
        # possibly currently playing
        if hasattr(self, "curBut") and self.curBut == self.form.playB:
            if self.form2:
                self.curBut.config(command=self.oldCmd, image=self.oldImage, bg="white")
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
        self.oldTT = self.form.playRevTT
        self.oldTTtext = "play reverse according to current play mode"
        self.curBut = self.form.playRevB
        self.oldCmd = self.PlayRev_cb
        self.oldImage = self.playRevIcon
        self.oldText = "Play Reverse"
        if self.form2:
            self.curBut.config(command=self.Stop_cb, image=self.stopIcon)
        else:
            self.curBut.config(command=self.Stop_cb, text="Stop")
        self.oldTT.bind(self.curBut, "stop play")
        self.play(framerate)

    def FastReverse_cb(self, event=None):
        # print 'FastReverse'
        # framerate = self.framerate * 2
        self.oneDirection = 0
        self.PlayRev_cb(framerate=-1)  # framerate)

    def FastForward_cb(self, event=None):
        # print 'FastForward'
        self.oneDirection = 0
        # framerate = self.framerate * 2
        self.Play_cb(framerate=-1)

    def Stop_cb(self, event=None):
        self.stop = 1
        if hasattr(self, "curBut"):
            if self.form2:
                self.curBut.config(command=self.oldCmd, image=self.oldImage)
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
                # FIX THIS!!!!
                # DECIDE if stop means reset to start or not
                # self.nextFrame(self.startFrame)
            self.oldTT.bind(self.curBut, self.oldTTtext)

        self.stopRecording_cb()

        # FIX THIS: does this go here?  or in nextFrame
        # clean up form
        # if self.hasCounter:
        #    self.form.ent2.delete(0,'end')
        #    self.form.ent2.insert(0, str(self.currentFrameIndex))

    # these may be superfluous: called by original form
    def PlayReturn_cb(self, event=None):
        # print 'PlayReturn_cb'
        # this should be superfluous
        self.playMode = 3
        self.Play_cb()

    def Loop_cb(self, event=None):
        # print 'Loop_cb'
        # this should be superfluous
        self.playMode = 3
        self.Play_cb()

    def Pause_cb(self, event=None):
        self.stop = 1

    # methods to set Frame to a specific frame
    # SetState_cb, GoToStart_cb, GoToEnd_cb, setCurrentFrameIndex
    def SetState_cb(self, event=None):
        # do nothing if no counter
        if self.hasCounter:
            index = self.form.counter.get()
            self.nextFrame(index)

    def GoToStart_cb(self, event=None):
        # print "GoToStart_cb", self.startFrame, self.currentFrameIndex
        # self.currentFrameIndex = self.startFrame
        self.oneDirection = 0
        self.nextFrame(self.startFrame)

    def GoToEnd_cb(self, event=None):
        # print 'GoToEnd'
        self.oneDirection = 0
        # self.currentFrameIndex = self.endFrame
        self.nextFrame(self.endFrame)

    def setCurrentFrameIndex(self, index):
        # print 'setting currentFrameIndex to', index
        self.currentFrameIndex = index

    # methods for player gui
    def Close_cb(self, event=None):
        self.stop = 1
        if hasattr(self, "form"):
            self.form.withdraw()

    def SetAnim_cb(self):
        """ function to be overwritten.
        Use to call a functoin to set the animatiom frame."""

        return

    def buildForm2(self, titleStr):
        self.stop = 1
        if hasattr(self, "form"):
            if hasattr(self.form, "deiconify"):
                self.form.deiconify()
                return
        maxval = self.endFrame
        ifd = InputFormDescr(title=titleStr)

        if self.buttonMask.get("gotoStartB", None) is not False:
            ifd.append(
                {
                    "name": "gotoStartB",
                    "widgetType": Tkinter.Button,
                    #'text':'gotoStart',
                    "tooltip": "sets frame to current startFrame",
                    "wcfg": {
                        "bd": 4,
                        "image": self.gotoStartIcon,
                        "width": self.gotoStartIcon.width(),
                        "height": self.gotoStartIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw"},
                    "command": self.GoToStart_cb,
                }
            )

        if self.buttonMask.get("fastReverseB", None) is not False:
            ifd.append(
                {
                    "name": "fastReverseB",
                    "widgetType": Tkinter.Button,
                    #'text':'fastReverse',
                    "tooltip": "play reverse as fast as possible",
                    "wcfg": {
                        "bd": 4,
                        "image": self.ff_revIcon,
                        "width": self.ff_revIcon.width(),
                        "height": self.ff_revIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 1},
                    "command": self.FastReverse_cb,
                }
            )

        if self.buttonMask.get("playRevB", None) is not False:
            ifd.append(
                {
                    "name": "playRevB",
                    "widgetType": Tkinter.Button,
                    #'text':'Play Reverse',
                    "tooltip": "play reverse according to current play mode",
                    "wcfg": {
                        "bd": 4,
                        "image": self.playRevIcon,
                        "width": self.playRevIcon.width(),
                        "height": self.playRevIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 2},
                    "command": self.PlayRev_cb,
                }
            )

            if self.hasCounter:
                ifd.append(
                    {
                        "widgetType": Pmw.Counter,
                        "name": "statesCounter",
                        "required": 1,
                        "tooltip": "used to show frames via random access",
                        "wcfg": {  #'labelpos': 'n,
                            #'label_text':'conformation:  ',
                            "autorepeat": 0,
                            "entryfield_value": self.startFrame,
                            #'entryfield_value':self.idList[0],
                            "datatype": self.custom_counter,
                            "entry_width": 3,
                            "entryfield_validate": self.custom_validate,
                        },
                        "gridcfg": {"sticky": "nesw", "row": -1, "column": 3, "columnspan": 2},
                    }
                )

        if self.buttonMask.get("playB", None) is not False:
            ifd.append(
                {
                    "name": "playB",
                    "widgetType": Tkinter.Button,
                    #'text':'Play',
                    "tooltip": "play forward according to current play mode",
                    "wcfg": {
                        "bd": 4,
                        "image": self.playIcon,
                        "width": self.playIcon.width(),
                        "height": self.playIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 5},
                    "command": self.Play_cb,
                }
            )

        if self.buttonMask.get("fastForwardB", None) is not False:
            ifd.append(
                {
                    "name": "fastForwardB",
                    "widgetType": Tkinter.Button,
                    #'text':'fastForward',
                    "tooltip": "play as fast as possible",
                    "wcfg": {
                        "bd": 4,
                        "image": self.ff_fwdIcon,
                        "width": self.ff_fwdIcon.width(),
                        "height": self.ff_fwdIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 6},
                    "command": self.FastForward_cb,
                }
            )

        if self.buttonMask.get("gotoEndB", None) is not False:
            ifd.append(
                {
                    "name": "gotoEndB",
                    "widgetType": Tkinter.Button,
                    #'text':'gotoEnd',
                    "tooltip": "sets frame to current endFrame",
                    "wcfg": {
                        "bd": 4,
                        "image": self.gotoEndIcon,
                        "width": self.gotoEndIcon.width(),
                        "height": self.gotoEndIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 7},
                    "command": self.GoToEnd_cb,
                }
            )

        if self.buttonMask.get("modeB", None) is not False:
            ifd.append(
                {
                    "name": "modeB",
                    "widgetType": Tkinter.Button,
                    "text": "Change Mode",
                    "tooltip": "opens panel to change play options",
                    "wcfg": {
                        "bd": 4,
                        "image": self.chmodIcon,
                        "width": self.chmodIcon.width(),
                        "height": self.chmodIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 8},
                    "command": self.SetMode_cb,
                }
            )

        if pymediaFound and self.buttonMask.get("recordB", None) is not False:
            ifd.append(
                {
                    "name": "recordB",
                    "widgetType": Tkinter.Checkbutton,
                    "text": "Record",
                    "tooltip": "record an mpeg movie into movie_####.mpg",
                    "defaultValue": 0,
                    "wcfg": {
                        "bd": 4,
                        "variable": Tkinter.IntVar(),
                        "image": self.recIcon,
                        "width": self.recIcon.width(),
                        "height": self.recIcon.height(),
                        "indicatoron": 0,
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 9},
                    "command": self.startRecording_cb,
                }
            )

        if self.buttonMask.get("setanimB", None) is not False:
            ifd.append(
                {
                    "name": "setanimB",
                    "widgetType": Tkinter.Button,
                    "text": "SetAnim",
                    "tooltip": "Set Animation",
                    "wcfg": {"bd": 4},
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 10},
                    "command": self.SetAnim_cb,
                }
            )

        if self.buttonMask.get("closeB", None) is not False:
            ifd.append(
                {
                    "name": "closeB",
                    "widgetType": Tkinter.Button,
                    "text": "Close",
                    "tooltip": "closes player",
                    "wcfg": {
                        "bd": 4,
                        "image": self.closeIcon,
                        "width": self.closeIcon.width(),
                        "height": self.closeIcon.height(),
                    },
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 11},
                    #'gridcfg':{'sticky':'nesw', 'columnspan':2},
                    "command": self.Close_cb,
                }
            )

        if self.hasSlider:
            ifd.append(
                {
                    "name": "slider",
                    "widgetType": Tkinter.Scale,
                    "wcfg": {"orient": "horizontal", "from_": self.startFrame, "to": self.maxFrame, "showvalue": False},
                    "gridcfg": {"sticky": "nesw", "row": 1, "column": 0, "columnspan": 12},
                    "command": self.nextFrame,
                }
            )
        # form = self.vf.getUserInput(ifd, modal=0,blocking=0)
        form = InputForm(self.master, self.root, descr=ifd, modal=0, blocking=0, closeWithWindow=1)
        form.ifd = ifd
        form.playB = form.ifd.entryByName["playB"]["widget"]
        form.playRevB = form.ifd.entryByName["playRevB"]["widget"]
        # set up link to balloon help which needs to change, also
        form.playTT = form.ifd.entryByName["playB"]["balloon"]
        form.playRevTT = form.ifd.entryByName["playRevB"]["balloon"]
        if self.hasCounter:
            ctr = ifd.entryByName["statesCounter"]["widget"]
            entF = ctr.component("entryfield")
            form.ent2 = entF._entryFieldEntry
            da = ctr.component("downarrow")
            ua = ctr.component("uparrow")
            for item in [da, ua]:
                item.bind("<ButtonPress-1>", self.SetState_cb, "+")
            form.ent2.bind("<Return>", self.SetState_cb, "+")
            form.counter = form.ifd.entryByName["statesCounter"]["widget"]
        if self.hasSlider:
            slider = form.ifd.entryByName["slider"]["widget"]
            slider.set(self.currentFrameIndex)
        # print 'returning form'
        return form

    def buildForm(self, titleStr):
        # ??FIX THIS:
        self.stop = 1
        if hasattr(self, "form"):
            self.form.deiconify()
            return
        maxval = self.endFrame
        ifd = InputFormDescr(title=titleStr)
        if self.hasCounter:
            ifd.append(
                {
                    "widgetType": Pmw.Counter,
                    "name": "statesCounter",
                    "required": 1,
                    "tooltip": "used to show frames via random access",
                    "wcfg": {  #'labelpos': 'n,
                        #'label_text':'conformation:  ',
                        "autorepeat": 0,
                        "entryfield_value": self.startFrame,
                        #'entryfield_value':self.idList[0],
                        "datatype": self.custom_counter,
                        "entry_width": 9,
                        "entryfield_validate": self.custom_validate,
                    },
                    "gridcfg": {"sticky": "nesw", "columnspan": 2},
                }
            )
        ifd.append(
            {
                "name": "playB",
                "widgetType": Tkinter.Button,
                "text": "Play",
                "tooltip": "play sequence according to current play mode",
                "wcfg": {"bd": 4},
                "gridcfg": {"sticky": "nesw", "columnspan": 1},
                "command": self.Play_cb,
            }
        )
        ifd.append(
            {
                "name": "playRevB",
                "widgetType": Tkinter.Button,
                "text": "Play Reverse",
                "wcfg": {"bd": 4},
                "gridcfg": {"sticky": "nesw", "row": -1, "column": 1},
                "command": self.PlayRev_cb,
            }
        )
        ifd.append(
            {
                "name": "playTB",
                "widgetType": Tkinter.Button,
                "text": "Play+Return",
                "wcfg": {"bd": 4},
                "gridcfg": {"sticky": "nesw", "columnspan": 1},
                "command": self.PlayReturn_cb,
            }
        )
        ifd.append(
            {
                "name": "loopB",
                "widgetType": Tkinter.Button,
                "text": "Loop",
                "wcfg": {"bd": 4},
                "gridcfg": {"sticky": "nesw", "row": -1, "column": 1},
                "command": self.Loop_cb,
            }
        )
        ifd.append(
            {
                "name": "stopB",
                "widgetType": Tkinter.Button,
                "text": "Stop",
                "tooltip": "stop play",
                "wcfg": {"bd": 4},
                "gridcfg": {"sticky": "nesw"},
                "command": self.Stop_cb,
            }
        )
        # add fastforward, fastrewind, thumbwheel for speed
        ifd.append(
            {
                "name": "pauseB",
                "widgetType": Tkinter.Button,
                "text": "Pause",
                "wcfg": {"bd": 4},
                "gridcfg": {"sticky": "nesw", "row": -1, "column": 1},
                "command": self.Pause_cb,
            }
        )

        ifd.append(
            {
                "name": "closeB",
                "widgetType": Tkinter.Button,
                "text": "Close",
                "wcfg": {"bd": 4},
                #'gridcfg':{'sticky':'nesw','row':-1, 'column':1},
                "gridcfg": {"sticky": "nesw", "columnspan": 2},
                "command": self.Close_cb,
            }
        )
        form = InputForm(self.master, self.root, descr=ifd, modal=0, blocking=0, closeWithWindow=1)
        form.ifd = ifd
        if self.hasCounter:
            ctr = ifd.entryByName["statesCounter"]["widget"]
            entF = ctr.component("entryfield")
            form.ent2 = entF._entryFieldEntry
            da = ctr.component("downarrow")
            ua = ctr.component("uparrow")
            for item in [da, ua]:
                item.bind("<ButtonPress-1>", self.SetState_cb, "+")
            form.ent2.bind("<Return>", self.SetState_cb, "+")
            form.counter = form.ifd.entryByName["statesCounter"]["widget"]
        form.stopB = form.ifd.entryByName["stopB"]["widget"]
        form.playB = form.ifd.entryByName["playB"]["widget"]
        form.playRevB = form.ifd.entryByName["playRevB"]["widget"]
        # print 'returning form1'
        self.form = form
        return form

    # methods for changing playMode
    def SetMode_cb(self, event=None):
        # print 'SetMode'
        # playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions
        #   3   play continuously in 2 directions
        # play framerate is frame/per second
        if not hasattr(self, "playModeForm"):
            self.playModeList = [
                "once and stop",
                "continuously in 1 direction",
                "once in 2 directions",
                "continuously in 2 directions",
            ]
            ifd2 = InputFormDescr(title="Set Play Mode")

            ifd2.append(
                {
                    "name": "playModeLabel",
                    "widgetType": Tkinter.Label,
                    "wcfg": {"text": "play mode options:", "font": (ensureFontCase("helvetica"), 12, "bold")},
                    "gridcfg": {"sticky": "w"},
                }
            )

            ifd2.append(
                {
                    "name": "playMode",
                    "widgetType": Tkinter.Radiobutton,
                    "defaultValue": self.playModeList[self.playMode],
                    "listtext": self.playModeList,
                    "gridcfg": {"sticky": "w"},
                }
            )

            ifd2.append(
                {
                    "name": "framerateTW",
                    "widgetType": ThumbWheel,
                    "tooltip": """Framerate to enforce during playback""",
                    "gridcfg": {"sticky": "we"},
                    "wcfg": {
                        "value": self.framerate,
                        "oneTurn": 100.0,
                        "type": "float",
                        "continuous": True,
                        "wheelPad": 2,
                        "width": 145,
                        "height": 18,
                        "labCfg": {"text": "framerate:  "},
                    },
                }
            )

            ifd2.append(
                {
                    "name": "startFrameTW",
                    "widgetType": ThumbWheel,
                    "tooltip": """First frame used in playback""",
                    "gridcfg": {"sticky": "we"},
                    "wcfg": {
                        "value": self.startFrame,
                        "oneTurn": 100,
                        "type": "int",
                        "continuous": True,
                        "wheelPad": 2,
                        "width": 145,
                        "height": 18,
                        "labCfg": {"text": "start frame: "},
                    },
                }
            )

            ifd2.append(
                {
                    "name": "endFrameTW",
                    "widgetType": ThumbWheel,
                    "tooltip": """Last frame used in playback""",
                    "gridcfg": {"sticky": "we"},
                    "wcfg": {
                        "value": self.endFrame,
                        "oneTurn": 100,
                        "type": "int",
                        "continuous": True,
                        "wheelPad": 2,
                        "width": 145,
                        "height": 18,
                        "labCfg": {"text": " end frame: "},
                    },
                }
            )

            ifd2.append(
                {
                    "name": "stepSizeTW",
                    "widgetType": ThumbWheel,
                    "tooltip": """???""",
                    "gridcfg": {"sticky": "we"},
                    "wcfg": {
                        "value": self.stepSize,
                        "oneTurn": 100,
                        "type": "int",
                        "continuous": True,
                        "wheelPad": 2,
                        "width": 145,
                        "height": 18,
                        "labCfg": {"text": " step size:  "},
                    },
                }
            )

            ifd2.append(
                {
                    "name": "acceptB",
                    "widgetType": Tkinter.Button,
                    "wcfg": {"text": "ok", "command": self.setPlayMode_cb},
                    "gridcfg": {"sticky": "nesw"},
                }
            )

            ifd2.append(
                {
                    "name": "cancelB",
                    "widgetType": Tkinter.Button,
                    "wcfg": {"text": "cancel", "command": self.cancelPlayMode_cb},
                    "gridcfg": {"sticky": "nesw", "row": -1, "column": 1},
                }
            )
            if self.master is None:
                master = self.root
            else:
                master = Tkinter.Toplevel()
            self.playModeForm = InputForm(master, None, descr=ifd2, modal=0, blocking=0)
            self.playModeVar = self.playModeForm.descr.entryByName["playMode"]["variable"]
            self.framerateWidget = self.playModeForm.descr.entryByName["framerateTW"]["widget"]
            self.startFrameWidget = self.playModeForm.descr.entryByName["startFrameTW"]["widget"]
            self.endFrameWidget = self.playModeForm.descr.entryByName["endFrameTW"]["widget"]
            self.stepSizeWidget = self.playModeForm.descr.entryByName["stepSizeTW"]["widget"]
        else:
            self.playModeForm.deiconify()

    def setPlayMode_cb(self, event=None):
        curVal = self.playModeVar.get()
        self.playMode = self.playModeList.index(curVal)
        # print 'setting playMode to ', curVal
        self.framerate = round(self.framerateWidget.get(), 4)
        # print 'setting self.framerate ->', self.framerate
        self.timestamp = 1.0 / self.framerate

        self.startFrame = self.startFrameWidget.get()
        self.endFrame = self.endFrameWidget.get()
        self.stepSize = self.stepSizeWidget.get()
        self.cancelPlayMode_cb()
        self.oneDirection = 0

    def cancelPlayMode_cb(self, event=None):
        self.playModeForm.withdraw()

    # methods for counter
    def custom_validate(self, text):
        # print 'in custom_validate, text=', text
        if not len(text):
            return -1

        if text in ["start", "end"]:
            return 1

        tt = int(text)
        okList = range(self.startFrame, self.endFrame + 1)
        if tt in okList:
            return 1
        else:
            return -1

    def custom_counter(self, text, factor, increment, **kw):
        # text is current content of entry
        # factor is 1 for increment and -1 for decrement
        # increment is value of increment megawidget option
        ###if not text in self.idList:
        ###raise ValueError, text + ' not in current idList'
        # check whether ind+factor is in range
        newval = self.currentFrameIndex + factor
        # print 'newval=', newval
        if newval < 0 or newval > self.endFrame:
            # print 'custom_counter returning ', text
            return text
        else:
            # print 'custom_counter returning ', newval
            return newval
class TrajPlayer(Player):
    """ a GUI to play a trajectory. The class constructor takes a Trajectory object and
        a correspoonding molecule as arguments."""
    
    def __init__(self, mol, traj, vf, titleStr=None, sequenceList=None,
                        idList = None, delta=0, form2=1,
                        ask=1, **kw):
        
        self.mol = mol
        self.traj = traj
        self.startFrame = 0
        self.ask = ask
        mol.allAtoms.addConformation(mol.allAtoms.coords[:])
        self.coordSlot = len(mol.allAtoms[0]._coords) - 1
        self.update(sequenceList, idList)
        kw['master'] = vf.GUI.ROOT
        kw['endFrame'] = self.endFrame
        kw['maxFrame'] = self.endFrame
        kw['form2'] = form2
        kw['titleStr'] = titleStr
        self.vf = vf
        apply(Player.__init__, (self,), kw)
        try:
            self.form.ifd.entryByName['setanimB']['widget'].grid_forget()
            #print 'withdrew SetAnim button'
            self.form.autoSize()
        except:
            pass

    def update(self, sequenceList=None, idList=None):
        if not sequenceList:
            self.sequenceList = range(len(self.traj.coords))
            #self.sequenceList = self.traj.coords.keys()
        else :
            self.sequenceList = sequenceList
        lenSeq = len(self.sequenceList)
        self.maxFrame = lenSeq
        self.endFrame = lenSeq
        if self.startFrame>lenSeq:
            self.startFrame = 0

        if hasattr(self, 'playModeForm'):
            e = self.playModeForm.descr.entryByName
            endTW = e['endFrameTW']['widget']
            #print 'setting endTW to ', self.endFrame
            endTW.max = self.endFrame
            endTW.set(self.endFrame)
            startTW = e['startFrameTW']['widget']
            startTW.set(self.startFrame)
        if not idList:
            #insert 0 for original state
            idL = range(0, len(self.sequenceList) + 1)
            self.idList = map(str, idL)
        else:
            self.idList = map(str, idList)
        #print "self.idList", self.idList
        
        if hasattr(self, 'form'):
            if hasattr(self.form, 'ent2'):
                newLen = max(map(len, self.idList))
                if newLen>3:
                    #print 'update:updating ent2 width'
                    self.form.ent2.config(width=newLen)
                self.form.ent2.delete(0,'end')
                #could use startFrame if it is valid here:
                if self.startFrame<=len(self.sequenceList) and self.startFrame>0:
                    next_val = str(self.idList[self.startFrame])
                    self.form.ent2.insert(0, next_val)
                    self.currentFrameIndex = self.startFrame
                    self.applyState(self.startFrame-1)
                else:
                    #print "restarting from frame =", self.idList[0]
                    #print self.startFrame, ": index out of range for ", sequenceList, "; resetting startFrame to  0"
                    self.form.ent2.insert(0, str(self.idList[0]))
                    #this calls applyState with reset flag
                    self.applyState(-1)


    def applyState(self, ind):
        """None<-applyState(ind)"""
        mol = self.mol
        # -1 is key for go back to original
        if int(ind)==-1:
            mol.allAtoms.setConformation(0)
            conf = None
        else:
            
            #in this case want to get new coords
            #coords = self.traj.coords["frame%d"%ind]
            coords = self.traj.coords[ind]
            coordsarr = (Numeric.array(coords)*10).astype("f")
            allAtoms = self.mol.allAtoms
            allAtoms.updateCoords(coordsarr[:], self.coordSlot)

        if not self.vf.hasGui: return
        event = EditAtomsEvent('coords', mol.allAtoms)
        self.vf.dispatchEvent(event)
        #modEvent = ModificationEvent('edit','coords', mol.allAtoms)
        #mol.geomContainer.updateGeoms(modEvent)
        self.vf.GUI.VIEWER.Redraw()
        #self.showStats()


   


    def SetMode_cb(self, event=None):
        #print 'SetMode'
        #playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions
        #   3   play continuously in 2 directions
        #play framerate is frame/per second
        if not hasattr(self, 'playModeForm'):
            self.showPlayMode = Tkinter.IntVar()
            self.showFrameParmWidgets = Tkinter.IntVar()
            self.playModeVar = Tkinter.StringVar()
            self.playModeVar.set('once and stop')
            self.playModeList=[ 'once and stop', 
                                'continuously in 1 direction',
                                'once in 2 directions', 
                                'continuously in 2 directions']
            self.frameParmsList=[ 'framerateLabel','framerateTW','startFrameLabel', 
                                  'startFrameTW', 'endFrameLabel', 'endFrameTW', 
                                  'stepSizeLabel', 'stepSizeTW']

            #self.showListVar = Tkinter.IntVar()
            ifd2 = InputFormDescr(title='Set Play Options')    
            ## ifd2.append({'name':'selectCB',
##                 'widgetType': Tkinter.Checkbutton,
##                 'tooltip':'show ids of current ordered conformation list',
##                 'wcfg':{ 'text':'Show Conf List',
##                         #'command': self.showStatesList,
##                         #'variable': self.showListVar,
##                        },
##                 'gridcfg':{'sticky':'ew', 'row':-1, 'column':1}})
##                 #'gridcfg':{'sticky':'ew'}})
            ifd2.append({'name':'playModeMb',
                'widgetType': Tkinter.Menubutton,
                'tooltip':'set play mode choice',
                'wcfg':{ 'text':'Play Mode',
                       },
                'gridcfg':{'sticky':'we'}})
                #'gridcfg':{'sticky':'w', 'columnspan':2}})
            ifd2.append({'name':'adjustFrameParmsMb',
                'widgetType': Tkinter.Checkbutton,
                'tooltip':'opens panel to set play rate, start conf number, end conf number \nand step size for playing conf sequence',
                'wcfg':{ 'text':'Play Parameters',
                        'command': self.showFrameParms_cb,
                        'variable': self.showFrameParmWidgets,
                       },
                'gridcfg':{'sticky':'w', 'row':-1, 'column':1}})
            ifd2.append( {'name': 'framerateLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'frame rate:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'framerateTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set max num of confs to be displayed per second',
                    'wcfg':{'labCfg':{'fg':'black', 'side':'left', 'text':''},
                        'showLabel':1, 'width':100,
                        'min':0,
                        'max':100,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.framerate,
                        'oneTurn':100,
                        'type':'float',
                        'increment':.1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'red'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            ifd2.append( {'name': 'startFrameLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'start frame:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'startFrameTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set number of first conf to be displayed',
                    'wcfg':{
                        'labCfg':{
                            'fg':'black',
                            'side':'left',
                            'text':''
                            },
                        'showLabel':1, 'width':100,
                        'min':0,
                        'max':self.endFrame,
                        'lockBMin':0,
                        'lockBMax':1,
                        'lockBIncrement':1,
                        'value':self.startFrame,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'green'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'ew', 'row':-1,  'column':1}})
            ifd2.append( {'name': 'endFrameLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'end frame:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'endFrameTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set number of last conf to be displayed',
                    'wcfg':{
                        'labCfg':{
                            'fg':'black',
                            'side':'left',
                            'text':''
                            },
                        'showLabel':1, 'width':100,
                        'min':self.startFrame,
                        'max':self.maxFrame,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.endFrame,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'green'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            ifd2.append( {'name': 'stepSizeLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'step size:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'stepSizeTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set step before next conf number: default is 1',
                    'wcfg':{
                        'labCfg':{
                            'fg':'black',
                            'side':'left',
                            'text':''
                            },
                        'showLabel':1, 'width':100,
                        'min':1,
                        'max':1000,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.stepSize,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'blue'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            ifd2.append({'name':'buildB',
                'widgetType': Tkinter.Button,
                'tooltip':'build a new molecule with current conf coords\nand add it to viewer',
                'wcfg':{ 'text':'Build Current',
                        'command': self.Build_cb,
                       },
                'gridcfg':{'sticky':'we'}})
                #'gridcfg':{'sticky':'ew', 'row':-1, 'column':1}})

            ifd2.append({'name':'writeB',
                'widgetType': Tkinter.Button,
                'tooltip':'write a new file with current conf coords',
                'wcfg':{ 'text':'Write Current',
                        'command': self.Write_cb,
                       },
                #'gridcfg':{'sticky':'we'}})
                'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})         

            ifd2.append({'name':'cancelB',
                        'widgetType': Tkinter.Button,
                        'wcfg':{
                            'text': 'Close',
                            'command': self.cancelPlayMode_cb,
                        },
                        #'gridcfg':{'sticky':'ew', 'row':-1, 'column':1}})
                        'gridcfg':{'sticky':'ew','columnspan':2}}),
            self.playModeForm = InputForm(self.master, self.root,
                        descr = ifd2,
                        modal = 0, blocking = 0)
            self.framerateWidget = ifd2.entryByName['framerateTW']['widget']
            self.startFrameWidget = ifd2.entryByName['startFrameTW']['widget']
            self.endFrameWidget = ifd2.entryByName['endFrameTW']['widget']
            self.stepSizeWidget = ifd2.entryByName['stepSizeTW']['widget']
            self.frameParmCfgs = []
            self.frameParmWidgets = []
            for i in self.frameParmsList:
                ent = ifd2.entryByName[i]
                self.frameParmCfgs.append(ent['gridcfg'])
                self.frameParmWidgets.append(ent['widget'])
            self.playModeMb = ifd2.entryByName['playModeMb']['widget']
            self.playModeMb.bind('<ButtonPress>', self.buildPlayModeMenu, add='+')
            self.showFrameParms_cb()
            #self.showList = ifd2.entryByName['selectCB']['widget']
        else:
            self.playModeVar.set(self.playModeList[self.playMode])
            self.framerateWidget.set(self.framerate)
            self.startFrameWidget.set(self.startFrame)
            self.endFrameWidget.set(self.endFrame)
            self.stepSizeWidget.set(self.stepSize)
            self.playModeForm.deiconify()
        self.playModeForm.autoSize()

    def buildPlayModeMenu(self, event=None):
        mB = self.playModeMb
        keyList = self.playModeList
        if not self.showPlayMode.get():
            #mB.config(bg='white')
            if not hasattr(mB, 'menu'):
                mB.menu = Tkinter.Menu(mB)
                mB['menu'] = mB.menu
            else:
                mB.menu.delete(1, 'end')
            for i in range(len(keyList)):
                mB.menu.add_radiobutton(label=keyList[i], var=self.playModeVar, 
                            value=keyList[i], command=self.setMode_cb)
            self.showPlayMode.set(1)
        else:
            mB.menu.unpost()
            self.showPlayMode.set(0)
            
    def showFrameParms_cb(self, event=None):
        if not self.showFrameParmWidgets.get():
            for w in self.frameParmWidgets:
                w.grid_forget()
        else:
            for i in range(len(self.frameParmWidgets)):
                w = self.frameParmWidgets[i]
                cfg = self.frameParmCfgs[i]
                w.grid(cfg)
        self.playModeForm.autoSize()

    def setMode_cb(self, event=None):
        curVal = self.playModeVar.get()
        #print 'setting playMode to ', curVal
        self.playMode = self.playModeList.index(curVal)
        #print 'setting playMode to ', curVal
        self.framerate = round(self.framerateWidget.get(),4)
        #print 'setting self.framerate ->', self.framerate
        self.timestamp= 1./self.framerate
        self.startFrame = self.startFrameWidget.get()
        self.endFrame = self.endFrameWidget.get()
        #print 'set endFrame to', self.endFrame
        self.stepSize = self.stepSizeWidget.get()
        self.playMode = self.playModeList.index(curVal)
        #i think this restarts the player's trip memory
        #that is, hasn't gone in any direction yet
        self.oneDirection = 0
        if not self.stop:
            self.stop = 1
            self.play(self.framerate)

            

    def setPlayMode_cb(self, event=None):
        self.setMode_cb()
        self.cancelPlayMode_cb()
        self.oneDirection = 0
        

    def SetRMSRef_cb(self, event=None):
        print 'in SetRMSRef_cb'
        return


    def Build_cb(self, event=None):
        #print building current
        """None<-Build_cb(mol, event=None)

        builds new molecule with current coordinates and adds it to the viewer
        """
        #FIRST CHECK THAT THIS HASN'T already been built
        #get the current counter content for name of new molecule
        #w = self.form.ifd.entryByName['statesCounter']['widget']
        numStr = self.form.counter.get()
        #numStr = w.get()
        #remember idList has '0' always added at the beginning for input conf
        confInd =  self.idList.index(numStr) - 1
        #CHECK THIS IS CORRECT!!!
        conf = self.sequenceList[confInd]
        self.buildConf(conf, numStr)


    def buildConf(self, conf, nameStr):
        newname = self.mol.name + '_conf_' + nameStr
        if newname in self.vf.Mols.name:
            msg = newname + ' already in viewer. Not building a second copy'
            self.vf.warningMsg(msg)
            return 'ERROR'
        allLines = self.mol.parser.allLines
        newLines = []
        coords = self.mol.allAtoms.coords
        natoms = len(coords)
        ctr = 0
        parser = self.mol.parser.__class__()
        if isinstance(parser, groParser):
            newLines.append(allLines[0])
            newLines.append(allLines[1])
            for l in allLines[2:natoms+2]:
                cc = coords[ctr]/10
                newLines.append(l[:20] +'%8.3f%8.3f%8.3f'%(cc[0],cc[1],cc[2])+ l[44:])
                ctr = ctr+1
            for l in allLines[natoms+2:]:
                newLines.append(l)
        else:
            for l in allLines:
                if find(l, 'ATOM')==0 or find(l, 'HETA')==0:
                    cc = coords[ctr]
                    newLines.append(l[:30] +'%8.3f%8.3f%8.3f'%(cc[0],cc[1],cc[2])+ l[54:])
                    ctr = ctr+1
                else:
                    newLines.append(l)
        
        parser.allLines = newLines
        filename = parser.filename = self.mol.parser.filename + '_conf_' + nameStr
        newMol = parser.parse()[0]          
        newMol.name = newname
        newMol = self.vf.addMolecule(newMol, ask=self.ask)


    def Write_cb(self, event=None):
        #print writing current
        """None<-Write_cb(mol, event=None)
        writes a new file with current coordinates
        """
        filename = self.vf.askFileSave(types=[('pdb files','*.pdb'),('pdbq files', '*.pdbq'),
                        ('pdbqt files', '*.pdbqt'), ('.gro. files', '*.gro'), ("all", "*")], 
                        title="write current conf:")
        if filename is not None:
            self.write_conf(filename)



    def write_conf(self, filename):       
            fptr = open(filename, 'w')
            ctr = 0
            liglines = self.mol.parser.allLines
            coords = self.mol.allAtoms.coords
            natoms = len(coords)
            if isinstance(self.mol.parser, groParser):
                fptr.write(liglines[0])
                fptr.write(liglines[1])
                for l in liglines[2:natoms+2]:
                    cc = coords[ctr]/10
                    fptr.write(l[:20] +'%8.3f%8.3f%8.3f'%(cc[0],cc[1],cc[2])+ l[44:])
                    ctr +=1
            for l in liglines[natoms+2:]:
                fptr.write(l)
            else:
                for l in liglines:
                    if l.find("ATOM")!=0 and l.find("HETATM")!=0:
                        l += "\n"
                        fptr.write(l)
                    else:
                        crds = coords[ctr] 
                        rec = "%s%8.3f%8.3f%8.3f%s\n"%(l[:30],crds[0], crds[1], crds[2],l[54:] ) 
                        fptr.write(rec)
                        ctr += 1
            fptr.close()
class Player(Tkinter.Frame):
    """Widget to play sequence of frames, with GUI to specify direction and speed.
    required attributes:
        currentFrameIndex = 0
        startFrame = 0
        endFrame = 0
        maxFrame = 0
        stepSize = 1
        target = endFrame           #determines direction of play
        increment = 1               #implements decrementing vs incrementing
                                    #  in getNextFrameIndex
        playMode = 0                #playMode options:
                                    #   0   play once and stop
                                    #   1   play continuously in 1 direction
                                    #   2   play once in 2 directions
                                    #   3   play continuously in 2 directions
        framerate =15.              # number of frame per second to be display
        hasSlider = False           #adds Tkinter Scale Widget if True

    required methods:
    #play methods:
        play                           #play according to play mode
        getNextFrameIndex              #returns index of next frame to
                                        play according to current index
                                        and playMode
        nextFrame                      #actually display the nextFrame
                                        ??possibly update widgets???

    #methods to regulate play
        Play_cb                        #play according to playMode
        PlayRev_cb                     #play backwards  
        FastForward_cb()               #play foward at max speed
        FastReverse_cb()               #play reverse at max speed
        Stop_cb                        #stop current play
        ?Pause_cb                      #stop at current frame??
        ?Loop_cb                       #???????


    #methods to set Frame to a specific frame
        SetState_cb                    #counter callback for random access
        GoToStart_cb                   #set to current startFrame
        GoToEnd_cb                     #set to current endFrame
        ?setCurrentFrameIndex          #set currentframe index???


    #methods for player gui
        showGUI                        #show the gui
        buildForm2                     #opens image-based gui
        buildForm                      #opens text-based gui
        Close_cb                       #withdraws gui

    #methods for pmw counter
        custom_validate                #used by pmw to check entry
        custom_counter                 #used by pmw for counter


    #methods for changing playMode
        SetMode_cb                     #opens playModeForm
        setPlayMode_cb                 #sets playMode, sets delay,
                                          startFrame, endFrame 
                                          AND closes playModeForm
        cancelPlayMode_cb              #closes playModeForm w/out changes

        #methods for end points:
            setStartFrame()            #set startFrame
            setEndFrame()              #set endFrame
            setStepSize()              #sets increment, def=1
        additional methods:
        



    """

    def __init__(self, master=None, root=None,
                        height=80,width=200,
                        currentFrameIndex=0,
                        startFrame=0, 
                        endFrame=0,
                        maxFrame=0,
                        stepSize=1, 
                        playMode=0,
                        ##afterDelay=50,
                        titleStr='Player',
                        gotoStartfile = 'go_to_start.gif',
                        gotoEndfile = 'go_to_end.gif',
                        ff_revfile = 'ff_rev.gif',
                        ff_fwdfile = 'ff_fwd.gif',
                        stopfile = 'stop.gif',
                        playfile = 'play_fwd.gif',
                        playRevfile = 'play_rev.gif',
                        chmodfile = 'chmod.gif',
                        closefile = 'close.gif',
                        iconpath = None,
                        counter = 1,
                        form2=1,gui=1,framerate=15., hasSlider=False):

        # frame rate in fps
        self.framerate = framerate 
        self.gui = gui
        self.currentFrameIndex = currentFrameIndex
        self.startFrame = startFrame
        self.endFrame = endFrame
        self.targetFrame = self.endFrame
        self.maxFrame = maxFrame
        if not maxFrame:
            self.maxFrame = endFrame
        self.stepSize = stepSize
        #used for play once in 2 directions
        self.oneDirection = 0
        self.increment = 1
        self.target = self.endFrame
        self.hasSlider = hasSlider
        #used to coordinate switching icons
        #playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions and stop
        #   3   play continuously in 2 directions
        self.playMode = playMode
        ### replace by framerate
        #amt of time to sleep
        #self.delay = delay


        #amt of time for after
        #self.afterDelay = afterDelay

        self.afterID = None
        self.stop = 1
        self.hasCounter = 0
        # gui variable
        #self.master = master
        #self.root = root
        self.form2 = form2
        self.hasCounter = counter

        if gui:
            self.showGUI(master=master,root=root,
                         titleStr=titleStr,height=height,
                         width=width,iconpath=iconpath)


    def showGUI(self,master=None,root=None,
                width=200,height=80,titleStr='player',
                gotoStartfile = 'go_to_start.gif',
                gotoEndfile = 'go_to_end.gif',
                ff_revfile = 'ff_rev.gif',
                ff_fwdfile = 'ff_fwd.gif',
                stopfile = 'stop.gif',
                playfile = 'play_fwd.gif',
                playRevfile = 'play_rev.gif',
                chmodfile = 'chmod.gif',
                closefile = 'close.gif',iconpath=None):
        """ function to display the player gui."""

        if hasattr(self, 'form'):
	    if hasattr(self.form, "deiconify"):
                self.form.deiconify()
                return   
        self.master=master
        self.root=root

        if not self.form2:
            self.form = self.buildForm(titleStr)  # pass some arguments here
            self.form2=0
        else:
            if iconpath is None:
                iconpath = ('mglutil.gui.BasicWidgets.Tk','icons')
            ICONDIR = findFilePath(iconpath[1], iconpath[0])
            #if findFilePath failed, already returned
            gotoStartfile = os.path.join(ICONDIR,gotoStartfile)
            gotoEndfile = os.path.join(ICONDIR,gotoEndfile)
            ff_revfile = os.path.join(ICONDIR,ff_revfile)
            ff_fwdfile = os.path.join(ICONDIR,ff_fwdfile)
            stopfile = os.path.join(ICONDIR,stopfile)
            playfile = os.path.join(ICONDIR,playfile)
            playRevfile = os.path.join(ICONDIR,playRevfile)
            chmodfile = os.path.join(ICONDIR,chmodfile)
            closefile = os.path.join(ICONDIR,closefile)
            
            self.gotoStartIcon = Tkinter.PhotoImage(file=gotoStartfile, master=master)
            self.gotoEndIcon = Tkinter.PhotoImage(file=gotoEndfile, master=master)
            self.ff_revIcon = Tkinter.PhotoImage(file=ff_revfile, master=master)
            self.ff_fwdIcon = Tkinter.PhotoImage(file=ff_fwdfile, master=master)
            self.stopIcon = Tkinter.PhotoImage(file=stopfile, master=master)
            self.playIcon = Tkinter.PhotoImage(file=playfile, master=master)
            self.playRevIcon = Tkinter.PhotoImage(file=playRevfile, master=master)
            self.chmodIcon = Tkinter.PhotoImage(file=chmodfile, master=master)
            self.closeIcon = Tkinter.PhotoImage(file=closefile, master=master)
            self.form = self.buildForm2(titleStr)  # pass some argument here

    #play methods:
    # play, waitTime, getNextFrameIndex, nextFrame
    def play(self, framerate,event=None):
        t1=  time.time() # previous frame time
        timestamp = 1./framerate # rate to update frame
        self.stop = 0
        ind = self.currentFrameIndex

        
        while not self.stop: #this has to be more complex
            if self.stop: 
                print 'play stopped!'
                break
            
            #do something different here if ff_fwd or ff_rev
            if self.gui:
                #self.afterID = self.master.after(self.afterDelay, self.waitTime)
                self.master.update()

            t2 = time.time()  # current time
            t = t2 -t1        # time difference between current frame and previous
    
            if (t < timestamp):
                pass
            else:
                id = self.getNextFrameIndex(self.currentFrameIndex)
                if id==None:
                    self.stop = 1
                    if self.gui:
                        self.Stop_cb()
                        break
                self.nextFrame(id) #maybe set entry then call nextFrame??
                self.currentFrameIndex = id
                t1 = t2
            
    def getNextFrameIndex(self, index):
        newFrame = index + self.increment*self.stepSize
        # check if  newFrame in current range:
        #       if incrementing, has to be <=self.endFrame
        #       if decrementing, has to be >=self.startFrame
        #   NB: incPos indicates whether currently incrementing or decrementing
        # FORCE newFrame into range 
        incPos = self.increment>0
        if incPos and newFrame>self.endFrame:
            newFrame = self.endFrame
        elif not incPos and newFrame<self.startFrame:
            newFrame = self.startFrame
        # check whether reached current targetFrame
        #       if so, action depends on current playMode 
        mode = self.playMode
        if index==self.targetFrame:
            # playModes 0 and 2 are play once and stop (in 1 or 2 directions)
            if not mode%2:
                if mode==0:
                    # None means stop
                    return None
                else:
                    # play once in 2 directions
                    #   check whether already reached halfway pt
                    if self.oneDirection:
                        return None
                    self.oneDirection = 1
                    # to reverse direction:
                    #   toggle increment
                    self.increment = -1 * self.increment
                    #   toggle targetFrame
                    if self.targetFrame==self.endFrame:
                        self.targetFrame = self.startFrame
                    else:
                        self.targetFrame = self.endFrame
                    return newFrame
            elif self.playMode==1:
                # play continuously in 1 direction
                # toggle targetFrame to the opposite end
                if self.targetFrame==self.endFrame:
                    return self.startFrame
                else:
                    return self.endFrame
            elif self.playMode==3:
                # loop continuously in 2 directions
                #   toggle increment
                self.increment = -1 * self.increment
                newFrame = self.targetFrame + self.stepSize * self.increment
                #   toggle targetFrame
                if self.targetFrame==self.endFrame:
                    self.targetFrame = self.startFrame
                else:
                    self.targetFrame = self.endFrame
                return newFrame
        return newFrame


##     def waitTime(self):
##         self.afterID = None
##         t1 = time.time()
##         delta = time.time() - t1
##         #curBut is either play or playRev button
##         hasCurBut = hasattr(self, 'curBut')
##         while delta < self.delay:
##             if hasCurBut:
##                 self.curBut.config(bg='red')
##             self.master.update()
##             time.sleep(self.delay/100)
##             delta = time.time() - t1
##         if hasCurBut:
##             self.curBut.config(bg='white')
##         if self.afterID is not None and hasCurBut:
##             self.curBut.after_cancel(self.afterID)
##             self.afterID = self.curBut.after(self.afterDelay, self.waitTime)
        

    def nextFrame(self, id):
        ##pass #must be overwritten
        id = int(id)
        if id == self.currentFrameIndex: return        
        if self.hasCounter and self.gui:
            self.form.ent2.delete(0,'end')
            self.form.ent2.insert(0, str(id))
            if self.hasSlider:
                self.form.ifd.entryByName['slider']['widget'].set(id)
        print 'playing ', id
        self.currentFrameIndex = int(id)


    #methods to call play
    #Play_cb, PlayRev_cb, FastForward_cb, FastReverse_cb
    #Stop_cb and possibly Pause_cb, Loop_cb

    def Play_cb(self, framerate=None,event=None):
        #print 'Play_cb'
        self.form.ifd.entryByName['playB']['widget'].grab_release()
        #this is a new call to Play_cb
        if framerate == None:
            framerate =self.framerate
        self.stop = 0
        self.oneDirection = 0
        self.targetFrame = self.endFrame
        self.increment = 1
        #print 'currentFrameIndex=', self.currentFrameIndex
        #possibly currently playing reverse
        if hasattr(self,'curBut') and self.curBut==self.form.playRevB:
            if self.form2:
                self.curBut.config(command=self.oldCmd,
                        image=self.oldImage,bg='white')
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
        self.oldTT = self.form.playTT
        self.oldTTtext = 'play forward according to current play mode'
        self.curBut = self.form.playB
        self.oldCmd = self.Play_cb
        self.oldImage = self.playIcon
        self.oldText = 'Play'
        if self.form2:
            self.curBut.config(command=self.Stop_cb, image=self.stopIcon)
        else:
            self.curBut.config(command=self.Stop_cb, text='Stop')
        self.oldTT.bind(self.curBut,'stop play')
        #self.master.update()
        self.play(framerate)


    def PlayRev_cb(self, framerate=None,event=None):
        #figure out current number and then play backwards
        #print 'currentFrameIndex=', self.currentFrameIndex
        self.form.ifd.entryByName['playRevB']['widget'].grab_release()
        if framerate == None:
            framerate=self.framerate
        self.increment = -1
        self.targetFrame = self.startFrame
        self.oneDirection = 0
        self.stop = 0
        #possibly currently playing 
        if hasattr(self,'curBut') and self.curBut==self.form.playB:
            if self.form2:
                self.curBut.config(command=self.oldCmd, 
                        image=self.oldImage,bg='white')
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
        self.oldTT = self.form.playRevTT
        self.oldTTtext = 'play reverse according to current play mode'
        self.curBut = self.form.playRevB
        self.oldCmd = self.PlayRev_cb
        self.oldImage = self.playRevIcon
        self.oldText = 'Play Reverse'
        if self.form2:
            self.curBut.config(command=self.Stop_cb, image=self.stopIcon)
        else:
            self.curBut.config(command=self.Stop_cb, text='Stop')
        self.oldTT.bind(self.curBut,'stop play')
        self.play(framerate)

    def FastReverse_cb(self, event=None):
        #print 'FastReverse'
        framerate = self.framerate * 2
        self.oneDirection = 0
        self.PlayRev_cb(framerate=framerate)
        

    def FastForward_cb(self, event=None):
        #print 'FastForward'
        self.oneDirection = 0
        framerate = self.framerate * 2
        self.Play_cb(framerate=framerate)
        


    def Stop_cb(self, event=None):
        self.stop = 1
        if hasattr(self, 'curBut'):
            if self.form2:
                self.curBut.config(command=self.oldCmd, image=self.oldImage)
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
                #FIX THIS!!!!
                #DECIDE if stop means reset to start or not
                self.nextFrame(self.startFrame)
            self.oldTT.bind(self.curBut,self.oldTTtext)
        #FIX THIS: does this go here?  or in nextFrame
        #clean up form
        #if self.hasCounter:
        #    self.form.ent2.delete(0,'end')
        #    self.form.ent2.insert(0, str(self.currentFrameIndex))


    #these may be superfluous: called by original form
    def PlayReturn_cb(self, event=None):
        #print 'PlayReturn_cb'
        #this should be superfluous
        self.playMode = 3
        self.Play_cb()


    def Loop_cb(self, event=None):
        #print 'Loop_cb'
        #this should be superfluous
        self.playMode = 3
        self.Play_cb()


    def Pause_cb(self, event=None):
        self.stop = 1


    #methods to set Frame to a specific frame
    #SetState_cb, GoToStart_cb, GoToEnd_cb, setCurrentFrameIndex
    def SetState_cb(self,  event=None):
        #do nothing if no counter
        if self.hasCounter:
            index = self.form.counter.get()
            self.nextFrame(index)


    def GoToStart_cb(self, event=None):
        #print 'GoToStart'
        #self.currentFrameIndex = self.startFrame
        self.oneDirection = 0
        self.nextFrame(self.startFrame)


    def GoToEnd_cb(self, event=None):
        #print 'GoToEnd'
        self.oneDirection = 0
        #self.currentFrameIndex = self.endFrame
        self.nextFrame(self.endFrame)


    def setCurrentFrameIndex(self, index):
        #print 'setting currentFrameIndex to', index
        self.currentFrameIndex = index 


    #methods for player gui
    def Close_cb(self, event=None):
        self.stop = 1
        if hasattr(self,'form'):
            self.form.withdraw()
    def SetAnim_cb(self):
        """ function to be overwritten.
        Use to call a functoin to set the animatiom frame."""

        return

    def buildForm2(self, titleStr):
        self.stop = 1
        if hasattr(self, 'form'):
            if hasattr(self.form, 'deiconify'):
                self.form.deiconify()
                return
        maxval = self.endFrame
        ifd = InputFormDescr(title=titleStr)
        ifd.append({'name': 'gotoStartB',
            'widgetType': Tkinter.Button,
            #'text':'gotoStart',
            'tooltip':'sets frame to current startFrame',
            'wcfg':{'bd':4,
                    'image':self.gotoStartIcon,
                    'width':self.gotoStartIcon.width(),
                    'height':self.gotoStartIcon.height()
            },
            'gridcfg':{'sticky':'nesw'},
            'command':self.GoToStart_cb})
        ifd.append({'name': 'fastReverseB',
            'widgetType': Tkinter.Button,
            #'text':'fastReverse',
            'tooltip':'play reverse as fast as possible',
            'wcfg':{'bd':4,
                    'image':self.ff_revIcon,
                    'width':self.ff_revIcon.width(),
                    'height':self.ff_revIcon.height()
            },
            'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1},
            'command':self.FastReverse_cb})
        ifd.append({'name': 'playRevB',
            'widgetType': Tkinter.Button,
            #'text':'Play Reverse',
            'tooltip':'play reverse according to current play mode',
            'wcfg':{'bd':4,
                    'image':self.playRevIcon,
                    'width':self.playRevIcon.width(),
                    'height':self.playRevIcon.height()},
            'gridcfg':{'sticky':'nesw','row':-1, 'column':2},
            'command':self.PlayRev_cb})
        if self.hasCounter:
            ifd.append({'widgetType':Pmw.Counter,
                    'name':'statesCounter',
                    'required':1,
                    'tooltip':'used to show frames via random access',
                    'wcfg':{#'labelpos': 'n,
                         #'label_text':'conformation:  ',
                        'autorepeat':0,
                        'entryfield_value':self.startFrame,
                        #'entryfield_value':self.idList[0],
                        'datatype': self.custom_counter,
                        'entry_width':3,
                        'entryfield_validate': self.custom_validate },
                     'gridcfg':{'sticky':'nesw', 'row':-1, 'column':3,'columnspan':2}})
        ifd.append({'name': 'playB',
            'widgetType': Tkinter.Button,
            #'text':'Play',
            'tooltip':'play forward according to current play mode',
            'wcfg':{'bd':4,
                    'image':self.playIcon,
                    'width':self.playIcon.width(),
                    'height':self.playIcon.height()
            },
            'gridcfg':{'sticky':'nesw', 'row':-1, 'column':5},
            'command':self.Play_cb})
        ifd.append({'name': 'fastForwardB',
            'widgetType': Tkinter.Button,
            #'text':'fastForward',
            'tooltip':'play as fast as possible',
            'wcfg':{'bd':4,
                    'image': self.ff_fwdIcon,
                    'width':self.ff_fwdIcon.width(),
                    'height':self.ff_fwdIcon.height()
                    },
            'gridcfg':{'sticky':'nesw','row':-1, 'column':6},
            'command':self.FastForward_cb})
        ifd.append({'name': 'gotoEndB',
            'widgetType': Tkinter.Button,
            #'text':'gotoEnd',
            'tooltip':'sets frame to current endFrame',
            'wcfg':{'bd':4,
                    'image':self.gotoEndIcon,
                    'width':self.gotoEndIcon.width(),
                    'height':self.gotoEndIcon.height()
            },
            'gridcfg':{'sticky':'nesw','row':-1, 'column':7},
            'command':self.GoToEnd_cb})
        ifd.append({'name': 'modeB',
            'widgetType': Tkinter.Button,
            'text':'Change Mode',
            'tooltip':'opens panel to change play options',
            'wcfg':{'bd':4,
                    'image':self.chmodIcon,
                    'width':self.chmodIcon.width(),
                    'height':self.chmodIcon.height()
                    },
            'gridcfg':{'sticky':'nesw','row':-1, 'column':8},
            'command':self.SetMode_cb})

        ifd.append({'name': 'setanimB',
            'widgetType': Tkinter.Button,
            'text':'SetAnim',
            'tooltip':'Set Animation',
            'wcfg':{'bd':4},
            'gridcfg':{'sticky':'nesw','row':-1, 'column':9},
            'command':self.SetAnim_cb})
        
        ifd.append({'name': 'closeB',
            'widgetType': Tkinter.Button,
            'text':'Close',
            'tooltip':'closes player',
            'wcfg':{'bd':4,
                    'image':self.closeIcon,
                    'width':self.closeIcon.width(),
                    'height':self.closeIcon.height(),
                    },
            'gridcfg':{'sticky':'nesw','row':-1, 'column':10},
            #'gridcfg':{'sticky':'nesw', 'columnspan':2},
            'command':self.Close_cb})
        if self.hasSlider:
            ifd.append({'name': 'slider',
                'widgetType': Tkinter.Scale,
                'wcfg':{'orient':'horizontal',
                        'from_':self.startFrame,
                        'to':self.maxFrame,
                        'showvalue':False},
                'gridcfg':{'sticky':'nesw','row':1, 'column':0, 'columnspan':11},
                'command':self.nextFrame
                })        
        #form = self.vf.getUserInput(ifd, modal=0,blocking=0)
        form = InputForm(self.master, self.root,
                         descr = ifd,
                         modal = 0, blocking = 0,
                         closeWithWindow=1)
        form.ifd = ifd
        form.playB = form.ifd.entryByName['playB']['widget']
        form.playRevB = form.ifd.entryByName['playRevB']['widget']
        #set up link to balloon help which needs to change, also
        form.playTT = form.ifd.entryByName['playB']['balloon']
        form.playRevTT = form.ifd.entryByName['playRevB']['balloon']
        if self.hasCounter:
            ctr = ifd.entryByName['statesCounter']['widget']
            entF = ctr.component('entryfield')
            form.ent2 = entF._entryFieldEntry
            da = ctr.component('downarrow')
            ua = ctr.component('uparrow')
            for item in [da,ua]:
                item.bind('<ButtonPress-1>', self.SetState_cb, '+')
            form.ent2.bind('<Return>', self.SetState_cb, '+')
            form.counter = form.ifd.entryByName['statesCounter']['widget']
        #print 'returning form'
        return form


    def buildForm(self, titleStr):
        #??FIX THIS:
        self.stop = 1
        if hasattr(self, 'form'):
            self.form.deiconify()
            return
        maxval = self.endFrame
        ifd = InputFormDescr(title=titleStr)
        if self.hasCounter:
            ifd.append({'widgetType':Pmw.Counter,
                    'name':'statesCounter',
                    'required':1,
                    'tooltip':'used to show frames via random access',
                    'wcfg':{#'labelpos': 'n,
                         #'label_text':'conformation:  ',
                        'autorepeat':0,
                        'entryfield_value':self.startFrame,
                        #'entryfield_value':self.idList[0],
                        'datatype': self.custom_counter,
                        'entry_width':9,
                        'entryfield_validate': self.custom_validate },
                     'gridcfg':{'sticky':'nesw', 'columnspan':2}})
        ifd.append({'name': 'playB',
            'widgetType': Tkinter.Button,
            'text':'Play',
            'tooltip':'play sequence according to current play mode',
            'wcfg':{'bd':4},
            'gridcfg':{'sticky':'nesw','columnspan':1},
            'command':self.Play_cb})
        ifd.append({'name': 'playRevB',
            'widgetType': Tkinter.Button,
            'text':'Play Reverse',
            'wcfg':{'bd':4},
            'gridcfg':{'sticky':'nesw','row':-1, 'column':1},
            'command':self.PlayRev_cb})
        ifd.append({'name': 'playTB',
            'widgetType': Tkinter.Button,
            'text':'Play+Return',
            'wcfg':{'bd':4},
            'gridcfg':{'sticky':'nesw','columnspan':1},
            'command':self.PlayReturn_cb})
        ifd.append({'name': 'loopB',
            'widgetType': Tkinter.Button,
            'text':'Loop',
            'wcfg':{'bd':4},
            'gridcfg':{'sticky':'nesw','row':-1, 'column':1},
            'command':self.Loop_cb})
        ifd.append({'name': 'stopB',
            'widgetType': Tkinter.Button,
            'text':'Stop',
            'tooltip':'stop play',
            'wcfg':{'bd':4,
                    },
            'gridcfg':{'sticky':'nesw'},
            'command':self.Stop_cb})
        #add fastforward, fastrewind, thumbwheel for speed
        ifd.append({'name': 'pauseB',
            'widgetType': Tkinter.Button,
            'text':'Pause',
            'wcfg':{'bd':4},
            'gridcfg':{'sticky':'nesw','row':-1, 'column':1},
            'command':self.Pause_cb})

        ifd.append({'name': 'closeB',
            'widgetType': Tkinter.Button,
            'text':'Close',
            'wcfg':{'bd':4},
            #'gridcfg':{'sticky':'nesw','row':-1, 'column':1},
            'gridcfg':{'sticky':'nesw', 'columnspan':2},
            'command':self.Close_cb})
        form = InputForm(self.master, self.root,
                         descr = ifd, modal = 0,
                         blocking = 0,closeWithWindow=1)
        form.ifd = ifd
        if self.hasCounter:
            ctr = ifd.entryByName['statesCounter']['widget']
            entF = ctr.component('entryfield')
            form.ent2 = entF._entryFieldEntry
            da = ctr.component('downarrow')
            ua = ctr.component('uparrow')
            for item in [da,ua]:
                item.bind('<ButtonPress-1>', self.SetState_cb, '+')
            form.ent2.bind('<Return>', self.SetState_cb, '+')
            form.counter = form.ifd.entryByName['statesCounter']['widget']
        form.stopB = form.ifd.entryByName['stopB']['widget']
        form.playB = form.ifd.entryByName['playB']['widget']
        form.playRevB = form.ifd.entryByName['playRevB']['widget']
        #print 'returning form1'
        self.form = form
        return form


    #methods for changing playMode
    def SetMode_cb(self, event=None):
        #print 'SetMode'
        #playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions
        #   3   play continuously in 2 directions
        #play framerate is frame/per second
        if not hasattr(self, 'playModeForm'):
            self.playModeList=[ 'once and stop', 
                                'continuously in 1 direction',
                                'once in 2 directions', 
                                'continuously in 2 directions']
            ifd2 = InputFormDescr(title='Set Play Mode')    
            ifd2.append( {'name': 'playModeLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'play mode options:', 
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name':'playMode',
                        'widgetType': Tkinter.Radiobutton,
                        'defaultValue': self.playModeList[self.playMode],
                        'listtext':self.playModeList,
                        'gridcfg':{'sticky':'w'}})
            ifd2.append( {'name': 'framerateLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'framerate:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'framerateTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'wcfg':{
                        'labcfg':{
                            'fg':'black',
                            'side':'left',
                            'text':'       '
                            },
                        'showLabel':1, 'width':100,
                        'min':0,
                        'max':100,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.framerate,
                        'oneTurn':100,
                        'type':'float',
                        'increment':.1,
                        'canvascfg':{'bg':'red'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':1, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw'}})

            ifd2.append( {'name': 'startFrameLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'start frame:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'startFrameTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'wcfg':{
                        'labcfg':{
                            'fg':'black',
                            'side':'left',
                            'text':'       '
                            },
                        'showLabel':1, 'width':100,
                        'min':0,
                        'max':self.endFrame,
                        'lockBMin':0,
                        'lockBMax':1,
                        'lockBIncrement':1,
                        'value':self.startFrame,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'canvascfg':{'bg':'green'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':1, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw'}})
            ifd2.append( {'name': 'endFrameLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'end frame:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'endFrameTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'wcfg':{
                        'labcfg':{
                            'fg':'black',
                            'side':'left',
                            'text':'       '
                            },
                        'showLabel':1, 'width':100,
                        'min':self.startFrame,
                        'max':self.maxFrame,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.endFrame,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'canvascfg':{'bg':'green'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':1, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw'}})
            ifd2.append( {'name': 'stepSizeLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'step size:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'stepSizeTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'wcfg':{
                        'labcfg':{
                            'fg':'black',
                            'side':'left',
                            'text':'       '
                            },
                        'showLabel':1, 'width':100,
                        'min':1,
                        'max':1000,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.stepSize,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'canvascfg':{'bg':'blue'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':1, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw'}})
            ifd2.append({'name':'acceptB',
                        'widgetType': Tkinter.Button,
                        'wcfg':{
                            'text': 'ok',
                            'command': self.setPlayMode_cb,
                        },
                        'gridcfg':{'sticky':'nesw'}})
            ifd2.append({'name':'cancelB',
                        'widgetType': Tkinter.Button,
                        'wcfg':{
                            'text': 'cancel',
                            'command': self.cancelPlayMode_cb,
                        },
                        'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            self.playModeForm = InputForm(self.master, self.root,
                        descr = ifd2,
                        modal = 0, blocking = 0)
            self.playModeVar = self.playModeForm.descr.entryByName['playMode']['variable']
            self.framerateWidget = self.playModeForm.descr.entryByName['framerateTW']['widget']
            self.startFrameWidget = self.playModeForm.descr.entryByName['startFrameTW']['widget']
            self.endFrameWidget = self.playModeForm.descr.entryByName['endFrameTW']['widget']
            self.stepSizeWidget = self.playModeForm.descr.entryByName['stepSizeTW']['widget']
        else:
            self.playModeForm.deiconify()
        

    def setPlayMode_cb(self, event=None):
        curVal = self.playModeVar.get()
        self.playMode = self.playModeList.index(curVal)
        #print 'setting playMode to ', curVal
        self.framerate = round(self.framerateWidget.get(),4)
        #print 'setting self.framerate ->', self.framerate
        self.timestamp= 1./self.framerate

        self.startFrame = self.startFrameWidget.get()
        self.endFrame = self.endFrameWidget.get()
        self.stepSize = self.stepSizeWidget.get()
        self.cancelPlayMode_cb()
        self.oneDirection = 0
        

    def cancelPlayMode_cb(self, event=None):
        self.playModeForm.withdraw()


    #methods for counter
    def custom_validate(self, text):
        #print 'in custom_validate, text=', text, ':', text in self.idList
        if not len(text):
            
            return -1
        tt = int(text)
        okList = range(self.startFrame, self.endFrame+1)
        if tt in okList:
            return 1
        else:
            return -1


    def custom_counter(self, text, factor, increment, **kw):
        # text is current content of entry
        # factor is 1 for increment and -1 for decrement
        # increment is value of increment megawidget option
        ###if not text in self.idList:
            ###raise ValueError, text + ' not in current idList'
        #check whether ind+factor is in range
        newval = self.currentFrameIndex + factor
        #print 'newval=', newval
        if newval<0 or newval>self.endFrame:
            #print 'returning ', text
            return text
        else:
            #print 'returning ', self.idList[newval]
            return newval
示例#6
0
class Player(Tkinter.Frame):
    """Widget to play sequence of frames.
    The GUI allows to specify direction and speed of playback.

    the nextFrame(number) methoid should be overridden and define how
    this player plays the animation
    
    the root constructor argument can be a Tkinter container in which to
    embde the control panel.
    
    required attributes:
        currentFrameIndex = 0
        startFrame = 0
        endFrame = 0
        maxFrame = 0
        stepSize = 1
        target = endFrame           #determines direction of play
        increment = 1               #implements decrementing vs incrementing
                                    #  in getNextFrameIndex
        playMode = 0                #playMode options:
                                    #   0   play once and stop
                                    #   1   play continuously in 1 direction
                                    #   2   play once in 2 directions
                                    #   3   play continuously in 2 directions
        framerate =15.              # number of frame per second to be display
        hasSlider = False           #adds Tkinter Scale Widget if True

    customization attributes:
        buttonMask is a dictionary that provides a button name as a key and
        a boolean as a value. For each button in the GUI if the name appears
        in self.buttonMask and the value is False the button willnot be
        addded. This only works when form2 is true. slider and counter
        are handle by the hasSlider and coutner keyword arguments

    required methods:
    #play methods:
        play                           #play according to play mode
        getNextFrameIndex              #returns index of next frame to
                                        play according to current index
                                        and playMode
        nextFrame                      #actually display the nextFrame
                                        ??possibly update widgets???

    #methods to regulate play
        Play_cb                        #play according to playMode
        PlayRev_cb                     #play backwards  
        FastForward_cb()               #play foward at max speed
        FastReverse_cb()               #play reverse at max speed
        Stop_cb                        #stop current play
        ?Pause_cb                      #stop at current frame??
        ?Loop_cb                       #???????


    #methods to set Frame to a specific frame
        SetState_cb                    #counter callback for random access
        GoToStart_cb                   #set to current startFrame
        GoToEnd_cb                     #set to current endFrame
        ?setCurrentFrameIndex          #set currentframe index???


    #methods for player gui
        showGUI                        #show the gui
        buildForm2                     #opens image-based gui
        buildForm                      #opens text-based gui
        Close_cb                       #withdraws gui

    #methods for pmw counter
        custom_validate                #used by pmw to check entry
        custom_counter                 #used by pmw for counter


    #methods for changing playMode
        SetMode_cb                     #opens playModeForm
        setPlayMode_cb                 #sets playMode, sets delay,
                                          startFrame, endFrame 
                                          AND closes playModeForm
        cancelPlayMode_cb              #closes playModeForm w/out changes

        #methods for end points:
            setStartFrame()            #set startFrame
            setEndFrame()              #set endFrame
            setStepSize()              #sets increment, def=1
        additional methods:
    """
    def __init__(
            self,
            master=None,
            root=None,
            height=80,
            width=200,
            currentFrameIndex=0,
            startFrame=0,
            endFrame=0,
            maxFrame=0,
            stepSize=1,
            playMode=0,
            ##afterDelay=50,
            titleStr='Player',
            gotoStartfile='go_to_start.gif',
            gotoEndfile='go_to_end.gif',
            ff_revfile='ff_rev.gif',
            ff_fwdfile='ff_fwd.gif',
            stopfile='stop.gif',
            playfile='play_fwd.gif',
            playRevfile='play_rev.gif',
            chmodfile='chmod.gif',
            closefile='close.gif',
            iconpath=None,
            counter=1,
            form2=1,
            gui=1,
            framerate=15.,
            hasSlider=False,
            buttonMask=None):

        # frame rate in fps
        self.framerate = framerate
        self.gui = gui
        self.currentFrameIndex = currentFrameIndex
        self.startFrame = startFrame
        self.endFrame = endFrame
        self.targetFrame = self.endFrame
        self.maxFrame = maxFrame
        if not maxFrame:
            self.maxFrame = endFrame
        self.stepSize = stepSize
        #used for play once in 2 directions
        self.oneDirection = 0
        self.increment = 1
        self.target = self.endFrame
        self.hasSlider = hasSlider
        #used to coordinate switching icons
        #playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions and stop
        #   3   play continuously in 2 directions
        self.playMode = playMode
        ### replace by framerate
        #amt of time to sleep
        #self.delay = delay

        #amt of time for after
        #self.afterDelay = afterDelay

        self.afterID = None
        self.stop = 1
        self.hasCounter = 0
        # gui variable
        #self.master = master
        #self.root = root
        self.form2 = form2
        self.hasCounter = counter

        if buttonMask is None:
            self.buttonMask = {}
            # self.buttonMask provides a button name as a key and a boolean
            # as a value. For each button in the GUI if the name appears in
            # self.buttonMask and the value is False the button willnot be
            # addded
        else:
            self.buttonMask = buttonMask

        if gui:
            self.showGUI(master=master,
                         root=root,
                         titleStr=titleStr,
                         height=height,
                         width=width,
                         iconpath=iconpath)

        # make sure we have a master as we will call master.update in play()
        if hasattr(master, 'update'):
            self.masterForUpdate = self.master
        else:
            self.masterForUpdate = self.root

    def showGUI(self,
                master=None,
                root=None,
                width=200,
                height=80,
                titleStr='player',
                gotoStartfile='go_to_start.gif',
                gotoEndfile='go_to_end.gif',
                ff_revfile='ff_rev.gif',
                ff_fwdfile='ff_fwd.gif',
                stopfile='stop.gif',
                playfile='play_fwd.gif',
                playRevfile='play_rev.gif',
                chmodfile='chmod.gif',
                closefile='close.gif',
                iconpath=None):
        """ function to display the player gui."""

        if hasattr(self, 'form'):
            if hasattr(self.form, "deiconify"):
                self.form.deiconify()
                return
        self.master = master
        self.root = root

        if not self.form2:
            self.form = self.buildForm(titleStr)  # pass some arguments here
            self.form2 = 0
        else:
            if iconpath is None:
                iconpath = ('mglutil.gui.BasicWidgets.Tk', 'icons')
            ICONDIR = findFilePath(iconpath[1], iconpath[0])
            #if findFilePath failed, already returned
            gotoStartfile = os.path.join(ICONDIR, gotoStartfile)
            gotoEndfile = os.path.join(ICONDIR, gotoEndfile)
            ff_revfile = os.path.join(ICONDIR, ff_revfile)
            ff_fwdfile = os.path.join(ICONDIR, ff_fwdfile)
            stopfile = os.path.join(ICONDIR, stopfile)
            playfile = os.path.join(ICONDIR, playfile)
            playRevfile = os.path.join(ICONDIR, playRevfile)
            chmodfile = os.path.join(ICONDIR, chmodfile)
            closefile = os.path.join(ICONDIR, closefile)
            recordfile = os.path.join(ICONDIR, "record.gif")
            record1file = os.path.join(ICONDIR, "record1.gif")

            self.gotoStartIcon = Tkinter.PhotoImage(file=gotoStartfile,
                                                    master=master)
            self.gotoEndIcon = Tkinter.PhotoImage(file=gotoEndfile,
                                                  master=master)
            self.ff_revIcon = Tkinter.PhotoImage(file=ff_revfile,
                                                 master=master)
            self.ff_fwdIcon = Tkinter.PhotoImage(file=ff_fwdfile,
                                                 master=master)
            self.stopIcon = Tkinter.PhotoImage(file=stopfile, master=master)
            self.playIcon = Tkinter.PhotoImage(file=playfile, master=master)
            self.playRevIcon = Tkinter.PhotoImage(file=playRevfile,
                                                  master=master)
            self.recIcon = Tkinter.PhotoImage(file=recordfile, master=master)
            self.rec1Icon = Tkinter.PhotoImage(file=record1file, master=master)
            self.chmodIcon = Tkinter.PhotoImage(file=chmodfile, master=master)
            self.closeIcon = Tkinter.PhotoImage(file=closefile, master=master)
            self.form = self.buildForm2(titleStr)  # pass some argument here

    #play methods:
    # play, waitTime, getNextFrameIndex, nextFrame
    def play(self, framerate, event=None):
        t1 = time.time()  # previous frame time
        timestamp = 1. / framerate  # rate to update frame
        self.stop = 0
        ind = self.currentFrameIndex

        # if player at the end we resume from begining
        if ind >= self.endFrame:
            self.GoToStart_cb()

        while not self.stop:  #this has to be more complex
            if self.stop:
                print 'play stopped!'
                break

            #do something different here if ff_fwd or ff_rev
            if self.gui:
                #self.afterID = self.master.after(self.afterDelay, self.waitTime)
                self.masterForUpdate.update()

            t2 = time.time()  # current time
            t = t2 - t1  # time difference between current frame and previous

            if framerate > -1 and t < timestamp:
                pass
            else:
                id = self.getNextFrameIndex(self.currentFrameIndex)
                if id == None:
                    self.stop = 1
                    if self.gui:
                        self.Stop_cb()
                        break
                self.nextFrame(id)  #maybe set entry then call nextFrame??
                self.currentFrameIndex = id
                t1 = t2

    def getNextFrameIndex(self, index):
        newFrame = index + self.increment * self.stepSize
        # check if  newFrame in current range:
        #       if incrementing, has to be <=self.endFrame
        #       if decrementing, has to be >=self.startFrame
        #   NB: incPos indicates whether currently incrementing or decrementing
        # FORCE newFrame into range
        incPos = self.increment > 0
        if incPos and newFrame > self.endFrame:
            newFrame = self.endFrame
        elif not incPos and newFrame < self.startFrame:
            newFrame = self.startFrame
        # check whether reached current targetFrame
        #       if so, action depends on current playMode
        mode = self.playMode
        if index == self.targetFrame:
            # playModes 0 and 2 are play once and stop (in 1 or 2 directions)
            if not mode % 2:
                if mode == 0:
                    # None means stop
                    return None
                else:
                    # play once in 2 directions
                    #   check whether already reached halfway pt
                    if self.oneDirection:
                        return None
                    self.oneDirection = 1
                    # to reverse direction:
                    #   toggle increment
                    self.increment = -1 * self.increment
                    #   toggle targetFrame
                    if self.targetFrame == self.endFrame:
                        self.targetFrame = self.startFrame
                    else:
                        self.targetFrame = self.endFrame
                    return newFrame
            elif self.playMode == 1:
                # play continuously in 1 direction
                # toggle targetFrame to the opposite end
                if self.targetFrame == self.endFrame:
                    return self.startFrame
                else:
                    return self.endFrame
            elif self.playMode == 3:
                # loop continuously in 2 directions
                #   toggle increment
                self.increment = -1 * self.increment
                newFrame = self.targetFrame + self.stepSize * self.increment
                #   toggle targetFrame
                if self.targetFrame == self.endFrame:
                    self.targetFrame = self.startFrame
                else:
                    self.targetFrame = self.endFrame
                return newFrame
        return newFrame


##     def waitTime(self):
##         self.afterID = None
##         t1 = time.time()
##         delta = time.time() - t1
##         #curBut is either play or playRev button
##         hasCurBut = hasattr(self, 'curBut')
##         while delta < self.delay:
##             if hasCurBut:
##                 self.curBut.config(bg='red')
##             self.master.update()
##             time.sleep(self.delay/100)
##             delta = time.time() - t1
##         if hasCurBut:
##             self.curBut.config(bg='white')
##         if self.afterID is not None and hasCurBut:
##             self.curBut.after_cancel(self.afterID)
##             self.afterID = self.curBut.after(self.afterDelay, self.waitTime)

    def nextFrame(self, id):
        ##pass #must be overriden
        id = int(id)
        if id == self.currentFrameIndex: return
        if self.hasCounter and self.gui:
            self.form.ent2.delete(0, 'end')
            self.form.ent2.insert(0, str(id))
            if self.hasSlider:
                self.form.ifd.entryByName['slider']['widget'].set(id)
        print 'playing ', id
        self.currentFrameIndex = int(id)

    #methods to call play
    #Play_cb, PlayRev_cb, FastForward_cb, FastReverse_cb
    #Stop_cb and possibly Pause_cb, Loop_cb
    def startRecording_cb(self, event=None):
        pass

    def stopRecording_cb(self, event=None):
        pass

    def Play_cb(self, framerate=None, event=None):
        #print 'Play_cb'
        self.form.ifd.entryByName['playB']['widget'].grab_release()
        #this is a new call to Play_cb
        if framerate == None:
            framerate = self.framerate
        self.stop = 0
        self.oneDirection = 0
        self.targetFrame = self.endFrame
        self.increment = 1
        #print 'currentFrameIndex=', self.currentFrameIndex
        #possibly currently playing reverse
        if hasattr(self, 'curBut') and self.curBut == self.form.playRevB:
            if self.form2:
                self.curBut.config(command=self.oldCmd,
                                   image=self.oldImage,
                                   bg='white')
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
        self.oldTT = self.form.playTT
        self.oldTTtext = 'play forward according to current play mode'
        self.curBut = self.form.playB
        self.oldCmd = self.Play_cb
        self.oldImage = self.playIcon
        self.oldText = 'Play'
        if self.form2:
            self.curBut.config(command=self.Stop_cb, image=self.stopIcon)
        else:
            self.curBut.config(command=self.Stop_cb, text='Stop')
        self.oldTT.bind(self.curBut, 'stop play')
        #self.master.update()
        self.play(framerate)
        self.stopRecording_cb()

    def PlayRev_cb(self, framerate=None, event=None):
        #figure out current number and then play backwards
        #print 'currentFrameIndex=', self.currentFrameIndex
        self.form.ifd.entryByName['playRevB']['widget'].grab_release()
        if framerate == None:
            framerate = self.framerate
        self.increment = -1
        self.targetFrame = self.startFrame
        self.oneDirection = 0
        self.stop = 0
        #possibly currently playing
        if hasattr(self, 'curBut') and self.curBut == self.form.playB:
            if self.form2:
                self.curBut.config(command=self.oldCmd,
                                   image=self.oldImage,
                                   bg='white')
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
        self.oldTT = self.form.playRevTT
        self.oldTTtext = 'play reverse according to current play mode'
        self.curBut = self.form.playRevB
        self.oldCmd = self.PlayRev_cb
        self.oldImage = self.playRevIcon
        self.oldText = 'Play Reverse'
        if self.form2:
            self.curBut.config(command=self.Stop_cb, image=self.stopIcon)
        else:
            self.curBut.config(command=self.Stop_cb, text='Stop')
        self.oldTT.bind(self.curBut, 'stop play')
        self.play(framerate)

    def FastReverse_cb(self, event=None):
        #print 'FastReverse'
        #framerate = self.framerate * 2
        self.oneDirection = 0
        self.PlayRev_cb(framerate=-1)  #framerate)

    def FastForward_cb(self, event=None):
        #print 'FastForward'
        self.oneDirection = 0
        #framerate = self.framerate * 2
        self.Play_cb(framerate=-1)

    def Stop_cb(self, event=None):
        self.stop = 1
        if hasattr(self, 'curBut'):
            if self.form2:
                self.curBut.config(command=self.oldCmd, image=self.oldImage)
            else:
                self.curBut.config(command=self.oldCmd, text=self.oldText)
                #FIX THIS!!!!
                #DECIDE if stop means reset to start or not
                #self.nextFrame(self.startFrame)
            self.oldTT.bind(self.curBut, self.oldTTtext)

        self.stopRecording_cb()

        #FIX THIS: does this go here?  or in nextFrame
        #clean up form
        #if self.hasCounter:
        #    self.form.ent2.delete(0,'end')
        #    self.form.ent2.insert(0, str(self.currentFrameIndex))

    #these may be superfluous: called by original form
    def PlayReturn_cb(self, event=None):
        #print 'PlayReturn_cb'
        #this should be superfluous
        self.playMode = 3
        self.Play_cb()

    def Loop_cb(self, event=None):
        #print 'Loop_cb'
        #this should be superfluous
        self.playMode = 3
        self.Play_cb()

    def Pause_cb(self, event=None):
        self.stop = 1

    #methods to set Frame to a specific frame
    #SetState_cb, GoToStart_cb, GoToEnd_cb, setCurrentFrameIndex
    def SetState_cb(self, event=None):
        #do nothing if no counter
        if self.hasCounter:
            index = self.form.counter.get()
            self.nextFrame(index)

    def GoToStart_cb(self, event=None):
        #print "GoToStart_cb", self.startFrame, self.currentFrameIndex
        #self.currentFrameIndex = self.startFrame
        self.oneDirection = 0
        self.nextFrame(self.startFrame)

    def GoToEnd_cb(self, event=None):
        #print 'GoToEnd'
        self.oneDirection = 0
        #self.currentFrameIndex = self.endFrame
        self.nextFrame(self.endFrame)

    def setCurrentFrameIndex(self, index):
        #print 'setting currentFrameIndex to', index
        self.currentFrameIndex = index

    #methods for player gui
    def Close_cb(self, event=None):
        self.stop = 1
        if hasattr(self, 'form'):
            self.form.withdraw()

    def SetAnim_cb(self):
        """ function to be overwritten.
        Use to call a functoin to set the animatiom frame."""

        return

    def buildForm2(self, titleStr):
        self.stop = 1
        if hasattr(self, 'form'):
            if hasattr(self.form, 'deiconify'):
                self.form.deiconify()
                return
        maxval = self.endFrame
        ifd = InputFormDescr(title=titleStr)

        if self.buttonMask.get('gotoStartB', None) is not False:
            ifd.append({
                'name': 'gotoStartB',
                'widgetType': Tkinter.Button,
                #'text':'gotoStart',
                'tooltip': 'sets frame to current startFrame',
                'wcfg': {
                    'bd': 4,
                    'image': self.gotoStartIcon,
                    'width': self.gotoStartIcon.width(),
                    'height': self.gotoStartIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw'
                },
                'command': self.GoToStart_cb
            })

        if self.buttonMask.get('fastReverseB', None) is not False:
            ifd.append({
                'name': 'fastReverseB',
                'widgetType': Tkinter.Button,
                #'text':'fastReverse',
                'tooltip': 'play reverse as fast as possible',
                'wcfg': {
                    'bd': 4,
                    'image': self.ff_revIcon,
                    'width': self.ff_revIcon.width(),
                    'height': self.ff_revIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 1
                },
                'command': self.FastReverse_cb
            })

        if self.buttonMask.get('playRevB', None) is not False:
            ifd.append({
                'name': 'playRevB',
                'widgetType': Tkinter.Button,
                #'text':'Play Reverse',
                'tooltip': 'play reverse according to current play mode',
                'wcfg': {
                    'bd': 4,
                    'image': self.playRevIcon,
                    'width': self.playRevIcon.width(),
                    'height': self.playRevIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 2
                },
                'command': self.PlayRev_cb
            })

            if self.hasCounter:
                ifd.append({
                    'widgetType': Pmw.Counter,
                    'name': 'statesCounter',
                    'required': 1,
                    'tooltip': 'used to show frames via random access',
                    'wcfg': {  #'labelpos': 'n,
                        #'label_text':'conformation:  ',
                        'autorepeat': 0,
                        'entryfield_value': self.startFrame,
                        #'entryfield_value':self.idList[0],
                        'datatype': self.custom_counter,
                        'entry_width': 3,
                        'entryfield_validate': self.custom_validate
                    },
                    'gridcfg': {
                        'sticky': 'nesw',
                        'row': -1,
                        'column': 3,
                        'columnspan': 2
                    }
                })

        if self.buttonMask.get('playB', None) is not False:
            ifd.append({
                'name': 'playB',
                'widgetType': Tkinter.Button,
                #'text':'Play',
                'tooltip': 'play forward according to current play mode',
                'wcfg': {
                    'bd': 4,
                    'image': self.playIcon,
                    'width': self.playIcon.width(),
                    'height': self.playIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 5
                },
                'command': self.Play_cb
            })

        if self.buttonMask.get('fastForwardB', None) is not False:
            ifd.append({
                'name': 'fastForwardB',
                'widgetType': Tkinter.Button,
                #'text':'fastForward',
                'tooltip': 'play as fast as possible',
                'wcfg': {
                    'bd': 4,
                    'image': self.ff_fwdIcon,
                    'width': self.ff_fwdIcon.width(),
                    'height': self.ff_fwdIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 6
                },
                'command': self.FastForward_cb
            })

        if self.buttonMask.get('gotoEndB', None) is not False:
            ifd.append({
                'name': 'gotoEndB',
                'widgetType': Tkinter.Button,
                #'text':'gotoEnd',
                'tooltip': 'sets frame to current endFrame',
                'wcfg': {
                    'bd': 4,
                    'image': self.gotoEndIcon,
                    'width': self.gotoEndIcon.width(),
                    'height': self.gotoEndIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 7
                },
                'command': self.GoToEnd_cb
            })

        if self.buttonMask.get('modeB', None) is not False:
            ifd.append({
                'name': 'modeB',
                'widgetType': Tkinter.Button,
                'text': 'Change Mode',
                'tooltip': 'opens panel to change play options',
                'wcfg': {
                    'bd': 4,
                    'image': self.chmodIcon,
                    'width': self.chmodIcon.width(),
                    'height': self.chmodIcon.height()
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 8
                },
                'command': self.SetMode_cb
            })

        if pymediaFound and self.buttonMask.get('recordB', None) is not False:
            ifd.append({
                'name': 'recordB',
                'widgetType': Tkinter.Checkbutton,
                'text': 'Record',
                'tooltip': 'record an mpeg movie into movie.mpeg',
                'defaultValue': 0,
                'wcfg': {
                    'bd': 4,
                    'variable': Tkinter.IntVar(),
                    'image': self.recIcon,
                    'width': self.recIcon.width(),
                    'height': self.recIcon.height(),
                    'indicatoron': 0,
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 9
                },
                'command': self.startRecording_cb
            })

        if self.buttonMask.get('setanimB', None) is not False:
            ifd.append({
                'name': 'setanimB',
                'widgetType': Tkinter.Button,
                'text': 'SetAnim',
                'tooltip': 'Set Animation',
                'wcfg': {
                    'bd': 4
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 10
                },
                'command': self.SetAnim_cb
            })

        if self.buttonMask.get('closeB', None) is not False:
            ifd.append({
                'name': 'closeB',
                'widgetType': Tkinter.Button,
                'text': 'Close',
                'tooltip': 'closes player',
                'wcfg': {
                    'bd': 4,
                    'image': self.closeIcon,
                    'width': self.closeIcon.width(),
                    'height': self.closeIcon.height(),
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 11
                },
                #'gridcfg':{'sticky':'nesw', 'columnspan':2},
                'command': self.Close_cb
            })

        if self.hasSlider:
            ifd.append({
                'name': 'slider',
                'widgetType': Tkinter.Scale,
                'wcfg': {
                    'orient': 'horizontal',
                    'from_': self.startFrame,
                    'to': self.maxFrame,
                    'showvalue': False
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': 1,
                    'column': 0,
                    'columnspan': 12
                },
                'command': self.nextFrame
            })
        #form = self.vf.getUserInput(ifd, modal=0,blocking=0)
        form = InputForm(self.master,
                         self.root,
                         descr=ifd,
                         modal=0,
                         blocking=0,
                         closeWithWindow=1)
        form.ifd = ifd
        form.playB = form.ifd.entryByName['playB']['widget']
        form.playRevB = form.ifd.entryByName['playRevB']['widget']
        #set up link to balloon help which needs to change, also
        form.playTT = form.ifd.entryByName['playB']['balloon']
        form.playRevTT = form.ifd.entryByName['playRevB']['balloon']
        if self.hasCounter:
            ctr = ifd.entryByName['statesCounter']['widget']
            entF = ctr.component('entryfield')
            form.ent2 = entF._entryFieldEntry
            da = ctr.component('downarrow')
            ua = ctr.component('uparrow')
            for item in [da, ua]:
                item.bind('<ButtonPress-1>', self.SetState_cb, '+')
            form.ent2.bind('<Return>', self.SetState_cb, '+')
            form.counter = form.ifd.entryByName['statesCounter']['widget']
        if self.hasSlider:
            slider = form.ifd.entryByName['slider']['widget']
            slider.set(self.currentFrameIndex)
        #print 'returning form'
        return form

    def buildForm(self, titleStr):
        #??FIX THIS:
        self.stop = 1
        if hasattr(self, 'form'):
            self.form.deiconify()
            return
        maxval = self.endFrame
        ifd = InputFormDescr(title=titleStr)
        if self.hasCounter:
            ifd.append({
                'widgetType': Pmw.Counter,
                'name': 'statesCounter',
                'required': 1,
                'tooltip': 'used to show frames via random access',
                'wcfg': {  #'labelpos': 'n,
                    #'label_text':'conformation:  ',
                    'autorepeat': 0,
                    'entryfield_value': self.startFrame,
                    #'entryfield_value':self.idList[0],
                    'datatype': self.custom_counter,
                    'entry_width': 9,
                    'entryfield_validate': self.custom_validate
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'columnspan': 2
                }
            })
        ifd.append({
            'name': 'playB',
            'widgetType': Tkinter.Button,
            'text': 'Play',
            'tooltip': 'play sequence according to current play mode',
            'wcfg': {
                'bd': 4
            },
            'gridcfg': {
                'sticky': 'nesw',
                'columnspan': 1
            },
            'command': self.Play_cb
        })
        ifd.append({
            'name': 'playRevB',
            'widgetType': Tkinter.Button,
            'text': 'Play Reverse',
            'wcfg': {
                'bd': 4
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1,
                'column': 1
            },
            'command': self.PlayRev_cb
        })
        ifd.append({
            'name': 'playTB',
            'widgetType': Tkinter.Button,
            'text': 'Play+Return',
            'wcfg': {
                'bd': 4
            },
            'gridcfg': {
                'sticky': 'nesw',
                'columnspan': 1
            },
            'command': self.PlayReturn_cb
        })
        ifd.append({
            'name': 'loopB',
            'widgetType': Tkinter.Button,
            'text': 'Loop',
            'wcfg': {
                'bd': 4
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1,
                'column': 1
            },
            'command': self.Loop_cb
        })
        ifd.append({
            'name': 'stopB',
            'widgetType': Tkinter.Button,
            'text': 'Stop',
            'tooltip': 'stop play',
            'wcfg': {
                'bd': 4,
            },
            'gridcfg': {
                'sticky': 'nesw'
            },
            'command': self.Stop_cb
        })
        #add fastforward, fastrewind, thumbwheel for speed
        ifd.append({
            'name': 'pauseB',
            'widgetType': Tkinter.Button,
            'text': 'Pause',
            'wcfg': {
                'bd': 4
            },
            'gridcfg': {
                'sticky': 'nesw',
                'row': -1,
                'column': 1
            },
            'command': self.Pause_cb
        })

        ifd.append({
            'name': 'closeB',
            'widgetType': Tkinter.Button,
            'text': 'Close',
            'wcfg': {
                'bd': 4
            },
            #'gridcfg':{'sticky':'nesw','row':-1, 'column':1},
            'gridcfg': {
                'sticky': 'nesw',
                'columnspan': 2
            },
            'command': self.Close_cb
        })
        form = InputForm(self.master,
                         self.root,
                         descr=ifd,
                         modal=0,
                         blocking=0,
                         closeWithWindow=1)
        form.ifd = ifd
        if self.hasCounter:
            ctr = ifd.entryByName['statesCounter']['widget']
            entF = ctr.component('entryfield')
            form.ent2 = entF._entryFieldEntry
            da = ctr.component('downarrow')
            ua = ctr.component('uparrow')
            for item in [da, ua]:
                item.bind('<ButtonPress-1>', self.SetState_cb, '+')
            form.ent2.bind('<Return>', self.SetState_cb, '+')
            form.counter = form.ifd.entryByName['statesCounter']['widget']
        form.stopB = form.ifd.entryByName['stopB']['widget']
        form.playB = form.ifd.entryByName['playB']['widget']
        form.playRevB = form.ifd.entryByName['playRevB']['widget']
        #print 'returning form1'
        self.form = form
        return form

    #methods for changing playMode
    def SetMode_cb(self, event=None):
        #print 'SetMode'
        #playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions
        #   3   play continuously in 2 directions
        #play framerate is frame/per second
        if not hasattr(self, 'playModeForm'):
            self.playModeList = [
                'once and stop', 'continuously in 1 direction',
                'once in 2 directions', 'continuously in 2 directions'
            ]
            ifd2 = InputFormDescr(title='Set Play Mode')

            ifd2.append({
                'name': 'playModeLabel',
                'widgetType': Tkinter.Label,
                'wcfg': {
                    'text': 'play mode options:',
                    'font': (ensureFontCase('helvetica'), 12, 'bold')
                },
                'gridcfg': {
                    'sticky': 'w'
                }
            })

            ifd2.append({
                'name': 'playMode',
                'widgetType': Tkinter.Radiobutton,
                'defaultValue': self.playModeList[self.playMode],
                'listtext': self.playModeList,
                'gridcfg': {
                    'sticky': 'w'
                }
            })

            ifd2.append({
                'name': 'framerateTW',
                'widgetType': ThumbWheel,
                'tooltip': """Framerate to enforce during playback""",
                'gridcfg': {
                    'sticky': 'we'
                },
                'wcfg': {
                    'value': self.framerate,
                    'oneTurn': 100.,
                    'type': 'float',
                    'continuous': True,
                    'wheelPad': 2,
                    'width': 145,
                    'height': 18,
                    'labCfg': {
                        'text': 'framerate:  '
                    },
                },
            })

            ifd2.append({
                'name': 'startFrameTW',
                'widgetType': ThumbWheel,
                'tooltip': """First frame used in playback""",
                'gridcfg': {
                    'sticky': 'we'
                },
                'wcfg': {
                    'value': self.startFrame,
                    'oneTurn': 100,
                    'type': 'int',
                    'continuous': True,
                    'wheelPad': 2,
                    'width': 145,
                    'height': 18,
                    'labCfg': {
                        'text': 'start frame: '
                    },
                },
            })

            ifd2.append({
                'name': 'endFrameTW',
                'widgetType': ThumbWheel,
                'tooltip': """Last frame used in playback""",
                'gridcfg': {
                    'sticky': 'we'
                },
                'wcfg': {
                    'value': self.endFrame,
                    'oneTurn': 100,
                    'type': 'int',
                    'continuous': True,
                    'wheelPad': 2,
                    'width': 145,
                    'height': 18,
                    'labCfg': {
                        'text': ' end frame: '
                    },
                },
            })

            ifd2.append({
                'name': 'stepSizeTW',
                'widgetType': ThumbWheel,
                'tooltip': """???""",
                'gridcfg': {
                    'sticky': 'we'
                },
                'wcfg': {
                    'value': self.stepSize,
                    'oneTurn': 100,
                    'type': 'int',
                    'continuous': True,
                    'wheelPad': 2,
                    'width': 145,
                    'height': 18,
                    'labCfg': {
                        'text': ' step size:  '
                    },
                },
            })

            ifd2.append({
                'name': 'acceptB',
                'widgetType': Tkinter.Button,
                'wcfg': {
                    'text': 'ok',
                    'command': self.setPlayMode_cb,
                },
                'gridcfg': {
                    'sticky': 'nesw'
                }
            })

            ifd2.append({
                'name': 'cancelB',
                'widgetType': Tkinter.Button,
                'wcfg': {
                    'text': 'cancel',
                    'command': self.cancelPlayMode_cb,
                },
                'gridcfg': {
                    'sticky': 'nesw',
                    'row': -1,
                    'column': 1
                }
            })
            if self.master is None:
                master = self.root
            else:
                master = Tkinter.Toplevel()
            self.playModeForm = InputForm(master,
                                          None,
                                          descr=ifd2,
                                          modal=0,
                                          blocking=0)
            self.playModeVar = self.playModeForm.descr.entryByName['playMode'][
                'variable']
            self.framerateWidget = self.playModeForm.descr.entryByName[
                'framerateTW']['widget']
            self.startFrameWidget = self.playModeForm.descr.entryByName[
                'startFrameTW']['widget']
            self.endFrameWidget = self.playModeForm.descr.entryByName[
                'endFrameTW']['widget']
            self.stepSizeWidget = self.playModeForm.descr.entryByName[
                'stepSizeTW']['widget']
        else:
            self.playModeForm.deiconify()

    def setPlayMode_cb(self, event=None):
        curVal = self.playModeVar.get()
        self.playMode = self.playModeList.index(curVal)
        #print 'setting playMode to ', curVal
        self.framerate = round(self.framerateWidget.get(), 4)
        #print 'setting self.framerate ->', self.framerate
        self.timestamp = 1. / self.framerate

        self.startFrame = self.startFrameWidget.get()
        self.endFrame = self.endFrameWidget.get()
        self.stepSize = self.stepSizeWidget.get()
        self.cancelPlayMode_cb()
        self.oneDirection = 0

    def cancelPlayMode_cb(self, event=None):
        self.playModeForm.withdraw()

    #methods for counter
    def custom_validate(self, text):
        #print 'in custom_validate, text=', text
        if not len(text):
            return -1

        if text in ['start', 'end']:
            return 1

        tt = int(text)
        okList = range(self.startFrame, self.endFrame + 1)
        if tt in okList:
            return 1
        else:
            return -1

    def custom_counter(self, text, factor, increment, **kw):
        # text is current content of entry
        # factor is 1 for increment and -1 for decrement
        # increment is value of increment megawidget option
        ###if not text in self.idList:
        ###raise ValueError, text + ' not in current idList'
        #check whether ind+factor is in range
        newval = self.currentFrameIndex + factor
        #print 'newval=', newval
        if newval < 0 or newval > self.endFrame:
            #print 'custom_counter returning ', text
            return text
        else:
            #print 'custom_counter returning ', newval
            return newval
class AnimPlayer(Player,geomsChooser):
    """ provide a player to display/undisplay DejaVu object
    in a cylce making a animation.

    viewer: DejaVu viewer
    height,width are the property of the player gui
    startFrame: frame to begin
    endFrame: last frame to display
    stepSize: step between new frame
    playMode:                  #playMode options:
                               #   0   play once and stop
                               #   1   play continuously in 1 direction
                               #   2   play once in 2 directions
                               #   3   play continuously in 2 directions
    titleStr: title of the gui windows
    counter: gui with a counter on or not
    gui: #1 show the player gui
         #0 player gui not display
    framerate =15.             # number of frame per second to be display
    """


    def __init__(self,viewer, master=None, root=None,
                 height=80,width=200,
                 currentFrameIndex=0,
                 startFrame=0, 
                 endFrame=0,
                 maxFrame=0,
                 stepSize=1, 
                 playMode=1,
                 titleStr='AnimPlayer',
                 counter = 1,
                 gui=1,framerate=15.):

        if master is None:
            master = Tkinter.Toplevel()

        # viewer from which we get the geom to animate
        self.viewer = viewer
        # frame list, is a list of geom .
        # each frame is made of n DejaVu object to be display
        # it a list of tuple, each tuple is a {} and []
        # {} is: {'objname':['geom1','geom2'],'objname':['geom1','geom2']}
        # [] is list of DejaVu object per frame
        self.framelist=[]

        Player.__init__(self, master=master,root=root,height=height,
                        width=width,currentFrameIndex=currentFrameIndex,
                        startFrame=startFrame,endFrame=endFrame,
                        maxFrame=maxFrame,stepSize=stepSize,
                        playMode=playMode,titleStr=titleStr,counter=counter,
                        gui=gui,framerate=framerate)

    def nextFrame(self, id):
        """ id: index number of the frame to display.
        undisplay object from previous frame, display object
        of new frame.
        """
        if not self.framelist:return
        id = int(id)
        if id >=len(self.framelist):return

        i = self.currentFrameIndex
        ## undisplay previous object
        frame = self.framelist[i]
        for obj in frame[1]:
            obj.Set(visible=0,redo=0)
            
        if self.hasCounter and self.gui:
            self.form.ent2.delete(0,'end')
            self.form.ent2.insert(0, str(id))

        ## display new frame
        currentframe = self.framelist[id]
        for obj in currentframe[1]:
            obj.Set(visible=1,redo=0)
        
        self.viewer.deleteOpenglList()
	self.viewer.Redraw()
        self.currentFrameIndex = id

#####################################################################
#### Animation Setting the frame

    def SetAnim_cb(self):
        self.showForm()
        
    def showForm(self):
        """create formdescr for setAnim
        form to set the animation:
        each frame is a list of geom to display
        """

        entryFrame = []
        for i in range(len(self.framelist)):
            val = 'frame_'+str(i)
            entryFrame.append((val,))
        
        if not hasattr(self,'form_Setanim'):
            ifd = InputFormDescr(title="SetAnimation")
            ifd.append({'widgetType':ListChooser,
                        'name':'availableGeom',
                        'tooltip':'geom available in viewer',
                        'wcfg':{'mode':'extended',
                                'lbwcfg':{'exportselection':1},
                                'command':[(self.toggleExpansion,'<Double-Button-1>')],
                                'commandEvent':None,
                                'title':'availableGeom'},
                        
                        'gridcfg':{'row':0,'column':0,
                                   'sticky':'wens','rowspan':3}})
            ifd.append({'name':'newframe',
                        'widgetType':Tkinter.Button,
                        'tooltip':""" Add an empty frame to the animation""",
                        'wcfg':{'text':'NewFrame','command':self.addframe_cb},
                        'gridcfg':{'row':0,'column':1,'rowspan':1 }})
            
            ifd.append({'name':'add',
                        'widgetType':Tkinter.Button,
                        'tooltip':""" Add the selected geom to selected frame""",
                        'wcfg':{'text':'AddGeom','command':self.add_cb},
                        'gridcfg':{'row':1,'column':1,'rowspan':1 }})
            
            ifd.append({'name':'geomtoload',
                        'widgetType':ListChooser,
                        'tooltip':"""list of frame  the user chose to
                        apply to the pattern""",
                        'wcfg':{'entries':entryFrame,
                                'mode':'extended',
                                'lbwcfg':{'exportselection':0},
                                'title':'Frame(geom) to be display'},
                        'gridcfg':{'sticky':'we', 
                                   'row':0, 'column':2,'rowspan':3}})
            ifd.append({'name':'remove',
                        'widgetType':Tkinter.Button,
                        'tooltip':""" Remove the selected entry from the
                        commands to be applied to the object when loaded in the application""",
                        'wcfg':{'text':'REMOVE','width':10,
                                'command':self.remove_cb},
                        'gridcfg':{'sticky':'we','row':0, 'column':3}})
            
            ifd.append({'name':'oneup',
                        'widgetType':Tkinter.Button,
                        'tooltip':"""Move the selected entry up one entry""",
                        'wcfg':{'text':'Move up','width':10,
                                'command':self.moveup_cb},
                        'gridcfg':{'sticky':'we','row':1,'column':3}})
            
            ifd.append({'name':'onedown',
                        'widgetType':Tkinter.Button,
                        'tooltip':"""Move the selected entry down one entry""",
                        'wcfg':{'text':'Move down','width':10,
                                'command':self.movedown_cb},
                        'gridcfg':{'sticky':'we','row':2,'column':3}})

            self.form_Setanim = InputForm(self.master,None,descr=ifd,
                                  scrolledFrame=0)
            
            
            self.lc = self.form_Setanim.descr.entryByName['availableGeom']['widget']
            self.lc2 = self.form_Setanim.descr.entryByName['geomtoload']['widget']
            self.addObject(self.viewer.rootObject,None)
            val = self.form_Setanim.go()
            if val:
                self.assign()
                self.form_Setanim.withdraw()
        else:
            self.form_Setanim.deiconify()
            val = self.form_Setanim.go()
            if val:
                self.assign()
                self.form_Setanim.withdraw()
                
    def deleteAnim(self):
        """ Delete all frame from the player list."""

        self.Stop_cb()
        self.startFrame=0
        self.endFrame = -1
        self.maxFrame = 0
        self.targetFrame = self.endFrame
        self.target = self.endFrame
        self.currentFrameIndex =0


    def assign(self,list=None):
        """ assign the animation.
        framelist ; list of {}
        return a list of obj for each frame
        """
        self.deleteAnim()
        AllObjects = self.viewer.rootObject.AllObjects()
        if list :
            self.framelist=[]
            for f in list:
                self.framelist.append((f,[]))
        print "assign"
        print "self.framelist",self.framelist
        for frame in self.framelist:
            geomDic = frame[0]
            Namelist=[]
            for parents in geomDic.keys():
                parentlist = filter(lambda x, name=parents:x.name == name,AllObjects)
                obj = parentlist[0]
                childrens = geomDic[obj.name]
                if len(childrens) > 0:
                    for namegeom in childrens:
                        child = filter(lambda x,
                                       name=namegeom:x.name == name,
                                       obj.children)[0]
                        if child.children != []:
                            for c in child.children:
                                frame[1].append(c)
                        else:
                            frame[1].append(child)
                else:
                    frame[1].append(obj)

            self.endFrame = self.endFrame +1
            self.maxFrame = self.maxFrame +1
            self.targetFrame = self.endFrame
            self.target = self.endFrame


    def movedown_cb(self):
        """ move entry one down """
        sel = self.lc2.get()
        index = self.lc2.getInd()
        if not sel: return
        sel = sel[0]
        if string.find(sel,"frame") < 0: return
        # get frame Index
        frameInd = int(string.split(sel,'_')[1])
        currentframe = self.framelist[frameInd]
        if (frameInd + 1) >= len(self.framelist):return
        # select next Frame.
        nextframe = self.framelist[frameInd+1]
        # move current frame one down in list
        self.framelist[frameInd] =nextframe
        self.framelist[frameInd+1] =currentframe
        self.updatelistchooser(self.framelist)

    def moveup_cb(self):
        """ move entry one up """
        sel = self.lc2.get()
        index = self.lc2.getInd()
        if not sel: return
        sel = sel[0]
        if string.find(sel,"frame") < 0: return
        # get frame Index
        frameInd = int(string.split(sel,'_')[1])
        currentframe=self.framelist[frameInd]
        if (frameInd - 1) <  0 :return
        # select previous Frame
        prevframe = self.framelist[frameInd-1]
        # move current frame one up in list
        self.framelist[frameInd] =prevframe
        self.framelist[frameInd-1] =currentframe
        self.updatelistchooser(self.framelist)
        
    def addframe_cb(self):
        """ add a new frame entry"""
        frame = ({},[])
        nb = len(self.framelist)
        #frame.number = nbframe 
        value = 'frame_'+ str(nb)
        self.framelist.append(frame)
        self.lc2.deselect(0,last='end')
        self.lc2.insert('end',value)
        self.lc2.select('end')

    def add_cb(self):
        listgeom=[]
        # get the frame index to add new geom
        if len(self.lc2.entries)>0:
            ind = self.lc2.getInd()
            if len(ind) ==0:return # no entry selected so create a new frame
            # get geom name to load
            o = map(int,self.lc.lb.curselection())
            for Ind in o:
                    fullName = self.getFullName(Ind)
                    listgeom.append(fullName)
            # get frame instance
            for index in ind:
                value = self.lc2.entries[index][0]
                if string.find(value,"frame") < 0: return
                frameInd = int(string.split(value,'_')[1])
                frameGeom = self.framelist[frameInd][0]
                for geom in listgeom:
                    # strip the root
                    l = string.split(geom,'|')
                    if not frameGeom.has_key(l[1]):
                        frameGeom[l[1]]=[]
                    for i in l[2:]:
                        if not( i in frameGeom[l[1]]):
                            frameGeom[l[1]].append(i)

            self.updatelistchooser(self.framelist)
        else:
            return
        
    def updatelistchooser(self,entry):
        """ update what is display in the list chooser """
        # save current selection
        sel  = self.lc2.get()
        # remove current entry
        self.lc2.clear()
        prefix = '~'
        prefix2 = '~~'
        nb= 0
        for e in entry:
            v = 'frame_'+str(nb)
            nb = nb+1
            # listchooser entry has to be a tuple(value,comment)
            self.lc2.add((v,))
            for mol in e[0].keys():
                self.lc2.add((prefix+mol,))
                for geom in e[0][mol]:
                    self.lc2.add((prefix2+geom,))
        # select the entry save as sel
        # keep the entry selected after the update
        for i in sel:
            self.lc2.select((i,))


    def findFramefromGeomInd(self,index):
        """ return the frame number from  which the geom was selected """
        for i in range(index+1):
            value = self.lc2.entries[index-i][0]
            if string.find(value,"frame") >= 0:
                frameInd =  int(string.split(value,'_')[1])
                lcInd = index -i
                return (frameInd,lcInd)
        return 0
    
    def findParentGeom(self,index):
        """ find the parent value name from a geom ~~
        go up to find first value with onley ~ """
        parent = None
        for i in range(index+1):
            parent = self.lc2.entries[index -i][0]
            if parent[0] == '~' and parent[1] !='~':
                parent = parent[1:]
                return parent
        return  None
    
    def removeEntryGeom(self,value,index):
        """ the geom entry in the listchooser"""
        # first find from which frame we need to remove geom
        val = self.findFramefromGeomInd(index)
        if val:
            frameInd =val[0]
            lcInd = val[1]
            if value[1] == '~':
                parent = self.findParentGeom(index)
                if parent:
                    listgeom = self.framelist[frameInd][0][parent]
                    rindex = listgeom.index(value[2:])
                    del listgeom[rindex]
                
            elif self.framelist[frameInd][0].has_key(value[1:]):
                del self.framelist[frameInd][0][value[1:]]
            
            self.updatelistchooser(self.framelist)
            
    def removeEntryFrame(self,value,index):
        """ remove the frame entry in the listchooser"""
        # delete frame from framelist
        frameInd = int(string.split(value,'_')[1])
        del self.framelist[frameInd]
        # Update list chooser
        self.updatelistchooser(self.framelist)
        
    def remove_cb(self):
        """ remove entry in litschooser (geomtoload)"""
        selindex = self.lc2.getInd()
        for index in selindex:
            value = self.lc2.entries[index][0]
            if string.find(value,"frame") >= 0:
                self.removeEntryFrame(value,index)
            elif value[0] == '~':
                self.removeEntryGeom(value,index)
示例#8
0
class TrajPlayer(Player):
    """ a GUI to play a trajectory. The class constructor takes a Trajectory object and
        a correspoonding molecule as arguments."""
    
    def __init__(self, mol, traj, vf, titleStr=None, sequenceList=None,
                        idList = None, delta=0, form2=1,
                        ask=1, **kw):
        
        self.mol = mol
        self.traj = traj
        self.startFrame = 0
        self.ask = ask
        mol.allAtoms.addConformation(mol.allAtoms.coords[:])
        self.coordSlot = len(mol.allAtoms[0]._coords) - 1
        self.update(sequenceList, idList)
        kw['master'] = None
        if vf.hasGui :
            kw['master'] = vf.GUI.ROOT
        kw['endFrame'] = self.endFrame
        kw['maxFrame'] = self.endFrame
        kw['form2'] = form2
        kw['titleStr'] = titleStr
        self.vf = vf
        if self.vf.hasGui :
            apply(Player.__init__, (self,), kw)
        try:
            self.form.ifd.entryByName['setanimB']['widget'].grid_forget()
            #print 'withdrew SetAnim button'
            self.form.autoSize()
        except:
            pass

    def update(self, sequenceList=None, idList=None):
        if not sequenceList:
            self.sequenceList = range(len(self.traj.coords))
            #self.sequenceList = self.traj.coords.keys()
        else :
            self.sequenceList = sequenceList
        lenSeq = len(self.sequenceList)
        self.maxFrame = lenSeq
        self.endFrame = lenSeq
        if self.startFrame>lenSeq:
            self.startFrame = 0

        if hasattr(self, 'playModeForm'):
            e = self.playModeForm.descr.entryByName
            endTW = e['endFrameTW']['widget']
            #print 'setting endTW to ', self.endFrame
            endTW.max = self.endFrame
            endTW.set(self.endFrame)
            startTW = e['startFrameTW']['widget']
            startTW.set(self.startFrame)
        if not idList:
            #insert 0 for original state
            idL = range(0, len(self.sequenceList) + 1)
            self.idList = map(str, idL)
        else:
            self.idList = map(str, idList)
        #print "self.idList", self.idList
        
        if hasattr(self, 'form'):
            if hasattr(self.form, 'ent2'):
                newLen = max(map(len, self.idList))
                if newLen>3:
                    #print 'update:updating ent2 width'
                    self.form.ent2.config(width=newLen)
                self.form.ent2.delete(0,'end')
                #could use startFrame if it is valid here:
                if self.startFrame<=len(self.sequenceList) and self.startFrame>0:
                    next_val = str(self.idList[self.startFrame])
                    self.form.ent2.insert(0, next_val)
                    self.currentFrameIndex = self.startFrame
                    self.applyState(self.startFrame-1)
                else:
                    #print "restarting from frame =", self.idList[0]
                    #print self.startFrame, ": index out of range for ", sequenceList, "; resetting startFrame to  0"
                    self.form.ent2.insert(0, str(self.idList[0]))
                    #this calls applyState with reset flag
                    self.applyState(-1)


    def applyState(self, ind):
        """None<-applyState(ind)"""
        mol = self.mol
        # -1 is key for go back to original
        if int(ind)==-1:
            mol.allAtoms.setConformation(0)
            conf = None
        else:
            #in this case want to get new coords
            #coords = self.traj.coords["frame%d"%ind]
            coords = self.traj.coords[ind]
            coordsarr = (Numeric.array(coords)*10).astype("f")
            allAtoms = self.mol.allAtoms
            allAtoms.updateCoords(coordsarr[:], self.coordSlot)

        if not self.vf.hasGui: return
        event = EditAtomsEvent('coords', mol.allAtoms)
        self.vf.dispatchEvent(event)
        #modEvent = ModificationEvent('edit','coords', mol.allAtoms)
        #mol.geomContainer.updateGeoms(modEvent)
        self.vf.GUI.VIEWER.Redraw()
        #self.showStats()


   


    def SetMode_cb(self, event=None):
        #print 'SetMode'
        #playMode options:
        #   0   play once and stop
        #   1   play continuously in 1 direction
        #   2   play once in 2 directions
        #   3   play continuously in 2 directions
        #play framerate is frame/per second
        if not hasattr(self, 'playModeForm'):
            self.showPlayMode = Tkinter.IntVar()
            self.showFrameParmWidgets = Tkinter.IntVar()
            self.playModeVar = Tkinter.StringVar()
            self.playModeVar.set('once and stop')
            self.playModeList=[ 'once and stop', 
                                'continuously in 1 direction',
                                'once in 2 directions', 
                                'continuously in 2 directions']
            self.frameParmsList=[ 'framerateLabel','framerateTW','startFrameLabel', 
                                  'startFrameTW', 'endFrameLabel', 'endFrameTW', 
                                  'stepSizeLabel', 'stepSizeTW']

            #self.showListVar = Tkinter.IntVar()
            ifd2 = InputFormDescr(title='Set Play Options')    
            ## ifd2.append({'name':'selectCB',
##                 'widgetType': Tkinter.Checkbutton,
##                 'tooltip':'show ids of current ordered conformation list',
##                 'wcfg':{ 'text':'Show Conf List',
##                         #'command': self.showStatesList,
##                         #'variable': self.showListVar,
##                        },
##                 'gridcfg':{'sticky':'ew', 'row':-1, 'column':1}})
##                 #'gridcfg':{'sticky':'ew'}})
            ifd2.append({'name':'playModeMb',
                'widgetType': Tkinter.Menubutton,
                'tooltip':'set play mode choice',
                'wcfg':{ 'text':'Play Mode',
                       },
                'gridcfg':{'sticky':'we'}})
                #'gridcfg':{'sticky':'w', 'columnspan':2}})
            ifd2.append({'name':'adjustFrameParmsMb',
                'widgetType': Tkinter.Checkbutton,
                'tooltip':'opens panel to set play rate, start conf number, end conf number \nand step size for playing conf sequence',
                'wcfg':{ 'text':'Play Parameters',
                        'command': self.showFrameParms_cb,
                        'variable': self.showFrameParmWidgets,
                       },
                'gridcfg':{'sticky':'w', 'row':-1, 'column':1}})
            ifd2.append( {'name': 'framerateLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'frame rate:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'framerateTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set max num of confs to be displayed per second',
                    'wcfg':{'labCfg':{'fg':'black', 'side':'left', 'text':''},
                        'showLabel':1, 'width':100,
                        'min':0,
                        'max':100,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.framerate,
                        'oneTurn':100,
                        'type':'float',
                        'increment':.1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'red'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            ifd2.append( {'name': 'startFrameLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'start frame:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'startFrameTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set number of first conf to be displayed',
                    'wcfg':{
                        'labCfg':{
                            'fg':'black',
                            'side':'left',
                            'text':''
                            },
                        'showLabel':1, 'width':100,
                        'min':0,
                        'max':self.endFrame,
                        'lockBMin':0,
                        'lockBMax':1,
                        'lockBIncrement':1,
                        'value':self.startFrame,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'green'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'ew', 'row':-1,  'column':1}})
            ifd2.append( {'name': 'endFrameLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'end frame:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'endFrameTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set number of last conf to be displayed',
                    'wcfg':{
                        'labCfg':{
                            'fg':'black',
                            'side':'left',
                            'text':''
                            },
                        'showLabel':1, 'width':100,
                        'min':self.startFrame,
                        'max':self.maxFrame,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.endFrame,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'green'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            ifd2.append( {'name': 'stepSizeLabel',
                    'widgetType':Tkinter.Label,
                    'wcfg':{'text':'step size:',
                        'font':(ensureFontCase('helvetica'),12,'bold')},
                    'gridcfg':{'sticky':'w'}})
            ifd2.append({'name': 'stepSizeTW',
                    'wtype':ThumbWheel,
                    'widgetType':ThumbWheel,
                    'tooltip':'set step before next conf number: default is 1',
                    'wcfg':{
                        'labCfg':{
                            'fg':'black',
                            'side':'left',
                            'text':''
                            },
                        'showLabel':1, 'width':100,
                        'min':1,
                        'max':1000,
                        'lockBMin':1,
                        'lockBMax':0,
                        'lockBIncrement':1,
                        'value':self.stepSize,
                        'oneTurn':10,
                        'type':'int',
                        'increment':1,
                        'callback':self.setMode_cb,
                        'canvascfg':{'bg':'blue'},
                        'wheelLabcfg1':{'font':(ensureFontCase('times'),14,'bold')},
                        'wheelLabcfg2':{'font':(ensureFontCase('times'),14,'bold')},
                        'continuous':0, 'wheelPad':1, 'height':20},
                    'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})
            ifd2.append({'name':'buildB',
                'widgetType': Tkinter.Button,
                'tooltip':'build a new molecule with current conf coords\nand add it to viewer',
                'wcfg':{ 'text':'Build Current',
                        'command': self.Build_cb,
                       },
                'gridcfg':{'sticky':'we'}})
                #'gridcfg':{'sticky':'ew', 'row':-1, 'column':1}})

            ifd2.append({'name':'writeB',
                'widgetType': Tkinter.Button,
                'tooltip':'write a new file with current conf coords',
                'wcfg':{ 'text':'Write Current',
                        'command': self.Write_cb,
                       },
                #'gridcfg':{'sticky':'we'}})
                'gridcfg':{'sticky':'nesw', 'row':-1, 'column':1}})         

            ifd2.append({'name':'cancelB',
                        'widgetType': Tkinter.Button,
                        'wcfg':{
                            'text': 'Close',
                            'command': self.cancelPlayMode_cb,
                        },
                        #'gridcfg':{'sticky':'ew', 'row':-1, 'column':1}})
                        'gridcfg':{'sticky':'ew','columnspan':2}}),
            self.playModeForm = InputForm(self.master, self.root,
                        descr = ifd2,
                        modal = 0, blocking = 0)
            self.framerateWidget = ifd2.entryByName['framerateTW']['widget']
            self.startFrameWidget = ifd2.entryByName['startFrameTW']['widget']
            self.endFrameWidget = ifd2.entryByName['endFrameTW']['widget']
            self.stepSizeWidget = ifd2.entryByName['stepSizeTW']['widget']
            self.frameParmCfgs = []
            self.frameParmWidgets = []
            for i in self.frameParmsList:
                ent = ifd2.entryByName[i]
                self.frameParmCfgs.append(ent['gridcfg'])
                self.frameParmWidgets.append(ent['widget'])
            self.playModeMb = ifd2.entryByName['playModeMb']['widget']
            self.playModeMb.bind('<ButtonPress>', self.buildPlayModeMenu, add='+')
            self.showFrameParms_cb()
            #self.showList = ifd2.entryByName['selectCB']['widget']
        else:
            self.playModeVar.set(self.playModeList[self.playMode])
            self.framerateWidget.set(self.framerate)
            self.startFrameWidget.set(self.startFrame)
            self.endFrameWidget.set(self.endFrame)
            self.stepSizeWidget.set(self.stepSize)
            self.playModeForm.deiconify()
        self.playModeForm.autoSize()

    def buildPlayModeMenu(self, event=None):
        mB = self.playModeMb
        keyList = self.playModeList
        if not self.showPlayMode.get():
            #mB.config(bg='white')
            if not hasattr(mB, 'menu'):
                mB.menu = Tkinter.Menu(mB)
                mB['menu'] = mB.menu
            else:
                mB.menu.delete(1, 'end')
            for i in range(len(keyList)):
                mB.menu.add_radiobutton(label=keyList[i], var=self.playModeVar, 
                            value=keyList[i], command=self.setMode_cb)
            self.showPlayMode.set(1)
        else:
            mB.menu.unpost()
            self.showPlayMode.set(0)
            
    def showFrameParms_cb(self, event=None):
        if not self.showFrameParmWidgets.get():
            for w in self.frameParmWidgets:
                w.grid_forget()
        else:
            for i in range(len(self.frameParmWidgets)):
                w = self.frameParmWidgets[i]
                cfg = self.frameParmCfgs[i]
                w.grid(cfg)
        self.playModeForm.autoSize()

    def setMode_cb(self, event=None):
        curVal = self.playModeVar.get()
        #print 'setting playMode to ', curVal
        self.playMode = self.playModeList.index(curVal)
        #print 'setting playMode to ', curVal
        self.framerate = round(self.framerateWidget.get(),4)
        #print 'setting self.framerate ->', self.framerate
        self.timestamp= 1./self.framerate
        self.startFrame = self.startFrameWidget.get()
        self.endFrame = self.endFrameWidget.get()
        #print 'set endFrame to', self.endFrame
        self.stepSize = self.stepSizeWidget.get()
        self.playMode = self.playModeList.index(curVal)
        #i think this restarts the player's trip memory
        #that is, hasn't gone in any direction yet
        self.oneDirection = 0
        if not self.stop:
            self.stop = 1
            self.play(self.framerate)

            

    def setPlayMode_cb(self, event=None):
        self.setMode_cb()
        self.cancelPlayMode_cb()
        self.oneDirection = 0
        

    def SetRMSRef_cb(self, event=None):
        print 'in SetRMSRef_cb'
        return


    def Build_cb(self, event=None):
        #print building current
        """None<-Build_cb(mol, event=None)

        builds new molecule with current coordinates and adds it to the viewer
        """
        #FIRST CHECK THAT THIS HASN'T already been built
        #get the current counter content for name of new molecule
        #w = self.form.ifd.entryByName['statesCounter']['widget']
        numStr = self.form.counter.get()
        #numStr = w.get()
        #remember idList has '0' always added at the beginning for input conf
        confInd =  self.idList.index(numStr) - 1
        #CHECK THIS IS CORRECT!!!
        conf = self.sequenceList[confInd]
        self.buildConf(conf, numStr)


    def buildConf(self, conf, nameStr):
        newname = self.mol.name + '_conf_' + nameStr
        if newname in self.vf.Mols.name:
            msg = newname + ' already in viewer. Not building a second copy'
            self.vf.warningMsg(msg)
            return 'ERROR'
        allLines = self.mol.parser.allLines
        newLines = []
        coords = self.mol.allAtoms.coords
        natoms = len(coords)
        ctr = 0
        parser = self.mol.parser.__class__()
        if isinstance(parser, groParser):
            newLines.append(allLines[0])
            newLines.append(allLines[1])
            for l in allLines[2:natoms+2]:
                cc = coords[ctr]/10
                newLines.append(l[:20] +'%8.3f%8.3f%8.3f'%(cc[0],cc[1],cc[2])+ l[44:])
                ctr = ctr+1
            for l in allLines[natoms+2:]:
                newLines.append(l)
        else:
            for l in allLines:
                if find(l, 'ATOM')==0 or find(l, 'HETA')==0:
                    cc = coords[ctr]
                    newLines.append(l[:30] +'%8.3f%8.3f%8.3f'%(cc[0],cc[1],cc[2])+ l[54:])
                    ctr = ctr+1
                else:
                    newLines.append(l)
        
        parser.allLines = newLines
        filename = parser.filename = self.mol.parser.filename + '_conf_' + nameStr
        newMol = parser.parse()[0]          
        newMol.name = newname
        newMol = self.vf.addMolecule(newMol, ask=self.ask)


    def Write_cb(self, event=None):
        #print writing current
        """None<-Write_cb(mol, event=None)
        writes a new file with current coordinates
        """
        filename = self.vf.askFileSave(types=[('pdb files','*.pdb'),('pdbq files', '*.pdbq'),
                        ('pdbqt files', '*.pdbqt'), ('.gro. files', '*.gro'), ("all", "*")], 
                        title="write current conf:")
        if filename is not None:
            self.write_conf(filename)



    def write_conf(self, filename):       
            fptr = open(filename, 'w')
            ctr = 0
            liglines = self.mol.parser.allLines
            coords = self.mol.allAtoms.coords
            natoms = len(coords)
            if isinstance(self.mol.parser, groParser):
                fptr.write(liglines[0])
                fptr.write(liglines[1])
                for l in liglines[2:natoms+2]:
                    cc = coords[ctr]/10
                    fptr.write(l[:20] +'%8.3f%8.3f%8.3f'%(cc[0],cc[1],cc[2])+ l[44:])
                    ctr +=1
            for l in liglines[natoms+2:]:
                fptr.write(l)
            else:
                for l in liglines:
                    if l.find("ATOM")!=0 and l.find("HETATM")!=0:
                        l += "\n"
                        fptr.write(l)
                    else:
                        crds = coords[ctr] 
                        rec = "%s%8.3f%8.3f%8.3f%s\n"%(l[:30],crds[0], crds[1], crds[2],l[54:] ) 
                        fptr.write(rec)
                        ctr += 1
            fptr.close()