Changeset - 7adc65771676
[Not reviewed]
default
0 4 0
drewp - 22 years ago 2002-07-07 06:16:11

big restructuring - moved lots of things (including most panels) to other files
4 files changed with 105 insertions and 592 deletions:
0 comments (0 inline, 0 general)
light8/io.py
Show inline comments
 

	
 

	
 
class BaseIO:
 
    def __init__(self):
 
        self.dummy=1
 
        self.__name__ = 'BaseIO'
 
        # please override and set __name__ to your class name
 

	
 
    def golive(self):
 
        """call this if you want to promote the dummy object becomes a live object"""
 
        print "IO: %s is going live" % self.__name__
 
        self.dummy=0
 
        # you'd override with additional startup stuff here,
 
        # perhaps even loading a module and saving it to a class
 
        # attr so the subclass-specific functions can use it
 

	
 
    def godummy(self):
 
        print "IO: %s is going dummy" % self.__name__
 
        self.dummy=1
 
        # you might override this to close ports, etc
 
        
 
    def isdummy(self):
 
        return self.dummy
 
DUMMY=1
 

	
 
    def __repr__(self):
 
        if self.dummy:
 
            return "<dummy %s instance>" % self.__name__
 
        else:
 
            return "<live %s instance>" % self.__name__
 

	
 
    # the derived class will have more methods to do whatever it does,
 
    # and they should return dummy values if self.dummy==1.
 

	
 
class ParportDMX(BaseIO):
 
    def __init__(self, dimmers=68):
 
        BaseIO.__init__(self)
 
        self.__name__='ParportDMX'
 
        self.dimmers = dimmers
 

	
 
    def golive(self):
 
        BaseIO.golive(self)
 
        import parport
 
        self.parport = parport
 
        self.parport.getparport()
 
        
 
    def sendlevels(self, levels):
 
        if self.dummy:
 
            return
 
        
 
        levels = list(levels) + [0]
 
        # if levels[14] > 0: levels[14] = 100 # non-dim
 
        self.parport.outstart()
 
        for p in range(1, self.dimmers + 2):
 
            self.parport.outbyte(levels[p-1]*255 / 100)
 
def init(DUMMY_in):
 
    global DUMMY
 
    if not DUMMY_in:
 
        getparport()
 
        DUMMY=0
 

	
 
class SerialPots(BaseIO):
 
    """
 
    this is a dummy object (that returns zeros forever) until you call startup()
 
    which makes it bind to the port, etc
 
    
 
    """
 
    def __init__(self):
 
        # no init here- call getport() to actually initialize
 
        self.dummy=1
 
        self.__name__='SerialPots' # i thought this was automatic!
 

	
 
    def golive(self):
 
        """
 
        ls -l /dev/i2c-0
 
        crw-rw-rw-    1 root     root      89,   0 Jul 11 12:27 /dev/i2c-0
 
        """
 
        import serport
 
        self.serport = serport
 
        
 
        self.f = open("/dev/i2c-0","rw")
 

	
 
        # this is for a chip with A0,A1,A2 lines all low:
 
        port = 72
 

	
 
        from fcntl import *
 

	
 
        I2C_SLAVE = 0x0703  #/* Change slave address                 */
 
        ioctl(self.f,I2C_SLAVE,port)
 
        self.dummy=0
 

	
 
    def godummy(self):
 
        BaseIO.godummy(self)
 
        self.f.close()
 

	
 
    def getlevels(self):
 
        if self.dummy:
 
            return (0,0,0,0)
 
        else:
 
            return self.serport.read_all_adc(self.f.fileno())
 

	
 

	
 
if __name__=='__main__':
 
    
 
    """ tester program that just dumps levels for a while """
 
    from time import sleep
 
    from serport import *
 

	
 
    i=0
 
    while i<100:
 
        sleep(.033)
 
        i=i+1
 

	
 
        print read_all_adc(f.fileno())
 

	
 
def sendlevels(levels):
 
    if DUMMY: return
 
    levels = list(levels) + [0]
 
    if levels[14] > 0: levels[14] = 100
 
    # print "levels", ' '.join(["%3.1f" % l for l in levels])
 
    outstart()
 
    for p in range(1,70):
 
        outbyte(levels[p-1]*255/100)
light8/panels.py
Show inline comments
 
"""some of the panels"""
 
from __future__ import nested_scopes
 

	
 
from Tix import *
 
from Tkinter import *
 
from uihelpers import *
 
import Patch
 
from FlyingFader import FlyingFader
 

	
 
