changeset 12:7adc65771676

big restructuring - moved lots of things (including most panels) to other files
author drewp
date Sun, 07 Jul 2002 06:16:11 +0000
parents c65119b66b00
children e44f79919085
files light8/io.py light8/panels.py light8/rsn.py light8/uihelpers.py
diffstat 4 files changed, 105 insertions(+), 592 deletions(-) [+]
line wrap: on
line diff
--- a/light8/io.py	Sun Jul 07 06:01:57 2002 +0000
+++ b/light8/io.py	Sun Jul 07 06:16:11 2002 +0000
@@ -1,109 +1,17 @@
 
-
-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)
--- a/light8/panels.py	Sun Jul 07 06:01:57 2002 +0000
+++ b/light8/panels.py	Sun Jul 07 06:16:11 2002 +0000
@@ -1,19 +1,18 @@
 """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),
@@ -21,181 +20,92 @@
             ('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)
+    
--- a/light8/rsn.py	Sun Jul 07 06:01:57 2002 +0000
+++ b/light8/rsn.py	Sun Jul 07 06:16:11 2002 +0000
@@ -7,7 +7,11 @@
 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
@@ -32,32 +36,11 @@
 
 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
 
@@ -80,45 +63,17 @@
 
     _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'
@@ -130,117 +85,42 @@
     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)
@@ -250,6 +130,7 @@
     xfader.setupwidget(xf)
     controlpanel.pack()
 
+
 buildinterface()
 
 class Pickles:
@@ -304,11 +185,11 @@
 
 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
 
--- a/light8/uihelpers.py	Sun Jul 07 06:01:57 2002 +0000
+++ b/light8/uihelpers.py	Sun Jul 07 06:16:11 2002 +0000
@@ -1,63 +1,27 @@
 """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:
@@ -68,28 +32,7 @@
 # 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"""
@@ -100,132 +43,3 @@
     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()