Changeset - fe9dff7dbffd
[Not reviewed]
default
0 1 0
Drew Perttula - 19 years ago 2006-06-19 02:20:41
drewp@bigasterisk.com
added C-l to launch subcomposer- in progress
keyboardcomposer will probably launch subcomposer correctly,
but i don't even know if KC blocks or not (untested), and
the SC is certainly a child process of the KC, which is
undesirable. We think that some sort of setpgrp call in
the child may fix that.
1 file changed with 24 insertions and 4 deletions:
0 comments (0 inline, 0 general)
bin/keyboardcomposer
Show inline comments
 
#!/usr/bin/python
 

	
 
from __future__ import division, nested_scopes
 
import sys, time
 
import os, sys, time, subprocess
 
from optparse import OptionParser
 

	
 
from twisted.internet import reactor, tksupport
 
from twisted.web import xmlrpc, server
 
from Tix import *
 
import Tix as tk
 
import pickle
 

	
 
import run_local
 
from light9.Fadable import Fadable
 
from light9.Submaster import Submasters, sub_maxes
 
from light9.subclient import SubClient
 
from light9 import dmxclient, showconfig, networking
 
from light9.uihelpers import toplevelat
 
from light9.uihelpers import toplevelat, bindkeys
 

	
 
nudge_keys = {
 
    'up' : list('qwertyuiop'),
 
    'down' : list('asdfghjkl')
 
}
 
nudge_keys['down'].append('semicolon')
 

	
 
class SubScale(Scale, Fadable):
 
    def __init__(self, master, *args, **kw):
 
        self.scale_var = kw.get('variable') or DoubleVar()
 
        kw.update({'variable' : self.scale_var,
 
                   'from' : 1, 'to' : 0, 'showvalue' : 0,
 
                   'sliderlength' : 15, 'res' : 0.01,
 
                   'width' : 40, 'troughcolor' : 'black', 'bg' : 'grey40',
 
                   'highlightthickness' : 1, 'bd' : 1,
 
                   'highlightcolor' : 'red', 'highlightbackground' : 'black',
 
                   'activebackground' : 'red'})
 
        Scale.__init__(self, master, *args, **kw)
 
        Fadable.__init__(self, var=self.scale_var, wheel_step=0.05)
 
        self.draw_indicator_colors()
 
    def draw_indicator_colors(self):
 
        if self.scale_var.get() == 0:
 
            self['troughcolor'] = 'black'
 
        else:
 
            self['troughcolor'] = 'blue'
 

	
 
class SubmasterTk(Frame):
 
    def __init__(self, master, name, current_level):
 
        Frame.__init__(self, master, bd=1, relief='raised', bg='black')
 
        self.name = name
 
        self.slider_var = DoubleVar()
 
        self.slider_var.set(current_level)
 
        self.scale = SubScale(self, variable=self.slider_var, width=20)
 
        namelabel = Label(self, text=name, font="Arial 9", bg='black',
 
            fg='white')
 
        namelabel.pack(side=TOP)
 
        levellabel = Label(self, textvariable=self.slider_var, font="Arial 11",
 
            bg='black', fg='white')
 
        levellabel.pack(side=TOP)
 
        self.scale.pack(side=BOTTOM, expand=1, fill=BOTH)
 
        bindkeys(self, "<Control-Key-l>", self.launch_subcomposer)
 

	
 
    def launch_subcomposer(self, *args):
 
        subprocess.Popen(["bin/subcomposer", self.name])
 

	
 
class KeyboardComposer(Frame, SubClient):
 
    def __init__(self, root, submasters, current_sub_levels=None):
 
        Frame.__init__(self, root, bg='black')
 
        SubClient.__init__(self)
 
        self.submasters = submasters
 
        self.name_to_subtk = {}
 
        self.current_sub_levels = {}
 
        if current_sub_levels:
 
        if current_sub_levels is not None:
 
            self.current_sub_levels = current_sub_levels
 
        else:
 
            try:
 
                self.current_sub_levels = \
 
                    pickle.load(file('.keyboardcomposer.savedlevels'))
 
            except IOError:
 
                pass
 

	
 
        self.draw_ui()
 
        self.send_levels_loop()
 
    def draw_ui(self):
 
        self.rows = [] # this holds Tk Frames for each row
 
        self.slider_vars = {} # this holds subname:sub Tk vars
 
        self.slider_table = {} # this holds coords:sub Tk vars
 
        self.name_to_subtk.clear() # subname : SubmasterTk instance
 
        self.current_row = 0
 
        
 
        self.make_key_hints()
 
        self.draw_sliders()
 
        self.highlight_row(self.current_row)
 
        self.rows[self.current_row].focus()
 

	
 
        self.buttonframe = Frame(self, bg='black')
 
        self.buttonframe.pack(side=BOTTOM)
 
@@ -238,50 +245,63 @@ class KeyboardComposer(Frame, SubClient)
 
            r.destroy()
 
        self.keyhints.destroy()
 
        self.buttonframe.destroy()
 
        self.draw_ui()
 

	
 
    def alltozero(self):
 
        for name, subtk in self.name_to_subtk.items():
 
            if subtk.scale.scale_var.get() != 0:
 
                subtk.scale.fade(value=0.0, length=0)
 

	
 
class LevelServer(xmlrpc.XMLRPC):
 
    def __init__(self,name_to_subtk):
 
        self.name_to_subtk = name_to_subtk
 
        
 
    def xmlrpc_fadesub(self,subname,level,secs):
 
        """submaster will fade to level in secs"""
 
        try:
 
            self.name_to_subtk[subname].scale.fade(level,secs)
 
            ret='ok'
 
        except Exception,e:
 
            ret=str(e)
 
        return ret
 

	
 
if __name__ == "__main__":
 
    parser = OptionParser()
 
    parser.add_option('--nonpersistent', action="store_true",
 
                      help="don't load or save levels")
 
    opts, args = parser.parse_args()
 
    
 
    s = Submasters()
 

	
 
    root = Tk()
 
    tl = toplevelat("Keyboard Composer", existingtoplevel=root)
 

	
 
    kc = KeyboardComposer(tl, s)
 
    startLevels = None
 
    if opts.nonpersistent:
 
        startLevels = {}
 
    kc = KeyboardComposer(tl, s, startLevels)
 
    kc.pack(fill=BOTH, expand=1)
 

	
 
    for helpline in ["Bindings: B3 mute; C-l edit levels in subcomposer"]:
 
        tk.Label(root,text=helpline, font="Helvetica -12 italic",
 
                 anchor='w').pack(side='top',fill='x')
 

	
 
    import twisted.internet
 
    try:
 
        ls = LevelServer(kc.name_to_subtk)
 
        reactor.listenTCP(networking.kcPort(), server.Site(ls))
 
    except twisted.internet.error.CannotListenError, e:
 
        print "Can't (and won't!) start level server:"
 
        print e
 

	
 
    root.protocol('WM_DELETE_WINDOW', reactor.stop)
 
    if not opts.nonpersistent:
 
    reactor.addSystemEventTrigger('after', 'shutdown', kc.save)
 
    
 
    tksupport.install(root,ms=10)
 
    if 0:
 
        sys.path.append("/home/drewp/projects/cuisine/pour")
 
        from utils import runstats
 
        runstats("reactor.run()")
 
    else:
 
        reactor.run()
0 comments (0 inline, 0 general)