stdfont = ('Arial', 8)
 
monofont = ('Courier', 8)
 

	
 

	
 

	
 
class Controlpanel(Frame):
 
    def __init__(self, parent, xfader, refresh_cb, quit_cb, jostle_cb, 
 
                 whatsup_cb=None):
 
        Frame.__init__(self,parent, bg='black')
 
        controlpanel = self
 
    def __init__(self,parent,xfader,refresh_cb,quit_cb):
 
        Frame.__init__(self,parent)
 
        controlpanel=self
 
        for txt,cmd in (
 
            ('Quit',       quit_cb),
 
            ('Refresh',    refresh_cb),
 
            ('Clear all', xfader.clearallbuttons),
 
            ('On -> X',     lambda: xfader.grab('x')),
 
            ('Clear X',     lambda: xfader.clearallbuttons('x')),
 
            ('On -> Y',     lambda: xfader.grab('y')),
 
            ('Clear Y',     lambda: xfader.clearallbuttons('y')),
 
            ("What's up?",     whatsup_cb)):
 
            Button(controlpanel, text=txt, command=cmd, bg='black', 
 
                fg='white',font=stdfont, padx=0, pady=0).pack(side='top', fill='x')
 
        # jostle button
 
        Checkbutton(controlpanel, text="Jostle", bg='black', fg='white',
 
            command=jostle_cb).pack(side=TOP, fill=X)
 
            ('Clear Y',     lambda: xfader.clearallbuttons('y'))):
 
            Button(controlpanel, text=txt, command=cmd).pack(side='top', fill='x')
 

	
 

	
 
class Console:
 
    def __init__(self,lightboard):
 
        t=toplevelat('console')
 
        self.frame = Frame(t, bg='black')
 
        self.entry=Entry(self.frame, bg='black', fg='white')
 
    def __init__(self):
 
        print "Light 8: Everything's under control"
 
        t=toplevelat(267,717,w=599,h=19)
 
        self.frame = Frame(t)
 
        self.entry=Entry(self.frame)
 
        self.entry.pack(expand=1, fill='x')
 
        self.entry.bind('<Return>',
 
                        lambda evt: self.execute(evt, self.entry.get()))
 
        self.entry.bind('<Return>', lambda evt: self.execute(evt, self.entry.get()))
 
        self.frame.pack(fill=BOTH, expand=1)
 
        self.lightboard=lightboard
 
    
 
    def execute(self, evt, str):
 
        if str[0] == '*': # make a new sub from the current levels
 
            self.lightboard.save_sub(str,self.lightboard.stageassub())
 
    def execute(evt, str):
 
        if str[0] == '*': # make a new sub
 
            make_sub(str)
 
        else:
 
            print '>>>', str
 
            print eval(str)
 
            self.frame.focus()
 
        self.frame.focus()
 

	
 
class Leveldisplay:
 
    def __init__(self, parent, channel_levels, num_channels=68):
 
    def __init__(self,parent,_oldlevels):
 
        global channel_levels
 
        
 
        frames = (make_frame(parent), make_frame(parent))
 
        channel_levels[:]=[]
 
        self.number_labels = []
 
        for channel in range(1, num_channels+1):
 

	
 
            # frame for this channel
 
            f = Frame(frames[channel > (num_channels/2)])
 
            # channel number -- will turn yellow when being altered
 
            num_lab = Label(f, text=str(channel), width=3, bg='grey40', 
 
                fg='white', font=stdfont, padx=0, pady=0, bd=0, height=1)
 
            num_lab.pack(side='left')
 
            self.number_labels.append(num_lab)
 

	
 
            # text description of channel
 
            Label(f, text=Patch.get_channel_name(channel), width=8, 
 
                font=stdfont, anchor='w', padx=0, pady=0, bd=0, 
 
                height=1, bg='black', fg='white').pack(side='left')
 

	
 
            # current level of channel, shows intensity with color
 
            l = Label(f, width=3, bg='lightBlue', font=stdfont, anchor='e', 
 
                      padx=1, pady=0, bd=0, height=1)
 
        channel_levels=[]
 
        for channel in range(1, 69):
 
            f=Frame(frames[channel > 34])
 
            Label(f,text=str(channel), width=3, bg='lightPink', 
 
                font=stdfont, padx=0, pady=0, bd=0, height=1).pack(side='left')
 
            Label(f,text=Patch.get_channel_name(channel), width=8, 
 
                font=stdfont, anchor='w', padx=0, pady=0, bd=0, height=1).pack(side='left')
 
            l=Label(f,text=_oldlevels[channel-1], width=3, bg='lightBlue', 
 
                font=stdfont, anchor='e', padx=1, pady=0, bd=0, height=1)
 
            l.pack(side='left')
 
            colorlabel(l)
 
            channel_levels.append(l)
 
            f.pack(side='top')
 

	
 
        self.channel_levels = channel_levels
 
        # channel_levels is an output - changelevel will use it to access 
 
        # these labels
 

	
 
