def __init__(self, master, DUMMY): self.master = master self.DUMMY = DUMMY self.jostle_mode = 0 self.lastline = None self.channel_levels = [] # these are actually the labels for the # channel levels, and should probably be moved # to panels.Leveldisplay self.scalelevels = {} self.lastsublevels = {} # to determine which subs changed self.unchangedeffect = {} # dict of levels for lights that didn't # change last time self.lastunchangedgroup = {} # doesn't draw any UI yet-- look for self.xfader.setupwidget() self.xfader = Xfader(self.scalelevels) self.oldlevels = [None] * 68 # never replace this; just clear it self.subediting = Subediting(currentoutputlevels=self.oldlevels) self.windowpos = 0 self.get_data() self.buildinterface() self.load() print "Light 8.8: Entering backgroundloop" self.backgroundloop() self.updatestagelevels() self.rec_file = open('light9.log', 'a') self.record_start()
class Lightboard: def __init__(self, master, DUMMY): self.master = master self.DUMMY = DUMMY self.jostle_mode = 0 self.lastline = None self.channel_levels = [] # these are actually the labels for the # channel levels, and should probably be moved # to panels.Leveldisplay self.scalelevels = {} self.lastsublevels = {} # to determine which subs changed self.unchangedeffect = {} # dict of levels for lights that didn't # change last time self.lastunchangedgroup = {} # doesn't draw any UI yet-- look for self.xfader.setupwidget() self.xfader = Xfader(self.scalelevels) self.oldlevels = [None] * 68 # never replace this; just clear it self.subediting = Subediting(currentoutputlevels=self.oldlevels) self.windowpos = 0 self.get_data() self.buildinterface() self.load() print "Light 8.8: Entering backgroundloop" self.backgroundloop() self.updatestagelevels() self.rec_file = open('light9.log', 'a') self.record_start() def buildinterface(self): print "Light 8.8: Constructing interface..." for w in self.master.winfo_children(): w.destroy() print "\tstage" stage_tl = toplevelat('stage') s = stage.Stage(stage_tl) stage.createlights(s) s.setsubediting(self.subediting) s.pack() self.stage = s # save it sub_tl = toplevelat('sub') scene_tl = toplevelat('scenes') effect_tl = toplevelat('effect') print "\tslider patching -- It can't be turned off!" mapping_tl = toplevelat('mapping') self.slidermapper = ExtSliderMapper.ExtSliderMapper(mapping_tl, self.scalelevels, ExternalSliders(), self) self.slidermapper.pack() print "\tsubmaster control" self.subpanels = Subpanels(sub_tl, effect_tl, scene_tl, self, self.scalelevels, Subs, self.xfader, self.changelevel, self.subediting, Subs.longestsubname()) for n, lev in self.scalelevels.items(): self.lastsublevels[n] = lev.get() print "\tlevel display" leveldisplay_tl = toplevelat('leveldisplay') leveldisplay_tl.bind('<Escape>', sys.exit) self.leveldisplay = Leveldisplay(leveldisplay_tl, self.channel_levels) # I don't think we need this # for i in range(0,len(self.channel_levels)): # self.channel_levels[i].config(text=self.oldlevels[i]) # colorlabel(self.channel_levels[i]) print "\tconsole" Console(self) # root frame print "\tcontrol panel" self.master.configure(bg='black') controlpanel = Controlpanel(self.master, self.xfader, self.refresh, self.quit, self.toggle_jostle, self.nonzerosubs) print "\tcrossfader" xf=Frame(self.master) xf.pack(side='right') self.master.bind('<q>', self.quit) self.master.bind('<r>', self.refresh) leveldisplay_tl.bind('<q>', self.quit) leveldisplay_tl.bind('<r>', self.refresh) self.xfader.setupwidget(xf) controlpanel.pack() print "\tcue fader (skipped)" # cuefader_tl = toplevelat('cuefader') # cuefader = Fader(cuefader_tl, Subs.cues, self.scalelevels) # cuefader.pack() print "Light 8.8: Everything's under control" def get_data(self,*args): Subs.reload_data(self.DUMMY) Patch.reload_data(self.DUMMY) print "Light 8.8:", len(Patch.patch), "dimmers patched" print "Light 8.8:", len(Subs.subs), "submasters loaded" def refresh(self, *args): 'rebuild interface, reload data' print "Light 8.8: Refresh initiated. Cross your fingers." self.get_data() print "Light 8.8: Subediting refreshed" self.subediting.refresh() print "Light 8.8: Rebuilding interface..." self.buildinterface() bindkeys(self.master,'<Escape>', self.quit) print "Light 8.8: Setting up slider patching..." self.slidermapper.setup() # self.master.tk_setPalette('gray40') print "Light 8.8: Now back to your regularly scheduled Light 8" def stageassub(self): """returns the current onstage lighting as a levels dictionary, skipping the zeros, and using names where possible""" levs=self.oldlevels return dict([(Patch.get_channel_name(i),l) for i,l in zip(range(1,len(levs)+1),levs) if l>0]) def save_sub(self, name, levels, refresh=1): if not name: print "Enter sub name in console." return st = '' linebuf = 'subs["%s"] = {' % name for channame,lev in levels.items(): if len(linebuf) > 60: st += linebuf + '\n ' linebuf = '' linebuf += ' "%s" : %d,' % (channame, lev) st += linebuf + '}\n' if self.DUMMY: filename = 'ConfigDummy.py' else: filename = 'Config.py' f = open(filename, 'a') f.write(st) f.close() print 'Added sub:', st if refresh: self.refresh() # this is called on a loop, and ALSO by the Scales def changelevel(self, *args): 'Amp trims slider' # load levels from external sliders extlevels = self.slidermapper.get_levels() for name, val in extlevels.items(): if name in self.scalelevels: sl = self.scalelevels[name] sl.set(val) # newstart = time() # learn what changed unchangedgroup = {} changedgroup = {} for name, lastlevel in self.lastsublevels.items(): newlevel = self.scalelevels[name].get() if lastlevel != newlevel: changedgroup[name] = newlevel else: unchangedgroup[name] = newlevel changedeffect = {} if not changedgroup: # should load levels from last time pass else: # calculate effect of new group. this should take no time if # nothing changed for name, level in changedgroup.items(): newlevels = Subs.subs[name].get_levels(level=level) for (ch, fadelev) in newlevels.items(): changedeffect[ch-1] = \ max(changedeffect.get(ch-1, 0), fadelev) if unchangedgroup != self.lastunchangedgroup: # unchanged group changed! (confusing, huh?) # this means: the static subs from the last time are not the same # as they are this time, so we recalculate effect of unchanged group self.unchangedeffect = {} for name, level in unchangedgroup.items(): newlevels = Subs.subs[name].get_levels(level=level) for (ch, fadelev) in newlevels.items(): self.unchangedeffect[ch-1] = \ max(self.unchangedeffect.get(ch-1, 0), fadelev) self.lastunchangedgroup = unchangedgroup # record sublevels for future generations (iterations, that is) for name in self.lastsublevels: self.lastsublevels[name] = self.scalelevels[name] # merge effects together levels = [0] * 68 if changedeffect: levels = [int(max(changedeffect.get(ch, 0), self.unchangedeffect.get(ch, 0))) for ch in range(0, 68)] else: levels = [int(self.unchangedeffect.get(ch, 0)) for ch in range(0, 68)] ''' newend = time() levels_opt = levels oldstart = time() # i tried to optimize this to a dictionary, but there was no speed # improvement levels = [0] * 68 for name, s in Subs.subs.items(): sublevel = self.scalelevels[name].get() newlevels = s.get_levels(level=sublevel) self.lastsublevels[name] = sublevel # XXX remove for (ch, fadelev) in newlevels.items(): levels[ch-1] = max(levels[ch-1], fadelev) levels = [int(l) for l in levels] oldend = time() newtime = newend - newstart oldtime = oldend - oldstart print "new", newtime, 'old', (oldend - oldstart), 'sup', \ oldtime / newtime if levels != levels_opt: raise "not equal" # for l, lo in zip(levels, levels_opt): # print l, lo ''' for lev,lab,oldlev,numlab in zip(levels, self.channel_levels, self.oldlevels, self.leveldisplay.number_labels): if lev != oldlev: lab.config(text="%d" % lev) # update labels in lev display colorlabel(lab) # recolor labels if lev < oldlev: numlab['bg'] = 'blue' else: numlab['bg'] = 'red' else: numlab['bg'] = 'grey40' # replace the elements in oldlevels - don't make a new list # (Subediting is watching it) self.oldlevels[:] = levels[:] if self.jostle_mode: delta = random.randrange(-1, 2, 1) # (-1, 0, or 1) # print "delta", delta levels = [min(100, max(x + delta, 0)) for x in levels] # print "jostled", levels dmxclient.outputlevels([l/100 for l in levels]) # self.parportdmx.sendlevels(levels) def updatestagelevels(self): self.master.after(100, self.updatestagelevels) for lev, idx in zip(self.oldlevels, xrange(0, 68 + 1)): self.stage.updatelightlevel(Patch.get_channel_name(idx + 1), lev) def load(self): try: filename = '/tmp/light9.prefs' if self.DUMMY: filename += '.dummy' print "Light 8.8: Loading from", filename file = open(filename, 'r') p = cPickle.load(file) for s, v in p.scalelevels.items(): try: self.scalelevels[s].set(v) except Exception,e: print "Couldn't set %s -> %s: %s" % (s, v,e) for name, substate in p.substate.items(): try: Subs.subs[name].set_state(substate) except Exception, e: print "Couldn't set sub %s state: %s" % (name,e)