Files @ b5efddd80dad
Branch filter:

Location: light9/bin/subcomposer - annotation

Drew Perttula
update more shbang lines
Ignore-this: fce511ba0c4892fad7eafd17dafe9a82
b5efddd80dad
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
42e4c4728a66
42e4c4728a66
42e4c4728a66
42e4c4728a66
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
7ecde61ebff1
9dd2baa41cca
1a84c5e83d3e
1a84c5e83d3e
f6ca2b2fa154
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
a6662d61ebcd
1a84c5e83d3e
42e4c4728a66
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
a6662d61ebcd
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
a6662d61ebcd
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
a6662d61ebcd
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
7ecde61ebff1
a13f2caf6f25
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
a13f2caf6f25
a13f2caf6f25
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
a6662d61ebcd
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
8b307310cc1b
8b307310cc1b
2c782ca93e73
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
8b307310cc1b
8b307310cc1b
1a84c5e83d3e
3e3ba0e3d4b8
cd75a12ad66d
3e3ba0e3d4b8
3e3ba0e3d4b8
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
9827df597f86
2c782ca93e73
2c782ca93e73
8b307310cc1b
2c782ca93e73
2c782ca93e73
9827df597f86
1a84c5e83d3e
4e558643c952
4e558643c952
4e558643c952
4e558643c952
4e558643c952
1a84c5e83d3e
1a84c5e83d3e
#!bin/python

from __future__ import division, nested_scopes
import sys,os,time,atexit
from optparse import OptionParser
import Tkinter as tk
try:
    from dispatch import dispatcher
except ImportError:
    import louie as dispatcher

import run_local
from light9.dmxchanedit import Levelbox
from light9 import dmxclient, Patch, Submaster, showconfig
from light9.uihelpers import toplevelat

class Subcomposer(tk.Frame):
    def __init__(self, master, levelboxopts=None, dmxdummy=0, numchannels=72,
        use_persistentlevels=0):
        tk.Frame.__init__(self, master, bg='black')
        self.dmxdummy = dmxdummy
        self.numchannels = numchannels

        self.levels = [0]*numchannels # levels should never get overwritten, just edited

        self.levelbox = Levelbox(self, num_channels=numchannels)
        self.levelbox.pack(side='top')
        # the dmx levels we edit and output, range is 0..1 (dmx chan 1 is
        # the 0 element)
        self.levelbox.setlevels(self.levels)

        self.savebox = EntryCommand(self, cmd=self.savenewsub)
        self.savebox.pack(side='top')

        self.loadbox = EntryCommand(self, verb="Load", cmd=self.loadsub)
        self.loadbox.pack(side='top')

        def alltozero():
            self.set_levels([0] * self.numchannels)
            dispatcher.send("levelchanged")

        tk.Button(self, text="all to zero", command=alltozero).pack(side='top')

        dispatcher.connect(self.levelchanged,"levelchanged")
        dispatcher.connect(self.sendupdate,"levelchanged")

        if use_persistentlevels:
            self.persistentlevels()

        self.lastupdate=0 # time we last sent to dmx

        self.lastsent=[] # copy of levels

    def fill_both_boxes(self, subname):
        for box in [self.savebox, self.loadbox]:
            box.set(subname)

    def persistentlevels(self):
        """adjusts levels from subcomposer.savedlevels, if possible; and
        arranges to save the levels in that file upon exit"""
        self.load_levels()
        atexit.register(self.save_levels)
    def save_levels(self, *args):
        levelfile = file("subcomposer.savedlevels","w")
        levelfile.write(" ".join(map(str, self.levels)))
    def load_levels(self):
        try:
            levelfile = file("subcomposer.savedlevels","r")
            levels = map(float, levelfile.read().split())
            self.set_levels(levels)
        except IOError:
            pass
    def levelchanged(self, channel=None, newlevel=None):
        if channel is not None and newlevel is not None:
            if channel>len(self.levels):
                return
            self.levels[channel-1]=max(0,min(1,float(newlevel)))
        self.levelbox.setlevels(self.levels)
    def savenewsub(self, subname):
        leveldict={}
        for i,lev in zip(range(len(self.levels)),self.levels):
            if lev!=0:
                leveldict[Patch.get_channel_name(i+1)]=lev

        s=Submaster.Submaster(subname,leveldict=leveldict)
        s.save()
    def loadsub(self, subname):
        """puts a sub into the levels, replacing old level values"""
        s=Submaster.Submasters(showconfig.getGraph()).get_sub_by_name(subname)
        self.set_levels(s.get_dmx_list())
        dispatcher.send("levelchanged")
    def sendupdate(self):
        if not self.dmxdummy:
            dmxclient.outputlevels(self.levels)
            self.lastupdate = time.time()
            self.lastsent = self.levels[:]
    def considersendupdate(self, use_after_loop=0):
        """If use_after_loop is true, it is the period of the after loop."""
        if self.lastsent != self.levels or time.time() > self.lastupdate + 1:
            self.sendupdate()
        if use_after_loop:
            self.after(use_after_loop, self.considersendupdate, use_after_loop)
    def set_levels(self, levels):
        oldLen = len(self.levels)
        self.levels[:] = levels + [0] * (oldLen - len(levels))
        dispatcher.send("levelchanged")

class EntryCommand(tk.Frame):
    def __init__(self, master, verb="Save", cmd=None):
        tk.Frame.__init__(self, master, bd=2, relief='raised')
        tk.Label(self, text="Sub name:").pack(side='left')
        self.cmd = cmd
        self.entry = tk.Entry(self)
        self.entry.pack(side='left', expand=True, fill='x')
        
        self.entry.bind("<Return>", self.action)
        tk.Button(self, text=verb, command=self.action).pack(side='left')

    def action(self, *args):
        subname = self.entry.get()
        self.cmd(subname)
        print "sub", self.cmd, subname

    def set(self, text):
        self.entry.delete(0, 'end')
        self.entry.insert(0, text)


def open_sub_editing_window(subname, use_mainloop=1, dmxdummy=0):
    if use_mainloop:
        toplevel = tk.Tk()
    else:
        toplevel = tk.Toplevel()
    if dmxdummy:
        dummy_str = ' (dummy)'
    else:
        dummy_str = ''
    toplevel.title("Subcomposer: %s%s" % (subname, dummy_str))
    sc = Subcomposer(toplevel, use_persistentlevels=0, dmxdummy=dmxdummy)
    sc.pack(fill='both', expand=1)
    sc.loadsub(subname)
    sc.considersendupdate(use_after_loop=10)
    if use_mainloop:
        tk.mainloop()

#############################

if __name__ == "__main__":
    parser = OptionParser(usage="%prog [subname]")
    parser.add_option('--no-geometry', action='store_true',
                      help="don't save/restore window geometry")
    opts, args = parser.parse_args()

    root=tk.Tk()
    root.config(bg='black')
    root.tk_setPalette("#004633")
    if not opts.no_geometry:
        toplevelat("subcomposer", root)

    sc = Subcomposer(root, dmxdummy=0,
                     #numchannels=276 # use this to see all the skyline dims
                     #numchannels=118
                     )
    sc.pack()

    tk.Label(root,text="Bindings: B1 adjust level; B2 set full; B3 instant bump",
             font="Helvetica -12 italic",anchor='w').pack(side='top',fill='x')

    if len(args) == 1:
        root.config(bg='green') # trying to make these look distinctive
        sc.loadsub(args[0])
        sc.fill_both_boxes(args[0])

    while 1:
        try:
            root.update()
        except tk.TclError:
            break

        sc.considersendupdate()
        time.sleep(.01)