class Subpanels:
 
    def __init__(self, scenesparent, effectsparent, scenes, lightboard,
 
                 scalelevels, Subs, xfader,
 
                 changelevel, subediting, longestname):
 
    def __init__(self,scenesparent,effectsparent,scalelevels,Subs,xfader,changelevel):
 
        
 
        sublist = Subs.subs.items()
 
        sublist.sort()
 

	
 
        for p in scenesparent,effectsparent,scenes:
 
            sw = ScrolledWindow(p, bg='black')
 
            for but,units in ( (4,-4),(5,4) ):
 
                sw.window.bind("<ButtonPress-%s>"%but,lambda ev,s=sw.vsb,u=units: s.tk.call('tkScrollByUnits',s,'hv',u))
 

	
 
            sw.pack(expand=1,fill=BOTH)
 
            if p==scenesparent:
 
                scenesparent = sw.window
 
            elif p==effectsparent:
 
                effectsparent = sw.window
 
            else:
 
                scenes=sw.window
 

	
 
        for name, sub in sublist:
 
            # choose one of the sub panels to add to
 
            if sub.is_effect:
 
                parent=effectsparent
 
                side1='bottom'
 
                side2='left'
 
                orient1='vert'
 
                end1=0
 
                end2=1
 
                width1=len(name)
 
            elif name.startswith("*") and name[1].isdigit():
 
                parent=scenes
 
                side1='right'
 
                side2='top'
 
                orient1='horiz'
 
                end1=1
 
                end2=0
 
                width1=longestname
 
            else:
 
                parent=scenesparent
 
                side1='right'
 
                side2='top'
 
                orient1='horiz'
 
                end1=1
 
                end2=0
 
                width1=longestname
 

	
 
            # make frame that surrounds the whole submaster
 
            f=Frame(parent, bd=1, relief='raised', bg='black')
 
            f.pack(fill='both',exp=1,side=side2)
 
            
 
            f=Frame(parent, bd=1, relief='raised')
 
            f.pack(fill='both',exp=1,side='left')
 

	
 
            # make DoubleVar (there might be one left around from
 
            # before a refresh)
 
            if name not in scalelevels:
 
                # scalelevels[name]=FancyDoubleVar()
 
                scalelevels[name]=DoubleVar()
 

	
 
            sub.set_slider_var(scalelevels[name])
 

	
 
            scaleopts = {'troughcolor' : 'grey70'}
 
            scaleopts = {}
 
            if sub.color:
 
                scaleopts['troughcolor'] = sub.color
 
            s=Scale(f,command=lambda l,name=name: changelevel(name,l),showvalue=0,
 
                    length=300-17,variable=scalelevels[name],width=20,
 
                    to=0,res=.001,from_=1,bd=1, **scaleopts)
 
            l=Label(f,text=str(name), font=stdfont, padx=0, pady=0)
 
            v=Label(f,textvariable=scalelevels[name], font=stdfont, padx=0, pady=0)
 
            l.pack(side='bottom')
 
            v.pack(side='bottom')
 

	
 
            s = FlyingFader(f, label=str(name), variable=scalelevels[name],
 
                            showvalue=0, length=100,
 
                            width=14, sliderlength=14,
 
                            to=end1,res=.001,from_=end2,bd=1, font=stdfont,
 
                            orient=orient1,
 
                            labelwidth=width1,
 
                            **scaleopts)
 
            s.configure(bg='black')
 
            s.label.configure(bg='black', fg='white')
 
            s.vlabel.configure(bg='black', fg='white')
 
            s.scale.configure(bg='black', fg='white')
 
            for axis in ('y','x'):
 
                cvar=IntVar()
 
                cb=Checkbutton(f,text=axis,variable=cvar,font=stdfont, padx=0, pady=0, bd=1)
 
                button = ('Alt','Control')[axis=='y'] # unused?
 
    #            s.bind('<Key-%s>'%axis, lambda ev,cb=cb: cb.invoke)
 
                cb.pack(side='bottom',fill='both', padx=0, pady=0)
 
                xfader.registerbutton(name,axis,cvar)
 

	
 
            # tell subediting what widgets to highlight when it's
 
            # editing a sub
 
            for w in (s,s.label,s.vlabel, s.scale):
 
                subediting.register(subname=name,widget=w)
 

	
 
            if not sub.is_effect:
 
                self.subeditingbuttons(f,side1,sub,name,lightboard,subediting)
 

	
 
            self.axisbuttons(f,s,xfader,stdfont,side1,name)
 

	
 
            s.pack(side='left', fill=BOTH, expand=1)
 
            s.pack(side='left')
 
            s.bind('<3>', lambda evt, v=scalelevels[name]: toggle_slider(v))\
 

	
 
            # effects frame?
 
            sframe = Frame(f,bd=2,relief='groove')
 
            sub.draw_tk(sframe)
 
            sframe.pack(side='left',fill='y')
 

	
 
    def subediting_edit(self,subediting,sub):
 
        subediting.setsub(sub)
 
        
 
    def subediting_save(self,name,sub,lightboard):
 
        lightboard.save_sub(name,sub.getlevels(),refresh=0)
 
        
 
    def subeditingbuttons(self,f,side1,sub,name,lightboard,subediting):
 
        for txt,cmd in (("Edit",lambda subediting=subediting,sub=sub: self.subediting_edit(subediting,sub)),
 
                        ("Save",lambda sub=sub,name=name,lightboard=lightboard: self.subediting_save(name,sub,lightboard)),
 
                        ("SaveStg",lambda l=lightboard,name=name: l.save_sub(name,l.stageassub(),refresh=1)),
 
                        ):
 
            eb = Button(f,text=txt,font=stdfont,padx=0,pady=0,
 
                        bd=1,command=cmd, bg='black', fg='white')
 
            eb.pack(side=side1,fill='both',padx=0,pady=0)
 
            
 
    def axisbuttons(self,f,s,xfader,stdfont,side1,name):
 
        for axis in ('y','x'):
 
            cvar=IntVar()
 
            eb_color = ('red', 'green')[axis == 'y']
 
            cb=Togglebutton(f,text=axis.upper(),variable=cvar,font=stdfont, 
 
                            padx=3, pady=0, bd=1, downcolor=eb_color, 
 
                            bg='black', fg='white')
 
            cb.pack(side=side1,fill='both', padx=0, pady=0)
 
            s.bind('<Key-%s>'%axis, lambda ev,cb=cb: cb.invoke)
 
            xfader.registerbutton(name,axis,cvar)
 
    
