changeset 51:71489bb71528

- Meet Fader. He is going to grow up and be a crossfader some day - Meet Fader. He is going to grow up and be a crossfader some day (tomarrow) - Tkinter -> Tix so we can use ScrolledListBox which has a command - Some improvements to Cue - Cues need to specify their final values - Cues are imported by subs. This should be fixed for style points. - Some other cleanups
author dmcc
date Sun, 07 Jul 2002 15:40:45 +0000
parents 5ff08b489693
children 065896b0913c
files light8/Config.py light8/ConfigDummy.py light8/Cue.py light8/Fader.py light8/Subs.py light8/Xfader.py light8/panels.py light8/rsn.py light8/stage.py light8/uihelpers.py light8/util.py
diffstat 11 files changed, 72 insertions(+), 186 deletions(-) [+]
line wrap: on
line diff
--- a/light8/Config.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/Config.py	Sun Jul 07 15:40:45 2002 +0000
@@ -3,6 +3,7 @@
 from __future__ import generators,division
 from Subs import *
 
+from Fader import fader
 
 patch = {
     
@@ -260,12 +261,8 @@
     'god' : fulls((6,)),
     ('strobe', 'grey'):strobe,
     
-#    'midstage' : dict([(r, 100) for r in range(11, 21)]),
-#    'backstage' : dict([(r, 100) for r in range(21, 31)]),
-#    'frontchase' : mr_effect,
     'chase' : chase,
     'chase2' : chase,
-#    'random' : randomdimmer,
 }
 
 subs["ba outrs"] = fulls("b11 b12 b13 b14 b15 b16 b31 b32 b33 b34 b35 b36".split())
--- a/light8/ConfigDummy.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/ConfigDummy.py	Sun Jul 07 15:40:45 2002 +0000
@@ -2,7 +2,15 @@
 from time import time
 from __future__ import generators,division
 from Subs import *
+from Cue import *
 
