Mercurial > code > home > repos > light9
annotate flax/CueFaders.py @ 151:990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
early cue stuff. the CueList will supply the CueFader with the cues to
work with, and will do crossfading sooner or later. the format of cues
is still very open. cuelist1 is a bogus cuelist for testing.
author | dmcc |
---|---|
date | Sun, 06 Jul 2003 16:33:06 +0000 |
parents | 45b12307c695 |
children | 4c3060ceddcc |
rev | line source |
---|---|
0 | 1 from __future__ import division, nested_scopes |
2 import Tix as Tk | |
3 import time | |
4 from TreeDict import TreeDict, allow_class_to_be_pickled | |
5 | |
6 class LabelledScale(Tk.Frame): | |
7 """Scale with two labels: a name and current value""" | |
8 def __init__(self, master, label, **opts): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
9 Tk.Frame.__init__(self, master, bd=2, relief='raised') |
0 | 10 opts.setdefault('variable', Tk.DoubleVar()) |
11 opts.setdefault('showvalue', 0) | |
12 self.scale_var = opts['variable'] | |
13 self.scale = Tk.Scale(self, **opts) | |
14 self.scale.pack(side='top', expand=1, fill='both') | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
15 self.name = Tk.Label(self, text=label) |
0 | 16 self.name.pack(side='bottom') |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
17 self.scale_value = Tk.Label(self, width=6) |
0 | 18 self.scale_value.pack(side='bottom') |
19 self.scale_var.trace('w', self.update_value_label) | |
20 self.update_value_label() | |
21 def set_label(self, label): | |
22 self.name['text'] = label | |
23 def update_value_label(self, *args): | |
24 val = self.scale_var.get() * 100 | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
25 self.scale_value['text'] = "%0.2f" % val |
0 | 26 |
27 class TimedGoButton(Tk.Frame): | |
28 """Go button, fade time entry, and time fader""" | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
29 def __init__(self, master, name, scale_to_fade): |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
30 Tk.Frame.__init__(self, master) |
0 | 31 self.name = name |
32 self.scale_to_fade = scale_to_fade | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
33 self.button = Tk.Button(self, text=name, command=self.start_fade) |
0 | 34 self.button.pack(fill='both', expand=1, side='left') |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
35 self.timer_var = Tk.StringVar() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
36 self.timer_entry = Tk.Entry(self, textvariable=self.timer_var, width=5) |
0 | 37 self.timer_entry.pack(fill='y', side='left') |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
38 self.timer_var.set("2") |
0 | 39 def start_fade(self, end_level=1): |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
40 try: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
41 fade_time = float(self.timer_var.get()) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
42 except ValueError: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
43 # TODO figure out how to handle this |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
44 print "can't fade -- bad time" |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
45 return |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
46 |
0 | 47 self.start_time = time.time() |
48 self.start_level = self.scale_to_fade.scale_var.get() | |
49 self.end_level = end_level | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
50 self.fade_length = fade_time |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
51 self.do_fade() |
0 | 52 def do_fade(self): |
53 diff = time.time() - self.start_time | |
54 if diff < self.fade_length: | |
55 percent = diff / self.fade_length | |
56 newlevel = self.start_level + \ | |
57 (percent * (self.end_level - self.start_level)) | |
58 self.scale_to_fade.scale_var.set(newlevel) | |
59 | |
60 if newlevel != self.end_level: | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
61 self.after(10, self.do_fade) |
0 | 62 else: |
63 self.scale_to_fade.scale_var.set(self.end_level) | |
64 | |
65 class CueFader(Tk.Frame): | |
66 def __init__(self, master, cuelist): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
67 Tk.Frame.__init__(self, master) |
0 | 68 self.cuelist = cuelist |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
69 self.auto_shift = 0 |
0 | 70 |
71 self.scales = {} | |
72 self.shift_buttons = {} | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
73 |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
74 topframe = Tk.Frame(self) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
75 self.current_cues = Tk.Label(topframe) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
76 self.current_cues.pack() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
77 self.update_cue_display() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
78 topframe.pack() |
0 | 79 |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
80 for name, start, end, side in (('Prev', 1, 0, 'left'), |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
81 ('Next', 0, 1, 'right')): |
0 | 82 |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
83 shift = Tk.Button(self, text="Shift %s" % name, state='disabled', |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
84 command=lambda name=name: self.shift(name)) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
85 shift.pack(side=side, fill='both', expand=1) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
86 |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
87 frame = Tk.Frame(self) |
0 | 88 scale = LabelledScale(frame, name, from_=start, to_=end, |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
89 res=0.01, orient='horiz') |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
90 scale.pack(fill='both', expand=1) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
91 go = TimedGoButton(frame, 'Go %s' % name, scale) |
0 | 92 go.pack(fill='both', expand=1) |
93 frame.pack(side=side, fill='both', expand=1) | |
94 | |
95 self.scales[name] = scale | |
96 self.shift_buttons[name] = shift | |
97 | |
98 scale.scale_var.trace('w', \ | |
99 lambda x, y, z, name=name, scale=scale: self.xfade(name, scale)) | |
100 def shift(self, name): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
101 for scale in self.scales.values(): |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
102 scale.scale_var.set(0) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
103 if name == 'Next': scale.update() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
104 print "shift", name |
0 | 105 self.cuelist.shift((-1, 1)[name == 'Next']) |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
106 self.update_cue_display() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
107 def update_cue_display(self): |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
108 current_cues = [cue.name for cue in self.cuelist.get_current_cues()] |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
109 self.current_cues['text'] = ', '.join(current_cues) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
110 def xfade(self, name, scale): |
0 | 111 scale_val = scale.scale_var.get() |
112 | |
113 if scale_val == 1: | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
114 if self.auto_shift: |
0 | 115 self.shift(name) |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
116 else: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
117 self.shift_buttons[name]['state'] = 'normal' |
0 | 118 else: |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
119 # disable any dangerous shifting |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
120 self.shift_buttons[name]['state'] = 'disabled' |
0 | 121 |
122 if scale_val != 0: | |
123 # disable illegal three part crossfades | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
124 # TODO: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
125 # if name == 'Next': |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
126 # disable go_prev button and slider, lock slider at 0 |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
127 pass |
0 | 128 else: |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
129 # undo above changes |
0 | 130 |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
131 # Actually, TimedGoButton and LabelledScale can have enable/disable |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
132 # methods which will only do the Tk calls if necessary |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
133 pass |
0 | 134 |
135 class Cue: | |
136 """A Cue has a name, a time, and any number of other attributes.""" | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
137 def __init__(self, name, time=3, **attrs): |
0 | 138 self.name = name |
139 self.time = time | |
140 self.__dict__.update(attrs) | |
141 def __repr__(self): | |
142 return "<Cue %s, length %s>" % (self.name, self.time) | |
143 | |
144 empty_cue = Cue('empty') | |
145 | |
146 allow_class_to_be_pickled(Cue) | |
147 | |
148 class CueList: | |
149 """Persistent list of Cues""" | |
150 def __init__(self, filename): | |
151 self.filename = filename | |
152 self.treedict = TreeDict() | |
153 try: | |
154 self.treedict.load(filename) | |
155 except IOError: | |
156 self.treedict.cues = [] | |
157 self.cues = self.treedict.cues | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
158 self.current_cue_index = 0 |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
159 self.next_pointer = None |
0 | 160 self.prev_pointer = None |
161 | |
162 import atexit | |
163 atexit.register(self.save) | |
164 def add_cue(self, cue, index=None): | |
165 """Adds a Cue object to the list. If no index is specified, | |
166 the cue will be added to the end.""" | |
167 index = index or len(self.cues) | |
168 self.cues.insert(index, cue) | |
169 def shift(self, diff): | |
170 """Shift through cue history""" | |
171 old_index = self.current_cue_index | |
172 self.current_cue_index = None | |
173 if diff < 0: # if going backwards | |
174 if self.prev_pointer: # use a prev pointer if we have one | |
175 self.current_cue_index = self.prev_pointer | |
176 self.next_pointer = old_index | |
177 self.prev_pointer = None | |
178 else: | |
179 if self.next_pointer: # use a next pointer if we have one | |
180 self.current_cue_index = self.next_pointer | |
181 self.next_pointer = None | |
182 self.prev_pointer = old_index | |
183 if not self.current_cue_index: | |
184 self.current_cue_index = old_index + diff | |
185 def set_next(self, index): | |
186 self.next_pointer = index | |
187 def set_prev(self, index): | |
188 self.prev_pointer = index | |
189 def bound_index(self, index): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
190 if not self.cues: |
0 | 191 return None |
192 else: | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
193 return max(0, min(index, len(self.cues))) |
0 | 194 def get_current_cue_indices(self): |
195 cur = self.current_cue_index | |
196 return [self.bound_index(index) for index in | |
197 (self.prev_pointer or cur - 1, | |
198 cur, | |
199 self.next_pointer or cur + 1)] | |
200 def get_current_cues(self): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
201 # print "get_current_cue_indices", self.get_current_cue_indices() |
0 | 202 return [self.get_cue_by_index(index) |
203 for index in self.get_current_cue_indices()] | |
204 def get_cue_by_index(self, index): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
205 # print "get_cue_by_index", index |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
206 if index: |
0 | 207 return self.cues[self.bound_index(index)] |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
208 else: |
0 | 209 return empty_cue |
210 def __del__(self): | |
211 self.save() | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
212 def save(self): |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
213 self.treedict.save(self.filename) |
0 | 214 |
215 if __name__ == "__main__": | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
216 if 0: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
217 z = CueList('cues/cuelist1') |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
218 z.add_cue(Cue('cue %s' % time.asctime(), time=2, a=7, b=8)) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
219 print 'cues', z.cues |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
220 else: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
221 cl = CueList('cues/cuelist1') |
0 | 222 |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
223 # to populate cue list |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
224 if 0: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
225 for x in range(20): |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
226 cl.add_cue(Cue('cue %d' % x, time=x, some_attribute=3)) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
227 |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
228 root = Tk.Tk() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
229 fader = CueFader(root, cl) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
230 fader.pack(fill='both', expand=1) |
0 | 231 Tk.mainloop() |