light8/rsn.py
Show inline comments
 
@@ -4,13 +4,17 @@ from __future__ import nested_scopes
 
from Tkinter import *
 
from parport import *
 
from time import sleep
 
from signal import *
 
import sys, thread, cPickle
 

	
 
import io
 
from uihelpers import *
 
from panels import *
 
from Xfader import *
 
import stage
 

	
 
if len(sys.argv) >= 2:
 
    DUMMY = 0
 
    print "This is the real thing, baby"
 
    window_title = "Light 8.8 (On Air)"
 
else:
 
@@ -29,38 +33,17 @@ def get_data(*args):
 
    Patch.reload_data(DUMMY)
 
    print "Patch:", Patch.patch
 
    print "Subs:", ', '.join(Subs.subs.keys())
 

	
 
get_data()
 

	
 
if not DUMMY:
 
    getparport()
 

	
 
def sendlevels(levels):
 
    if DUMMY: return
 
    levels = list(levels) + [0]
 
    if levels[14] > 0: levels[14] = 100
 
    # print "levels", ' '.join(["%3.1f" % l for l in levels])
 
    outstart()
 
    for p in range(1,70):
 
        outbyte(levels[p-1]*255/100)
 
io.init(DUMMY)
 

	
 
channel_levels = []
 
scalelevels = {}
 
fades = {}
 
stdfont = ('Arial', 8)
 
monofont = ('Courier', 8)
 

	
 
def colorlabel(label):
 
    txt=label['text'] or "0"
 
    lev=float(txt)/100
 
    low=(80,80,180)
 
    high=(255,55,050)
 
    out = [int(l+lev*(h-l)) for h,l in zip(high,low)]
 
    col="#%02X%02X%02X" % tuple(out)
 
    label.config(bg=col)
 

	
 
_oldlevels=[None] * 68
 

	
 
def changelevel(*args):
 
    'Amp trims slider'
 
    global _oldlevels
 