+f1 = Fade('red', 0, 2, 100)
+f2 = Fade('green', 1, 3, 50)
+f3 = Fade('blue', 0, 4, 0)
+f4 = Fade('clear', 0, 8, 75) 
+c1 = Cue("Color shift", 0, 10, f1, f2, f3, f4)
+
+cues = [c1]
 
 patch = {
     
@@ -241,7 +249,6 @@
             curtime = time()
         yield {dim : 100, 20 : params.get_param_value('magic')}
 
-
 subs = {
     'over pit sm' : levs(range(1, 13),(100,0,0,91,77,79,86,55,92,77,59,0)),
     'over pit lg' : fulls(range(1, 13)),
@@ -264,7 +271,7 @@
 #    'backstage' : dict([(r, 100) for r in range(21, 31)]),
 #    'frontchase' : mr_effect,
     'chase' : chase,
-    'chase2' : chase,
+    # 'chase2' : chase,
 #    'random' : randomdimmer,
 }
 
--- a/light8/Cue.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/Cue.py	Sun Jul 07 15:40:45 2002 +0000
@@ -7,10 +7,16 @@
     given time.  They contain Fades, which are actually children of Cue,
     meaning that Cues can contain Cues.  This is similar to the Light9 concept
     of Cues and Fades, but without all the Nodes."""
-    def __init__(self, name, starttime, endtime, *fades):
+    def __init__(self, name, starttime, endtime=None, dur=None, *fades):
         'Create a cue'
+        if not endtime:
+            endtime = starttime + dur
+        else:
+            dur = endtime - starttime
+
         self.name = name
         self.starttime = starttime
+        self.dur = dur
         self.endtime = endtime
         self.fades = fades
         self.cuestart = None
@@ -38,17 +44,22 @@
             for ch, lev in fade_d.items():
                 d[ch] = max(lev, d.get(ch, 0))
         return d
+    def get_end_levels(self):
+        'Returns the final levels'
+        d = {}
+        for fade in self.fades:
+            fade_d = fade.get_end_levels()
+            for ch, lev in fade_d.items():
+                d[ch] = max(lev, d.get(ch, 0))
+        return d
 
 class Fade(Cue):
     'See Cue.__doc__'
     def __init__(self, channel, starttime, endtime=None, endlevel=0, dur=None,
                  param=None):
-        'Only specify an end time or a duration'
-        if not endtime:
-            endtime = starttime + dur
-        else:
-            dur = endtime - starttime
-        Cue.__init__(self, "%s -> %f" % (channel, endlevel), starttime, endtime)
+        'Fades are simple Cues'
+        Cue.__init__(self, "%s -> %f" % (channel, endlevel), starttime, endtime,
+            dur)
         self.channel = channel
         self.endlevel = endlevel
         self.dur = dur
@@ -71,6 +82,8 @@
             percent = float(elapsed) / self.dur
             return {self.channel : self.init_level + 
                 percent * (self.endlevel - self.init_level)}
+    def get_end_levels(self):
+        return {self.channel : self.endlevel}
 
 if __name__ == '__main__':
     f1 = Fade('red', 0, 2, 100)
--- a/light8/Fader.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/Fader.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,13 +1,4 @@
 from Tix import *
-from time import time # time is on my side
-from util import subsetdict
-from FlyingFader import FlyingFader
-from uihelpers import get_selection
-
-# statuses are:
-# stopped - no cue is loaded or cue is stopped
-# running - cue is running, not complete
-# finished - cue is finished, next is loaded
 
 stdfont = ('Arial', 10)
 
@@ -17,178 +8,47 @@
         self.master = master
         self.cues = cues
         self.scalelevels = scalelevels
-        self.time_start = 0
         self.init_layout()
-        self.stop()
     def init_layout(self):
         Frame.__init__(self, self.master)
 
-        # info variables
         self.cuename = StringVar()
         self.cuelength = DoubleVar()
-        self.cuetarget = StringVar()
-
-        # info about a running cue
-        self.cuestatus = StringVar() # text description
-        self.cuestatus.set("stopped")
-        
-        self.cuepercent = DoubleVar() # percent complete
-        self.cuepercent.set(0)
-        self.cuepercent.trace('w', self.update_percent)
-        self.cuetimeelapse = StringVar() # time elapsed
-        self.cuetimeelapse.set('0s')
-        self.cuetimeleft = StringVar() # time left
-        self.cuetimeleft.set('0s')
+        self.cueend = StringVar()
 
         buttonframe = Frame(self)
-        topframe = Frame(self) # to contain cue list and infoframe
-        infoframe = Frame(topframe)
-        topframe.pack()
 
-        self.listbox = ScrolledListBox(topframe, 
-            command=self.update_selection)
-        self.listbox.listbox.configure({'exportselection' : 0, 
-            'selectmode' : EXTENDED})
+        self.listbox = ScrolledListBox(buttonframe)
+        self.listbox.listbox.configure({'exportselection' : 0})
         for c in self.cues:
             self.listbox.listbox.insert(END, c.name)
-        self.listbox.pack(side=LEFT)
-        self.listbox.listbox.bind("<<ListboxSelect>>", self.update_selection, 
-            add=1)
-        Button(buttonframe, text="Go", command=self.go, font=stdfont,
-            bg='green').pack(side=LEFT)
-        Button(buttonframe, text="Stop", command=self.stop, font=stdfont,
-            bg='red').pack(side=LEFT)
-        Button(buttonframe, text="Prev", command=self.prev, 
-            font=stdfont).pack(side=LEFT)
-        nextbutton = Button(buttonframe, text="Next", command=self.next, 
-            font=stdfont)
-        # Button(buttonframe, text="Load", command=self.mark_start, bg='grey80',
-            # font=stdfont).pack(side=LEFT)
+        self.listbox.pack(side=TOP)
+        Button(buttonframe, text="Go", command=self.go).pack(side=LEFT)
+        Button(buttonframe, text="Halt").pack(side=LEFT)
+        Button(buttonframe, text="Clear").pack(side=LEFT)
 
+        infoframe = Frame(self)
         Label(infoframe, textvariable=self.cuename, 
-            font=('Arial', 12), bg='lightBlue').grid(columnspan=4, sticky=NE+SW)
-
+            font=('Arial', 12), bg='lightBlue').grid(columnspan=2, sticky=NE+SW)
         Label(infoframe, text="Length", font=stdfont, 
             bg='lightPink').grid(row=1, sticky=NE+SW)
         Label(infoframe, textvariable=self.cuelength, 
-            font=stdfont).grid(row=1, column=1, columnspan=3, sticky=NE+SW)
-
+            font=stdfont).grid(row=1, column=1, sticky=NE+SW)
         Label(infoframe, text="Target", font=stdfont,
             bg='lightPink').grid(row=2, sticky=NE+SW)
-        Label(infoframe, textvariable=self.cuetarget, 
-            font=stdfont, wraplength=250).grid(row=2, column=1, columnspan=3, 
-                sticky=NE+SW)
-
-        Label(infoframe, text="Status", font=stdfont,
-            bg='lightPink').grid(row=3, sticky=NE+SW)
-        Label(infoframe, textvariable=self.cuestatus, 
-            font=stdfont).grid(row=3, column=1, columnspan=3, sticky=NE+SW)
-
-        Label(infoframe, text="Time Elapsed", font=stdfont,
-            bg='lightPink').grid(row=4, sticky=NE+SW)
-        Label(infoframe, textvariable=self.cuetimeelapse, 
-            font=stdfont).grid(row=4, column=1, sticky=NE+SW)
-
-        Label(infoframe, text="Time Remain", font=stdfont,
-            bg='lightPink').grid(row=4, column=2, sticky=NE+SW)
-        Label(infoframe, textvariable=self.cuetimeleft, 
-            font=stdfont).grid(row=4, column=3, sticky=NE+SW)
-
-        Label(infoframe, text="Percent Complete", font=stdfont,
-            bg='lightPink').grid(row=5, column=0, sticky=NE+SW)
-        self.percentlabel = Label(infoframe, 
-            font=stdfont)
-        self.percentlabel.grid(row=5, column=1, columnspan=3, sticky=NE+SW)
-
-        # s = Scale(infoframe, variable=self.cuepercent,
-        s = Scale(buttonframe, variable=self.cuepercent,
-                        showvalue=0, length=220,
-                        width=18, sliderlength=30,
-                        to=100,res=.1,from_=0,bd=1, font=stdfont,
-                        orient='horiz')
-        # s.grid(row=6, columnspan=4, sticky='ew')
-        nextbutton.pack(side=RIGHT)
-        s.pack(side=RIGHT, expand=1, fill=X)
-
+        Label(infoframe, textvariable=self.cueend, 
+            font=stdfont).grid(row=2, column=1, sticky=NE+SW)
         infoframe.pack(side=RIGHT, fill=BOTH, expand=1)
-        buttonframe.pack(side=BOTTOM, expand=1, fill=X)
+        buttonframe.pack(side=BOTTOM)
 
         self.listbox.listbox.select_set(0)
         self.update_selection()
-    def mark_start(self):
-        self.time_start = time()
-        startlevels = dict([(k, v.get()) for k, v in self.scalelevels.items()])
-        # print "going to mark with", startlevels
-        self.current.start(startlevels, self.time_start)
-    def update_percent(self, *args):
-        if self.cuestatus.get() != 'running':
-            self.cuestatus.set("running")
-            self.mark_start()
-
-        percent = self.cuepercent.get()
-        self.percentlabel.config(text='%.1f%%' % percent)
-        percent /= 100
-
-        elapsed = percent * self.current.dur
-        self.cuetimeelapse.set('%.1fs' % elapsed)
-        self.cuetimeleft.set('%.1fs' % (self.current.dur - elapsed))
-
-        newlevels = self.current.get_levels(self.time_start + elapsed)
-        # print "newlevels", newlevels
-        for ch, lev in newlevels.items():
-            try:
-                self.scalelevels[ch].set(lev)
-            except KeyError:
-                pass
-
-    def update_selection(self, *args):
-        self.cuestatus.set('stopped')
-        selection = get_selection(self.listbox.listbox)
+    def update_selection(self):
+        print self.listbox.listbox.curselection()
+        selection = int(self.listbox.listbox.curselection()[0]) # blech
         self.current = self.cues[selection]
         self.cuename.set(self.current.name)
         self.cuelength.set(self.current.dur)
-        target = ', '.join(['%s -> %.2f' % (n, lev) 
-            for n, lev in self.current.get_end_levels().items()])
-        self.cuetarget.set(target)
-        self.cuetimeelapse.set('0s')
-        self.cuetimeleft.set('%.1fs' % self.current.dur)
-        self.cuepercent.set(0)
+        self.cueend.set(str(self.current.get_end_levels()))
     def go(self):
-        self.update_selection()
-        self.cuestatus.set("running")
-        self.mark_start()
-        self.running_loop()
-    def stop(self):
-        self.cuestatus.set('stopped')
-    def prev(self):
-        self.stop()
-        selection = get_selection(self.listbox.listbox)
-        if selection != 0:
-            self.listbox.listbox.select_clear(selection)
-            self.listbox.listbox.select_set(selection - 1)
-            self.update_selection()
-            self.mark_start()
-    def next(self):
-        self.stop()
-        selection = get_selection(self.listbox.listbox)
-        if selection != self.listbox.listbox.size() - 1:
-            self.listbox.listbox.select_clear(selection)
-            self.listbox.listbox.select_set(selection + 1)
-            self.update_selection()
-            self.mark_start()
-    def running_loop(self):
-        if self.cuestatus.get() == 'stopped':
-            return
-        curtime = time()
-        elapsed = (curtime - self.time_start)
-
-        if elapsed > self.current.dur:
-            self.cuestatus.set('stopped')
-            self.cuepercent.set(100)
-
-            # advance cues if okay
-            self.next()
-            return
-
-        self.cuepercent.set(100 * elapsed / self.current.dur)
-        self.after(30, self.running_loop)
+        print 'Fade to', self.current.name
--- a/light8/Subs.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/Subs.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,6 +1,6 @@
 from Patch import *
 from time import time
-from Tkinter import *
+from Tix import *
 from types import TupleType
 
 stdfont = ('Arial', 8)
@@ -216,7 +216,7 @@
     
 
 def reload_data(dummy):
-    global subs
+    global subs, cues
     if dummy:
         import ConfigDummy as Config
     else:
@@ -234,5 +234,8 @@
         subs[name] = Sub(name, levels, color=color)
 
     # subs = dict([(name, Sub(levels)) for name, levels in Config.subs.items()])
+
+    cues = Config.cues
+
 def longestsubname():
     return max([len(x) for x in subs.keys()])
--- a/light8/Xfader.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/Xfader.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,4 +1,4 @@
-from Tkinter import *
+from Tix import *
 from __future__ import division
 
 class Xfader(Canvas):
--- a/light8/panels.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/panels.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,7 +1,7 @@
 """some of the panels"""
 from __future__ import nested_scopes
 
-from Tkinter import *
+from Tix import *
 from uihelpers import *
 import Patch
 from FlyingFader import FlyingFader
--- a/light8/rsn.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/rsn.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 from __future__ import nested_scopes
 
-from Tkinter import *
+from Tix import *
 from time import sleep
 from signal import signal, SIGINT
 import sys, cPickle
@@ -11,8 +11,10 @@
 from panels import *
 from Xfader import *
 from subediting import Subediting
+from Fader import Fader
 import stage
 
+
 if len(sys.argv) >= 2:
     DUMMY = 0
     print "This is the real thing, baby"
@@ -68,7 +70,8 @@
         effect_tl = toplevelat(462,4)
 
         self.subpanels = Subpanels(sub_tl, effect_tl, self.scalelevels, Subs, 
-            self.xfader, self.changelevel, self.subediting, Subs.longestsubname())
+            self.xfader, self.changelevel, self.subediting, 
+            Subs.longestsubname())
 
         leveldisplay_tl = toplevelat(873,400)
         leveldisplay_tl.bind('<Escape>', sys.exit)
@@ -97,6 +100,10 @@
         self.xfader.setupwidget(xf)
         controlpanel.pack()
 
+        cuefader_tl = toplevelat(98, 480)
+        cuefader = Fader(cuefader_tl, Subs.cues, self.scalelevels)
+        cuefader.pack()
+
     def refresh(self, *args):
         'rebuild interface, reload data'
         get_data()
--- a/light8/stage.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/stage.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,5 +1,4 @@
-from Tkinter import *
-
+from Tix import *
 
 def printevent(ev):
     for k in dir(ev):
@@ -7,10 +6,8 @@
             print k,getattr(ev,k)
     print ""
 
-
 textstyle={'font':'arial 7','fill':'white'}
 
-
 class Stage(Canvas):
     
     """a fancy widget that shows light locations (and optionally their
--- a/light8/uihelpers.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/uihelpers.py	Sun Jul 07 15:40:45 2002 +0000
@@ -1,6 +1,8 @@
 """all the tiny tk helper functions"""
+
 from __future__ import nested_scopes
 from Tkinter import *
+from Tix import *
 from types import StringType
 
 def make_frame(parent):
@@ -14,11 +16,11 @@
         w.bind(key, func)
 
 def toplevelat(x,y,w=None,h=None):
-    tl=Toplevel()
+    tl = Toplevel()
     if w and h:
-        tl.wm_geometry("%dx%d+%d+%d"%(w,h,x,y))
+        tl.wm_geometry("%dx%d+%d+%d" % (w,h,x,y))
     else:
-        tl.wm_geometry("+%d+%d"%(x,y))
+        tl.wm_geometry("+%d+%d" % (x,y))
     return tl
 
 def toggle_slider(s):
--- a/light8/util.py	Sun Jul 07 15:26:02 2002 +0000
+++ b/light8/util.py	Sun Jul 07 15:40:45 2002 +0000
@@ -15,8 +15,8 @@
 # class Setting that scales, maxes        
 
 def subsetdict(d, dkeys, default=0):
-    'Subset of dictionary d: only the keys in dkeys'
-    # print 'd', d, 'dkeys', dkeys
+    """Subset of dictionary d: only the keys in dkeys.  If you plan on omitting
+    keys, make sure you like the default."""
     newd = {} # dirty variables!
     for k in dkeys:
         newd[k] = d.get(k, default)