Mercurial > code > home > repos > light9
annotate flax/CueFaders.py @ 154:e3a92ccea4be
add cuisine path
author | dmcc |
---|---|
date | Mon, 07 Jul 2003 06:32:25 +0000 |
parents | 990a9474d0e7 |
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() |