@@ -77,182 +60,80 @@ def changelevel(*args):
 
        if lev != oldlev:
 
            lab.config(text="%d" % lev)
 
            colorlabel(lab)
 

	
 
    _oldlevels = levels[:]
 
        
 
    sendlevels(levels)
 
    io.sendlevels(levels)
 

	
 
def backgroundloop(*args):
 
    root.after(50, backgroundloop, ())
 
    changelevel()
 
    
 
def make_frame(parent):
 
    f = Frame(parent, bd=0)
 
    f.pack(side='left')
 
    return f
 

	
 
def add_fade(slider, evt):
 
    print 'b3!'
 

	
 
def execute(evt, str):
 
    if str[0] == '*': # make a new sub
 
        make_sub(str)
 
    else:
 
        print '>>>', str
 
        print eval(str)
 
    console_frame.focus()
 
    
 
def console():
 
    global console_entry, console_frame
 
    print "Light 8: Everything's under control"
 
    t=Toplevel(root)
 
    console_frame = Frame(t)
 
    console_entry=Entry(console_frame)
 
    console_entry.pack(expand=1, fill='x')
 
    console_entry.bind('<Return>', lambda evt: execute(evt, 
 
                                        console_entry.get()))
 
    console_frame.pack(fill=BOTH, expand=1)
 
    t.wm_geometry("599x19+267+717")
 

	
 
buildinterface = None # temporary
 
def refresh(*args):
 
    get_data()
 
    buildinterface()
 
    bindkeys('<Escape>', quit)
 
    bindkeys(root,'<Escape>', quit)
 

	
 
def quit(*args):
 
    filename = '/tmp/light9.prefs'
 
    if DUMMY:
 
        filename += '.dummy'
 
    print "Saving to", filename
 
    file = open(filename, 'w')
 
    cPickle.dump(Pickles(scalelevels), file)
 
    root.destroy()
 
    sys.exit()
 

	
 
def bindkeys(key, func):
 
    root.bind(key, func)
 
    for w in root.winfo_children():
 
        w.bind(key, func)
 

	
 
xfader=Xfader(scalelevels)
 

	
 

	
 
def toggle_slider(s):
 
    if s.get() == 0:
 
        s.set(100)
 
    else:
 
        s.set(0)
 
def printout(t):
 
    print t
 
    
 
xfader=Xfader(scalelevels)
 

	
 
def buildinterface(*args):
 
    global channel_levels, _oldlevels, leveldisplay, stdfont, monofnt, xfader
 
    global channel_levels, _oldlevels, leveldisplay, xfader
 
    for w in root.winfo_children():
 
        w.destroy()
 

	
 
    sublist = Subs.subs.items()
 
    sublist.sort()
 

	
 
    sub_tl = Toplevel()
 
    sub_tl.wm_geometry("+0+0")
 
    effect_tl = Toplevel()
 
    effect_tl.wm_geometry("+0+352")
 

	
 
    for name, sub in sublist:
 
        if sub.is_effect:
 
            f=Frame(effect_tl, bd=1, relief='raised')
 
        else:
 
            f=Frame(sub_tl, bd=1, relief='raised')
 

	
 
        f.pack(fill='both',exp=1,side='left')
 
        
 
        if name not in scalelevels:
 
            scalelevels[name]=DoubleVar()
 

	
 
        sub.set_slider_var(scalelevels[name])
 
    stage_tl=toplevelat(165,90)
 
    s=stage.Stage(stage_tl)
 
    stage.createlights(s)
 
    s.pack()
 

	
 
        scaleopts = {}
 
        if sub.color:
 
            scaleopts['troughcolor'] = sub.color
 
        s=Scale(f,command=lambda l,name=name: changelevel(name,l),showvalue=0,
 
                length=300-17,variable=scalelevels[name],width=20,
 
                to=0,res=.001,from_=1,bd=1, **scaleopts)
 
        l=Label(f,text=str(name), font=stdfont, padx=0, pady=0)
 
        v=Label(f,textvariable=scalelevels[name], font=stdfont, padx=0, pady=0)
 
        l.pack(side='bottom')
 
        v.pack(side='bottom')
 
    sub_tl = toplevelat(0,0)
 
    effect_tl = toplevelat(0,352)
 

	
 
        for axis in ('y','x'):
 
            cvar=IntVar()
 
            cb=Checkbutton(f,text=axis,variable=cvar,font=stdfont, padx=0, pady=0, bd=1)
 
            button = ('Alt','Control')[axis=='y'] # unused?
 
