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)