Mercurial > code > home > repos > light9
comparison flax/CueFaders.py @ 178:e9c06be9b26b
more updates, some bugfixes (hopefully!)
author | dmcc |
---|---|
date | Thu, 10 Jul 2003 07:20:20 +0000 |
parents | c8d24bd2a99e |
children | ce362534d133 |
comparison
equal
deleted
inserted
replaced
177:c47779b165b0 | 178:e9c06be9b26b |
---|---|
10 'prev' : ('blue', 'white'), | 10 'prev' : ('blue', 'white'), |
11 'cur' : ('yellow', 'black'), | 11 'cur' : ('yellow', 'black'), |
12 'next' : ('red', 'white'), | 12 'next' : ('red', 'white'), |
13 } | 13 } |
14 | 14 |
15 # TODO pause fades, set new time to be remaining about of time in the fade so fade | 15 # TODO |
16 # can continue properly | 16 # .... pause fades, set new time to be remaining about of time in the fade so |
17 # make fades work properly: the set_next / prev bug | 17 # fade can continue properly |
18 # find cue by page ("not necessawy!") | 18 # FIX? make fades work properly: the set_next / prev bug |
19 # CueFader controls KeyboardController? unlikely | 19 # WONT find cue by page ("not necessawy!") |
20 # WONT CueFader controls KeyboardController? unlikely | |
20 | 21 |
21 class LabelledScale(Tk.Frame): | 22 class LabelledScale(Tk.Frame): |
22 """Scale with two labels: a name and current value""" | 23 """Scale with two labels: a name and current value""" |
23 def __init__(self, master, label, **opts): | 24 def __init__(self, master, label, **opts): |
24 Tk.Frame.__init__(self, master, bd=2, relief='raised', bg='black') | 25 Tk.Frame.__init__(self, master, bd=2, relief='raised', bg='black') |
89 widget.bind("<5>", self.wheelscroll) | 90 widget.bind("<5>", self.wheelscroll) |
90 self.timer_entry.entry.configure(width=5, bg='black', fg='white') | 91 self.timer_entry.entry.configure(width=5, bg='black', fg='white') |
91 self.timer_entry.pack(fill='y', side='left') | 92 self.timer_entry.pack(fill='y', side='left') |
92 self.timer_var.set(2) | 93 self.timer_var.set(2) |
93 self.disabled = (self.button['state'] == 'disabled') | 94 self.disabled = (self.button['state'] == 'disabled') |
95 self.start_time = 0 | |
94 self.fading = 0 | 96 self.fading = 0 |
97 self.last_after_key = 0 | |
95 def wheelscroll(self, event): | 98 def wheelscroll(self, event): |
96 """Mouse wheel increments or decrements timer.""" | 99 """Mouse wheel increments or decrements timer.""" |
97 if event.num == 4: # scroll up | 100 if event.num == 4: # scroll up |
98 self.timer_entry.increment() | 101 self.timer_entry.increment() |
99 else: # scroll down | 102 else: # scroll down |
100 self.timer_entry.decrement() | 103 self.timer_entry.decrement() |
101 def start_fade(self, end_level=1): | 104 def start_fade(self, end_level=1): |
102 try: | 105 self.last_start_time = self.start_time |
103 fade_time = float(self.timer_var.get()) | |
104 except ValueError: | |
105 # since we use a control now, i don't think we need to worry about | |
106 # validation any more. | |
107 print ">>> Can't fade -- bad time", self.timer_var.get() | |
108 return | |
109 | |
110 self.start_time = time.time() | 106 self.start_time = time.time() |
111 self.start_level = self.scale_to_fade.scale_var.get() | 107 self.start_level = self.scale_to_fade.scale_var.get() |
112 self.end_level = end_level | 108 self.end_level = end_level |
113 self.fade_length = fade_time | 109 |
114 self.fading = 1 | 110 if self.fading == 1: # if we're already fading |
115 self.do_fade() | 111 print "already fading!" |
112 # fade_time = old_fade_length - | |
113 self.fading = 'paused' | |
114 self.fade_length = time.time() - self.last_start_time | |
115 print "fade_length", self.fade_length | |
116 self.end_fade() | |
117 else: | |
118 print "not already fading or continuing a fade" | |
119 try: | |
120 fade_time = float(self.timer_var.get()) | |
121 except ValueError: | |
122 # since we use a TixControl now, i don't think we need to worry | |
123 # about validation any more. | |
124 print ">>> Can't fade -- bad time", self.timer_var.get() | |
125 return | |
126 | |
127 # TODO fix | |
128 if self.fading != 'paused': | |
129 self.fade_length = fade_time | |
130 print "fade_length", self.fade_length | |
131 self.button['text'] = 'Pause' | |
132 self.fading = 1 | |
133 self.do_fade() | |
116 def do_fade(self): | 134 def do_fade(self): |
117 diff = time.time() - self.start_time | 135 diff = time.time() - self.start_time |
118 if diff < self.fade_length: | 136 if diff < self.fade_length: |
119 percent = diff / self.fade_length | 137 percent = diff / self.fade_length |
120 newlevel = self.start_level + \ | 138 newlevel = self.start_level + \ |
121 (percent * (self.end_level - self.start_level)) | 139 (percent * (self.end_level - self.start_level)) |
122 self.scale_to_fade.scale_var.set(newlevel) | 140 self.scale_to_fade.scale_var.set(newlevel) |
123 | 141 |
124 if newlevel != self.end_level: | 142 if newlevel != self.end_level: |
125 self.after(10, self.do_fade) | 143 self.last_after_key = self.after(10, self.do_fade) |
126 else: | 144 else: |
127 self.fading = 0 | 145 self.end_fade() |
128 else: | 146 else: |
129 self.scale_to_fade.scale_var.set(self.end_level) | 147 self.scale_to_fade.scale_var.set(self.end_level) |
130 self.fading = 0 | 148 self.end_fade() |
149 def end_fade(self): | |
150 self.button['text'] = self.name | |
151 self.fading = 0 | |
152 self.after_cancel(self.last_after_key) | |
131 def disable(self): | 153 def disable(self): |
132 if not self.disabled: | 154 if not self.disabled: |
133 self.button['state'] = 'disabled' | 155 self.button['state'] = 'disabled' |
134 self.disabled = 1 | 156 self.disabled = 1 |
135 def enable(self): | 157 def enable(self): |
214 res=0.0001, orient='horiz', flashtroughcolor=color, | 236 res=0.0001, orient='horiz', flashtroughcolor=color, |
215 labelformatter=lambda val, name=name: self.get_scale_desc(val, | 237 labelformatter=lambda val, name=name: self.get_scale_desc(val, |
216 name)) | 238 name)) |
217 scale.pack(fill='x', expand=0) | 239 scale.pack(fill='x', expand=0) |
218 go = TimedGoButton(frame, 'Go %s' % name, scale, bg=color, | 240 go = TimedGoButton(frame, 'Go %s' % name, scale, bg=color, |
219 fg='white') | 241 fg='white', width=10) |
220 go.pack(fill='both', expand=1) | 242 go.pack(fill='both', expand=1) |
221 frame.pack(side=side, fill='both', expand=1) | 243 frame.pack(side=side, fill='both', expand=1) |
222 | 244 |
223 shift = Tk.Button(frame, text="Shift %s" % name, state='disabled', | 245 shift = Tk.Button(frame, text="Shift %s" % name, state='disabled', |
224 command=lambda name=name: self.shift(name), fg=color, | 246 command=lambda name=name: self.shift(name), fg=color, |
247 self.cues_as_subs = {} | 269 self.cues_as_subs = {} |
248 self.update_cue_cache() | 270 self.update_cue_cache() |
249 def reload_cue_times(self): | 271 def reload_cue_times(self): |
250 prev, cur, next = self.cuelist.get_current_cues() | 272 prev, cur, next = self.cuelist.get_current_cues() |
251 self.go_buttons['Next'].set_time(next.time) | 273 self.go_buttons['Next'].set_time(next.time) |
252 def update_cue_cache(self): | 274 def update_cue_cache(self, compute_dmx_levels=1): |
253 """Rebuilds subs from the current cues. As this is expensive, we don't | 275 """Rebuilds subs from the current cues. As this is expensive, we don't |
254 do it unless necessary (i.e. whenever we shift or a cue is edited)""" | 276 do it unless necessary (i.e. whenever we shift or a cue is edited)""" |
277 # print "update_cue_cache" | |
255 # load the subs to fade between | 278 # load the subs to fade between |
256 for cue, name in zip(self.cuelist.get_current_cues(), | 279 for cue, name in zip(self.cuelist.get_current_cues(), |
257 ('Prev', 'Cur', 'Next')): | 280 ('Prev', 'Cur', 'Next')): |
258 self.cues_as_subs[name] = cue.get_levels_as_sub() | 281 self.cues_as_subs[name] = cue.get_levels_as_sub() |
259 self.compute_dmx_levels() | 282 if compute_dmx_levels: |
283 self.compute_dmx_levels() | |
260 def compute_dmx_levels(self): | 284 def compute_dmx_levels(self): |
261 """Compute the DMX levels to send. This should get called whenever the | 285 """Compute the DMX levels to send. This should get called whenever the |
262 DMX levels could change: either during a crossfade or when a cue is | 286 DMX levels could change: either during a crossfade or when a cue is |
263 edited. Since this is called when we know that a change might occur, | 287 edited. Since this is called when we know that a change might occur, |
264 we will send the new levels too.""" | 288 we will send the new levels too.""" |
269 | 293 |
270 other_sub = self.cues_as_subs[self.current_dir] | 294 other_sub = self.cues_as_subs[self.current_dir] |
271 current_levels_as_sub = cur_sub.crossfade(other_sub, scale_val) | 295 current_levels_as_sub = cur_sub.crossfade(other_sub, scale_val) |
272 self.current_dmx_levels = current_levels_as_sub.get_dmx_list() | 296 self.current_dmx_levels = current_levels_as_sub.get_dmx_list() |
273 self.send_dmx_levels() | 297 self.send_dmx_levels() |
298 | |
299 # print "compute_dmx_levels: fade at", scale_val | |
300 # print "between", cur_sub.name, | |
301 # print "and", other_sub.name | |
302 # print | |
274 def send_dmx_levels(self, *args): | 303 def send_dmx_levels(self, *args): |
275 # print "send_dmx_levels", self.current_dmx_levels | 304 # print "send_dmx_levels", self.current_dmx_levels |
276 if self.mute.get(): | 305 if self.mute.get(): |
277 dmxclient.outputlevels([0] * 68) | 306 dmxclient.outputlevels([0] * 68) |
278 else: | 307 else: |
301 button.pack_forget() | 330 button.pack_forget() |
302 def shift(self, name): | 331 def shift(self, name): |
303 # to prevent overshifting | 332 # to prevent overshifting |
304 if self.no_shifts_until_release: | 333 if self.no_shifts_until_release: |
305 return | 334 return |
306 | 335 # print "shift", name |
336 | |
337 self.cuelist.shift((-1, 1)[name == 'Next']) | |
338 self.update_cue_cache(compute_dmx_levels=0) | |
307 for scale_name, scale in self.scales.items(): | 339 for scale_name, scale in self.scales.items(): |
340 # print "shift: setting scale to 0", scale_name | |
308 scale.scale.set(0) | 341 scale.scale.set(0) |
309 self.cuelist.shift((-1, 1)[name == 'Next']) | 342 self.update_cue_cache(compute_dmx_levels=1) |
310 | 343 |
311 self.update_cue_cache() | |
312 if self.auto_load_times.get(): | 344 if self.auto_load_times.get(): |
313 self.reload_cue_times() | 345 self.reload_cue_times() |
314 def autoshift(self, name, scale): | 346 def autoshift(self, name, scale): |
315 scale_val = scale.scale_var.get() | 347 scale_val = scale.scale_var.get() |
316 | 348 |
572 def set_next(self, index): | 604 def set_next(self, index): |
573 prev, cur, next = self.get_current_cue_indices() | 605 prev, cur, next = self.get_current_cue_indices() |
574 self.reset_cue_indicators((next,)) | 606 self.reset_cue_indicators((next,)) |
575 CueList.set_next(self, index) | 607 CueList.set_next(self, index) |
576 self.update_cue_indicators() | 608 self.update_cue_indicators() |
609 | |
610 if self.fader: # XXX this is untested | |
611 self.fader.update_cue_cache() | |
577 def set_prev(self, index): | 612 def set_prev(self, index): |
578 prev, cur, next = self.get_current_cue_indices() | 613 prev, cur, next = self.get_current_cue_indices() |
579 self.reset_cue_indicators((prev,)) | 614 self.reset_cue_indicators((prev,)) |
580 CueList.set_prev(self, index) | 615 CueList.set_prev(self, index) |
581 self.update_cue_indicators() | 616 self.update_cue_indicators() |
617 | |
618 if self.fader: # XXX this is untested | |
619 self.fader.update_cue_cache() | |
582 def set_selection_as_prev(self): | 620 def set_selection_as_prev(self): |
583 sel = self.hlist.info_selection() | 621 sel = self.hlist.info_selection() |
584 if sel: | 622 if sel: |
585 self.set_prev(int(sel[0])) | 623 self.set_prev(int(sel[0])) |
586 def set_selection_as_next(self): | 624 def set_selection_as_next(self): |
616 lab.grid(row=row, column=0, sticky='nsew') | 654 lab.grid(row=row, column=0, sticky='nsew') |
617 | 655 |
618 entryvar = Tk.StringVar() | 656 entryvar = Tk.StringVar() |
619 entry = Tk.Entry(self, fg='white', bg='black', | 657 entry = Tk.Entry(self, fg='white', bg='black', |
620 textvariable=entryvar, insertbackground='white', | 658 textvariable=entryvar, insertbackground='white', |
621 highlightbackground='red') # TODO this red/black is backwards | 659 highlightcolor='red') # TODO this red/black is backwards |
622 entry.grid(row=row, column=1, sticky='nsew') | 660 entry.grid(row=row, column=1, sticky='nsew') |
623 | 661 |
624 self.variables[field] = entryvar | 662 self.variables[field] = entryvar |
625 | 663 |
626 def field_changed(x, y, z, field=field, entryvar=entryvar): | 664 def field_changed(x, y, z, field=field, entryvar=entryvar): |
647 self.enable_callbacks = 1 | 685 self.enable_callbacks = 1 |
648 | 686 |
649 if __name__ == "__main__": | 687 if __name__ == "__main__": |
650 root = Tk.Tk() | 688 root = Tk.Tk() |
651 root.title("ShowMaster 9000") | 689 root.title("ShowMaster 9000") |
652 root.geometry("500x555") | 690 root.geometry("600x670") |
653 cl = TkCueList(root, 'cues/dolly') | 691 cl = TkCueList(root, 'cues/dolly') |
654 cl.pack(fill='both', expand=1) | 692 cl.pack(fill='both', expand=1) |
655 | 693 |
656 fader = CueFader(root, cl) | 694 fader = CueFader(root, cl) |
657 fader.pack(fill='both', expand=1) | 695 fader.pack(fill='both', expand=1) |