#            s.bind('<Key-%s>'%axis, lambda ev,cb=cb: cb.invoke)
 
            cb.pack(side='bottom',fill='both', padx=0, pady=0)
 
            xfader.registerbutton(name,axis,cvar)
 

	
 
        s.pack(side='left')
 
        s.bind('<3>', lambda evt, v=scalelevels[name]: toggle_slider(v))\
 
        
 
        sframe = Frame(f,bd=2,relief='groove')
 
        sub.draw_tk(sframe)
 
        sframe.pack(side='left',fill='y')
 
    Subpanels(sub_tl,effect_tl,scalelevels,Subs,xfader,changelevel)
 

	
 
    # def event_printer(evt):
 
        # print dir(evt)
 

	
 
    # sub_tl.bind('<b>', event_printer)
 
    leveldisplay=Toplevel(root)    
 
    leveldisplay=toplevelat(873,400)
 
    leveldisplay.bind('<Escape>', sys.exit)
 
    leveldisplay.wm_geometry('+873+400')
 
    frames = (make_frame(leveldisplay), make_frame(leveldisplay))
 
    channel_levels=[]
 
    for channel in range(1, 69):
 
        f=Frame(frames[channel > 34])
 
        Label(f,text=str(channel), width=3, bg='lightPink', 
 
            font=stdfont, padx=0, pady=0, bd=0, height=1).pack(side='left')
 
        Label(f,text=Patch.get_channel_name(channel), width=8, 
 
            font=stdfont, anchor='w', padx=0, pady=0, bd=0, height=1).pack(side='left')
 
        l=Label(f,text=_oldlevels[channel-1], width=3, bg='lightBlue', 
 
            font=stdfont, anchor='e', padx=1, pady=0, bd=0, height=1)
 
        l.pack(side='left')
 
        colorlabel(l)
 
        channel_levels.append(l)
 
        f.pack(side='top')
 
    
 
    console()
 

	
 
    Leveldisplay(leveldisplay,_oldlevels)
 

	
 
    Console()
 

	
 
    # root frame
 
    controlpanel = Frame(root)
 
    xf=Frame(controlpanel)
 
    controlpanel = Controlpanel(root,xfader,refresh,quit)
 
    
 
    xf=Frame(root)
 
    xf.pack(side='right')
 
    for txt,cmd in (
 
        ('Quit',       quit),
 
        ('Refresh',    refresh),
 
        ('Clear all', xfader.clearallbuttons),
 
        ('On -> X',     lambda: xfader.grab('x')),
 
        ('Clear X',     lambda: xfader.clearallbuttons('x')),
 
        ('On -> Y',     lambda: xfader.grab('y')),
 
        ('Clear Y',     lambda: xfader.clearallbuttons('y'))):
 
        Button(controlpanel, text=txt, command=cmd).pack(side='top', fill='x')
 

	
 
    # Button(controlpanel, text='Quit',       command=quit).pack(side='left')
 
    # Button(controlpanel, text='Refresh',    command=refresh).pack(side='left')
 
    # Button(controlpanel, text='Clearxfade', command=xfader.clearallbuttons).pack(side='left')
 
    # Button(controlpanel, text='Grab x',     command=lambda: xfader.grab('x')).pack(side='left')
 
    # Button(controlpanel, text='Grab y',     command=lambda: xfader.grab('y')).pack(side='left')
 

	
 
    root.bind('<q>', quit)
 
    root.bind('<r>', refresh)
 
    leveldisplay.bind('<q>', quit)
 
    leveldisplay.bind('<r>', refresh)
 

	
 
    xfader.setupwidget(xf)
 
    controlpanel.pack()
 

	
 

	
 
buildinterface()
 

	
 
class Pickles:
 
    def __init__(self, scalelevels):
 
        self.scalelevels = dict([(name, lev.get()) 
 
            for name,lev in scalelevels.items()])
 
@@ -301,17 +182,17 @@ def make_sub(name):
 
    f.close()
 
    print 'Added sub:', st
 
    refresh()
 

	
 
load()
 
signal(SIGINT, quit)
 
bindkeys('<Escape>', quit)
 
bindkeys(root,'<Escape>', quit)
 

	
 
# bindkeys('<q>', quit)
 
# bindkeys('<r>', refresh)
 
# bindkeys('<s>', make_sub)
 
# bindkeys(root,'<q>', quit)
 
# bindkeys(root,'<r>', refresh)
 
# bindkeys(root,'<s>', make_sub)
 
backgroundloop()
 
root.mainloop() # Receiver switches main
 

	
 
