Files @ b19cd005a491
Branch filter:

Location: light9/bin/subcomposer - annotation

drewp@bigasterisk.com
just comments
Ignore-this: 850b0da90240ab6f764430505809fd6d
b5efddd80dad
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
5442f5d8979a
ce4fffe8e413
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
ce4fffe8e413
9dd2baa41cca
ce4fffe8e413
f29788d1c8c9
1a84c5e83d3e
1a84c5e83d3e
f29788d1c8c9
1a84c5e83d3e
ce4fffe8e413
f29788d1c8c9
1a84c5e83d3e
ce4fffe8e413
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
a6662d61ebcd
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
ce4fffe8e413
ce4fffe8e413
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
ce4fffe8e413
1a84c5e83d3e
2c782ca93e73
2c782ca93e73
2c782ca93e73
2c782ca93e73
a6662d61ebcd
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
a6662d61ebcd
1a84c5e83d3e
5442f5d8979a
f29788d1c8c9
2c782ca93e73
1a84c5e83d3e
7ecde61ebff1
a13f2caf6f25
1a84c5e83d3e
5442f5d8979a
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
ce4fffe8e413
1a84c5e83d3e
ce4fffe8e413
5442f5d8979a
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
2c782ca93e73
8b307310cc1b
8b307310cc1b
f29788d1c8c9
2c782ca93e73
2c782ca93e73
1a84c5e83d3e
1a84c5e83d3e
1a84c5e83d3e
8b307310cc1b
f29788d1c8c9
1a84c5e83d3e
ce4fffe8e413
f29788d1c8c9
ce4fffe8e413
f29788d1c8c9
1a84c5e83d3e
1a84c5e83d3e
2c782ca93e73
9827df597f86
2c782ca93e73
2c782ca93e73
8b307310cc1b
2c782ca93e73
2c782ca93e73
9827df597f86
ce4fffe8e413
4e558643c952
f29788d1c8c9
ce4fffe8e413
ce4fffe8e413
#!bin/python

from __future__ import division, nested_scopes
from optparse import OptionParser
import Tkinter as tk
import louie as dispatcher
from twisted.internet import reactor, tksupport, task

import run_local
from light9.dmxchanedit import Levelbox
from light9 import dmxclient, Patch, Submaster, showconfig, prof
from light9.uihelpers import toplevelat
from light9.rdfdb.syncedgraph import SyncedGraph
from light9.rdfdb import clientsession

class Subcomposer(tk.Frame):
    def __init__(self, master, graph, session):
        tk.Frame.__init__(self, master, bg='black')
        self.graph = graph
        self.session = session

        self.levelbox = Levelbox(self, graph)
        self.levelbox.pack(side='top')

        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():
            for lev in self.levelbox.levels:
                lev.setlevel(0)

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

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

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

    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()

    # this is going to be more like 'tie to sub' and 'untied'
    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 toDmxLevels(self):
        # the dmx levels we edit and output, range is 0..1 (dmx chan 1 is
        # the 0 element)
        out = {}
        for lev in self.levelbox.levels:
            out[lev.channelnum] = lev.currentlevel
        if not out:
            return []
        
        return [out.get(i, 0) for i in range(max(out.keys()) + 1)]
     
    def sendupdate(self):
        dmxclient.outputlevels(self.toDmxLevels(), twisted=True)


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)


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

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

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

    graph = SyncedGraph("subcomposer")
    session = clientsession.getUri('subcomposer', opts)

    sc = Subcomposer(root, graph, session)
    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])

    task.LoopingCall(sc.sendupdate).start(1)

    root.protocol('WM_DELETE_WINDOW', reactor.stop)
    tksupport.install(root,ms=10)
    prof.run(reactor.run, profile=False)