while 1:
 
    for lev in range(0,255,25)+range(255,0,-25):
 
        sleep(.2)
light8/uihelpers.py
Show inline comments
 
"""all the tiny tk helper functions"""
 

	
 
from __future__ import nested_scopes
 
from Tkinter import *
 
from Tix import *
 
from types import StringType
 

	
 
windowlocations = {
 
    'sub' : '425x738+00+00',
 
    'console' : '168x24+848+000',
 
    'leveldisplay' : '144x340+870+400',
 
    'cuefader' : '314x212+546+741',
 
    'effect' : '24x24+0963+338',
 
    'stage' : '823x683+37+030',
 
    'scenes' : '504x198+462+12',
 
}
 

	
 
def make_frame(parent):
 
    f = Frame(parent, bd=0, bg='black')
 
    f = Frame(parent, bd=0)
 
    f.pack(side='left')
 
    return f
 

	
 

	
 
def bindkeys(root,key, func):
 
    root.bind(key, func)
 
    for w in root.winfo_children():
 
        w.bind(key, func)
 

	
 

	
 
def toplevel_savegeometry(tl,name):
 
    try:
 
        geo = tl.geometry()
 
        if not geo.startswith("1x1"):
 
            f=open(".light9-window-geometry-%s" % name.replace(' ','_'),'w')
 
            f.write(tl.geometry())
 
        # else the window never got mapped
 
    except:
 
        # it's ok if there's no saved geometry
 
        pass
 

	
 
    # this would get called repeatedly for each child of the window (i
 
    # dont know why) so we unbind after the first Destroy event
 
    tl.unbind("<Destroy>",tl._toplevelat_funcid)
 
def toplevelat(x,y,w=None,h=None):
 
    tl=Toplevel()
 
    if w and h:
 
        tl.wm_geometry("%dx%d+%d+%d"%(w,h,x,y))
 
    else:
 
        tl.wm_geometry("+%d+%d"%(x,y))
 
    return tl
 

	
 
def toplevelat(name, existingtoplevel=None):
 
    tl = existingtoplevel or Toplevel()
 
    tl.title(name)
 

	
 
    try:
 
        f=open(".light9-window-geometry-%s" % name.replace(' ','_'))
 
        windowlocations[name]=f.read() # file has no newline
 
    except:
 
        # it's ok if there's no saved geometry
 
        pass
 

	
 
    if name in windowlocations:
 
        tl.geometry(windowlocations[name])
 

	
 
    tl._toplevelat_funcid=tl.bind("<Destroy>",lambda ev,tl=tl,name=name: toplevel_savegeometry(tl,name))
 

	
 
    return tl
 

	
 
def toggle_slider(s):
 
    if s.get() == 0:
 
        s.set(100)
 
    else:
 
        s.set(0)
 

	
 
# for lambda callbacks    
 
def printout(t):
 
    print t
 

	
 
def printevent(ev):
 
    for k in dir(ev):
 
        if not k.startswith('__'):
 
            print k,getattr(ev,k)
 
    print ""
 
    
 
def eventtoparent(ev,sequence):
 
    "passes an event to the parent, screws up TixComboBoxes"
 

	
 
    wid_class = str(ev.widget.__class__)
 
    if wid_class == 'Tix.ComboBox' or wid_class == 'Tix.TixSubWidget':
 
        return
 

	
 
    evdict={}
 
    for x in ['state', 'time', 'y', 'x', 'serial']:
 
        evdict[x]=getattr(ev,x)
 
#    evdict['button']=ev.num
 
    par=ev.widget.winfo_parent()
 
    if par!=".":
 
        ev.widget.nametowidget(par).event_generate(sequence,**evdict)
 
    #else the event made it all the way to the top, unhandled
 

	
 
def colorlabel(label):
 
    """color a label based on its own text"""
 
    txt=label['text'] or "0"
 
    lev=float(txt)/100
 
    low=(80,80,180)
 
    high=(255,55,050)
 
    out = [int(l+lev*(h-l)) for h,l in zip(high,low)]
 
    col="#%02X%02X%02X" % tuple(out)
 
    label.config(bg=col)
 

	
 
# TODO: get everyone to use this
 
def colorfade(low, high, percent):
 
    '''not foolproof.  make sure 0 < percent < 1'''
 
    out = [int(l+percent*(h-l)) for h,l in zip(high,low)]
 
    col="#%02X%02X%02X" % tuple(out)
 
    return col
 

	
 
def colortotuple(anytkobj, colorname):
 
    'pass any tk object and a color name, like "yellow"'
 
    rgb = anytkobj.winfo_rgb(colorname)
 
    return [v / 256 for v in rgb]
 

	
 
class Togglebutton(Button):
 
    """works like a single radiobutton, but it's a button so the
 
    label's on the button face, not to the side. the optional command
 
    callback is called on button set, not on unset. takes a variable
 
    just like a checkbutton"""
 
    def __init__(self,parent,variable=None,command=None,downcolor='red',**kw):
 

	
 
        self.oldcommand = command
 
        Button.__init__(self,parent,command=self.invoke,**kw)
 

	
 
        self._origbkg = self.cget('bg')
 
        self.downcolor = downcolor
 

	
 
        self._variable = variable
 
        if self._variable:
 
            self._variable.trace('w',self._varchanged)
 
            self._setstate(self._variable.get())
 
        else:
 
            self._setstate(0)
 

	
 
        self.bind("<Return>",self.invoke)
 
        self.bind("<1>",self.invoke)
 
        self.bind("<space>",self.invoke)
 

	
 
    def _varchanged(self,*args):
 
        self._setstate(self._variable.get())
 
        
 
    def invoke(self,*ev):
 
        if self._variable:
 
            self._variable.set(not self.state)
 
        else:
 
            self._setstate(not self.state)
 
        
 
        if self.oldcommand and self.state: # call command only when state goes to 1
 
            self.oldcommand()
 
        return "break"
 

	
 
    def _setstate(self,newstate):
 
        self.state = newstate
 
        if newstate: # set
 
            self.config(bg=self.downcolor,relief='sunken')
 
        else: # unset
 
            self.config(bg=self._origbkg,relief='raised')
 
        return "break"
 

	
 

	
 
class FancyDoubleVar(DoubleVar):
 
    def __init__(self,master=None):
 
        DoubleVar.__init__(self,master)
 
        self.callbacklist = {} # cbname : mode
 
        self.namedtraces = {} # name : cbname
 
    def trace_variable(self,mode,callback):
 
        """Define a trace callback for the variable.
 

	
 
        MODE is one of "r", "w", "u" for read, write, undefine.
 
        CALLBACK must be a function which is called when
 
        the variable is read, written or undefined.
 

	
 
        Return the name of the callback.
 
        """
 
        cbname = self._master._register(callback)
 
        self._tk.call("trace", "variable", self._name, mode, cbname)
 
        
 
        # we build a list of the trace callbacks (the py functrions and the tcl functionnames)
 
        self.callbacklist[cbname] = mode
 
#        print "added trace:",callback,cbname
 
        
 
        return cbname
 
    trace=trace_variable
 
    def disable_traces(self):
 
        for cb,mode in self.callbacklist.items():
 
#            DoubleVar.trace_vdelete(self,v[0],k)
 
            self._tk.call("trace", "vdelete", self._name, mode,cb)
 
            # but no master delete!
 
            
 
    def recreate_traces(self):
 
        for cb,mode in self.callbacklist.items():
 
#            self.trace_variable(v[0],v[1])
 
            self._tk.call("trace", "variable", self._name, mode,cb)
 

	
 
    def trace_named(self, name, callback):
 
        if name in self.namedtraces:
 
            print "FancyDoubleVar: already had a trace named %s - replacing it" % name
 
            self.delete_named(name)
 

	
 
        cbname = self.trace_variable('w',callback) # this will register in self.callbacklist too
 
        
 
        self.namedtraces[name] = cbname
 
        return cbname
 
        
 
    def delete_named(self, name):
 
        if name in self.namedtraces:
 

	
 
            cbname = self.namedtraces[name]
 
            
 
            self.trace_vdelete('w',cbname)
 
	    #self._tk.call("trace","vdelete",self._name,'w',cbname)
 
            print "FancyDoubleVar: successfully deleted trace named %s" % name
 
        else:
 
            print "FancyDoubleVar: attempted to delete named %s which wasn't set to any function" % name
 

	
 
def get_selection(listbox):
 
    'Given a listbox, returns first selection as integer'
 
    selection = int(listbox.curselection()[0]) # blech
 
    return selection
 

	
 
if __name__=='__main__':
 
    root=Tk()
 
    root.tk_focusFollowsMouse()
 
    iv=IntVar()
 
    def cb():
 
        print "cb!"
 
    t = Togglebutton(root,text="testbutton",command=cb,variable=iv)
 
    t.pack()
 
    Entry(root,textvariable=iv).pack()
 
    root.mainloop()
0 comments (0 inline, 0 general)