Mercurial > code > home > repos > light9
comparison flax/CueFaders.py @ 162:6c5753bad783
basic cue editing, darker colors, fade time selector is now a "TixControl"
basic cue editing, darker colors, fade time selector is now a "TixControl"
(spin box)
author | dmcc |
---|---|
date | Tue, 08 Jul 2003 07:10:20 +0000 |
parents | 0803fb42109d |
children | e0c227168519 |
comparison
equal
deleted
inserted
replaced
161:0803fb42109d | 162:6c5753bad783 |
---|---|
12 } | 12 } |
13 | 13 |
14 class LabelledScale(Tk.Frame): | 14 class LabelledScale(Tk.Frame): |
15 """Scale with two labels: a name and current value""" | 15 """Scale with two labels: a name and current value""" |
16 def __init__(self, master, label, **opts): | 16 def __init__(self, master, label, **opts): |
17 Tk.Frame.__init__(self, master, bd=2, relief='raised') | 17 Tk.Frame.__init__(self, master, bd=2, relief='raised', bg='black') |
18 opts.setdefault('variable', Tk.DoubleVar()) | 18 opts.setdefault('variable', Tk.DoubleVar()) |
19 opts.setdefault('showvalue', 0) | 19 opts.setdefault('showvalue', 0) |
20 | 20 |
21 self.normaltrough = opts.get('troughcolor', 'black') | 21 self.normaltrough = opts.get('troughcolor', 'black') |
22 self.flashtrough = opts.get('flashtroughcolor', 'red') | 22 self.flashtrough = opts.get('flashtroughcolor', 'red') |
23 del opts['flashtroughcolor'] | 23 del opts['flashtroughcolor'] |
24 | 24 |
25 self.scale_var = opts['variable'] | 25 self.scale_var = opts['variable'] |
26 self.scale = Tk.Scale(self, **opts) | 26 self.scale = Tk.Scale(self, **opts) |
27 self.scale.pack(side='top', expand=1, fill='both') | 27 self.scale.pack(side='top', expand=1, fill='both') |
28 self.name = Tk.Label(self, text=label) | 28 self.name = Tk.Label(self, text=label, bg='black', fg='white') |
29 self.name.pack(side='bottom') | 29 self.name.pack(side='bottom') |
30 self.scale_value = Tk.Label(self, width=6) | 30 self.scale_value = Tk.Label(self, width=6, bg='black', fg='white') |
31 self.scale_value.pack(side='bottom') | 31 self.scale_value.pack(side='bottom') |
32 self.scale_var.trace('w', self.update_value_label) | 32 self.scale_var.trace('w', self.update_value_label) |
33 self.update_value_label() | 33 self.update_value_label() |
34 self.disabled = (self.scale['state'] == 'disabled') | 34 self.disabled = (self.scale['state'] == 'disabled') |
35 def set_label(self, label): | 35 def set_label(self, label): |
52 self.disabled = 0 | 52 self.disabled = 0 |
53 | 53 |
54 class TimedGoButton(Tk.Frame): | 54 class TimedGoButton(Tk.Frame): |
55 """Go button, fade time entry, and time fader""" | 55 """Go button, fade time entry, and time fader""" |
56 def __init__(self, master, name, scale_to_fade, **kw): | 56 def __init__(self, master, name, scale_to_fade, **kw): |
57 Tk.Frame.__init__(self, master) | 57 Tk.Frame.__init__(self, master, bg='black') |
58 self.name = name | 58 self.name = name |
59 self.scale_to_fade = scale_to_fade | 59 self.scale_to_fade = scale_to_fade |
60 self.button = Tk.Button(self, text=name, command=self.start_fade, **kw) | 60 self.button = Tk.Button(self, text=name, command=self.start_fade, **kw) |
61 self.button.pack(fill='both', expand=1, side='left') | 61 self.button.pack(fill='both', expand=1, side='left') |
62 self.timer_var = Tk.StringVar() | 62 |
63 self.timer_entry = Tk.Entry(self, textvariable=self.timer_var, width=5) | 63 self.timer_var = Tk.DoubleVar() |
64 self.timer_entry = Tk.Control(self, step=0.5, min=0, integer=0) | |
65 self.timer_entry.entry.configure(textvariable=self.timer_var, width=5, | |
66 bg='black', fg='white') | |
64 self.timer_entry.pack(fill='y', side='left') | 67 self.timer_entry.pack(fill='y', side='left') |
65 self.timer_var.set("2") | |
66 self.disabled = (self.button['state'] == 'disabled') | 68 self.disabled = (self.button['state'] == 'disabled') |
67 def start_fade(self, end_level=1): | 69 def start_fade(self, end_level=1): |
68 try: | 70 try: |
69 fade_time = float(self.timer_var.get()) | 71 fade_time = float(self.timer_var.get()) |
70 except ValueError: | 72 except ValueError: |
95 self.disabled = 1 | 97 self.disabled = 1 |
96 def enable(self): | 98 def enable(self): |
97 if self.disabled: | 99 if self.disabled: |
98 self.button['state'] = 'normal' | 100 self.button['state'] = 'normal' |
99 self.disabled = 0 | 101 self.disabled = 0 |
102 def set_time(self, time): | |
103 self.timer_var.set(time) | |
100 | 104 |
101 class CueFader(Tk.Frame): | 105 class CueFader(Tk.Frame): |
102 def __init__(self, master, cuelist): | 106 def __init__(self, master, cuelist): |
103 Tk.Frame.__init__(self, master) | 107 Tk.Frame.__init__(self, master, bg='black') |
104 self.cuelist = cuelist | 108 self.cuelist = cuelist |
105 self.auto_shift = Tk.IntVar() | 109 self.auto_shift = Tk.IntVar() |
106 self.auto_shift.set(1) | 110 self.auto_shift.set(1) |
107 | 111 |
108 # this is a mechanism to stop Tk from autoshifting too much. | 112 # this is a mechanism to stop Tk from autoshifting too much. |
113 | 117 |
114 self.scales = {} | 118 self.scales = {} |
115 self.shift_buttons = {} | 119 self.shift_buttons = {} |
116 self.go_buttons = {} | 120 self.go_buttons = {} |
117 | 121 |
118 topframe = Tk.Frame(self) | 122 topframe = Tk.Frame(self, bg='black') |
119 | 123 |
120 self.set_prev_button = Tk.Button(topframe, text='Set Prev', | 124 self.set_prev_button = Tk.Button(topframe, text='Set Prev', |
121 command=lambda: cuelist.set_selection_as_prev(), | 125 command=lambda: cuelist.set_selection_as_prev(), |
122 fg='white', bg='blue') | 126 fg='white', bg='blue') |
123 self.set_prev_button.pack(side='left') | 127 self.set_prev_button.pack(side='left') |
124 | 128 |
125 self.auto_shift_checkbutton = Tk.Checkbutton(topframe, | 129 self.auto_shift_checkbutton = Tk.Checkbutton(topframe, |
126 variable=self.auto_shift, text='Autoshift', | 130 variable=self.auto_shift, text='Autoshift', |
127 command=self.toggle_autoshift) | 131 command=self.toggle_autoshift, bg='black', fg='white') |
128 self.auto_shift_checkbutton.pack(side='left') | 132 self.auto_shift_checkbutton.pack(side='left') |
129 | 133 |
130 self.set_next_button = Tk.Button(topframe, text='Set Next', | 134 self.set_next_button = Tk.Button(topframe, text='Set Next', |
131 command=lambda: cuelist.set_selection_as_next(), | 135 command=lambda: cuelist.set_selection_as_next(), |
132 fg='white', bg='red') | 136 fg='white', bg='red') |
133 self.set_next_button.pack(side='left') | 137 self.set_next_button.pack(side='left') |
134 | 138 |
135 topframe.pack(side='top') | 139 topframe.pack(side='top') |
136 | 140 |
137 faderframe = Tk.Frame(self) | 141 faderframe = Tk.Frame(self, bg='black') |
138 self.direction_info = (('Prev', 1, 0, 'left', 'blue'), | 142 self.direction_info = (('Prev', 1, 0, 'left', 'blue'), |
139 ('Next', 0, 1, 'right', 'red')) | 143 ('Next', 0, 1, 'right', 'red')) |
140 for name, start, end, side, color in self.direction_info: | 144 for name, start, end, side, color in self.direction_info: |
141 frame = Tk.Frame(self) | 145 frame = Tk.Frame(self, bg='black') |
142 scale = LabelledScale(frame, name, from_=start, to_=end, | 146 scale = LabelledScale(frame, name, from_=start, to_=end, |
143 res=0.0001, orient='horiz', flashtroughcolor=color) | 147 res=0.0001, orient='horiz', flashtroughcolor=color) |
144 scale.pack(fill='x', expand=0) | 148 scale.pack(fill='x', expand=0) |
145 go = TimedGoButton(frame, 'Go %s' % name, scale, bg=color, | 149 go = TimedGoButton(frame, 'Go %s' % name, scale, bg=color, |
146 fg='white') | 150 fg='white') |
288 else: | 292 else: |
289 return empty_cue | 293 return empty_cue |
290 def __del__(self): | 294 def __del__(self): |
291 self.save() | 295 self.save() |
292 def save(self): | 296 def save(self): |
297 print "Saving cues to", self.filename | |
293 self.treedict.save(self.filename) | 298 self.treedict.save(self.filename) |
294 def reload(self): | 299 def reload(self): |
295 # TODO: we probably will need to make sure that indices still make | 300 # TODO: we probably will need to make sure that indices still make |
296 # sense, etc. | 301 # sense, etc. |
297 self.treedict.load(self.filename) | 302 self.treedict.load(self.filename) |
298 | 303 |
299 class TkCueList(CueList, Tk.Frame): | 304 class TkCueList(CueList, Tk.Frame): |
300 def __init__(self, master, filename): | 305 def __init__(self, master, filename): |
301 CueList.__init__(self, filename) | 306 CueList.__init__(self, filename) |
302 Tk.Frame.__init__(self, master) | 307 Tk.Frame.__init__(self, master, bg='black') |
303 | 308 |
309 self.edit_tl = Tk.Toplevel() | |
310 self.editor = CueEditron(self.edit_tl, changed_callback=self.redraw_cue) | |
311 self.editor.pack(fill='both', expand=1) | |
312 | |
313 def edit_cue(index): | |
314 index = int(index) | |
315 self.editor.set_cue_to_edit(self.cues[index]) | |
316 | |
304 self.columns = ('name', 'time', 'page', 'desc') | 317 self.columns = ('name', 'time', 'page', 'desc') |
305 | |
306 self.scrolled_hlist = Tk.ScrolledHList(self, | 318 self.scrolled_hlist = Tk.ScrolledHList(self, |
307 options='hlist.columns %d hlist.header 1' % len(self.columns)) | 319 options='hlist.columns %d hlist.header 1' % len(self.columns)) |
308 self.hlist = self.scrolled_hlist.hlist | 320 self.hlist = self.scrolled_hlist.hlist |
309 self.hlist.configure(fg='white', bg='black', | 321 self.hlist.configure(fg='white', bg='black', |
310 command=self.select_callback) | 322 command=self.select_callback, browsecmd=edit_cue) |
311 self.scrolled_hlist.pack(fill='both', expand=1) | 323 self.scrolled_hlist.pack(fill='both', expand=1) |
312 | 324 |
313 boldfont = self.tk.call('tix', 'option', 'get', | 325 boldfont = self.tk.call('tix', 'option', 'get', |
314 'bold_font') | 326 'bold_font') |
315 header_style = Tk.DisplayStyle('text', refwindow=self, | 327 header_style = Tk.DisplayStyle('text', refwindow=self, |
321 | 333 |
322 self.cue_label_windows = {} | 334 self.cue_label_windows = {} |
323 for count, cue in enumerate(self.cues): | 335 for count, cue in enumerate(self.cues): |
324 self.display_cue(count, cue) | 336 self.display_cue(count, cue) |
325 self.update_cue_indicators() | 337 self.update_cue_indicators() |
326 def display_cue(self, cue_count, cue): | 338 |
327 # cue_count is the path in the hlist -- this probably isn't ideal | 339 def redraw_cue(self, cue): |
340 if 0: | |
341 # TODO: this is really inefficient | |
342 self.hlist.delete_all() | |
343 for count, cue in enumerate(self.cues): | |
344 self.display_cue(count, cue) | |
345 self.update_cue_indicators() | |
346 else: | |
347 path = self.cues.index(cue) | |
348 for col, header in enumerate(self.columns): | |
349 try: | |
350 text = getattr(cue, header) | |
351 except AttributeError: | |
352 text = '' | |
353 | |
354 if col == 0: | |
355 self.cue_label_windows[path]['text'] = text | |
356 else: | |
357 self.hlist.item_configure(path, col, text=text) | |
358 def display_cue(self, path, cue): | |
328 for col, header in enumerate(self.columns): | 359 for col, header in enumerate(self.columns): |
329 try: | 360 try: |
330 text = getattr(cue, header) | 361 text = getattr(cue, header) |
331 except AttributeError: | 362 except AttributeError: |
332 text = '' | 363 text = '' |
333 | 364 |
334 if col == 0: | 365 if col == 0: |
335 lab = Tk.Label(self.hlist, text=text, fg='white', bg='black') | 366 lab = Tk.Label(self.hlist, text=text, fg='white', bg='black') |
336 def select_and_highlight(event): | 367 def select_and_highlight(event): |
337 self.select_callback(cue_count) | 368 self.select_callback(path) |
338 self.hlist.selection_clear() | 369 self.hlist.selection_clear() |
339 self.hlist.selection_set(cue_count) | 370 self.hlist.selection_set(path) |
340 | 371 |
341 lab.bind("<Double-1>", select_and_highlight) | 372 lab.bind("<Double-1>", select_and_highlight) |
342 self.hlist.add(cue_count, itemtype='window', window=lab) | 373 self.hlist.add(path, itemtype='window', window=lab) |
343 self.cue_label_windows[cue_count] = lab | 374 self.cue_label_windows[path] = lab |
344 else: | 375 else: |
345 self.hlist.item_create(cue_count, col, text=text) | 376 self.hlist.item_create(path, col, text=text) |
346 def reset_cue_indicators(self, cue_indices=None): | 377 def reset_cue_indicators(self, cue_indices=None): |
347 """If cue_indices is None, we'll reset all of them.""" | 378 """If cue_indices is None, we'll reset all of them.""" |
348 cue_indices = cue_indices or self.cue_label_windows.keys() | 379 cue_indices = cue_indices or self.cue_label_windows.keys() |
349 for key in cue_indices: | 380 for key in cue_indices: |
350 window = self.cue_label_windows[key] | 381 window = self.cue_label_windows[key] |
385 def set_selection_as_next(self): | 416 def set_selection_as_next(self): |
386 sel = self.hlist.info_selection() | 417 sel = self.hlist.info_selection() |
387 if sel: | 418 if sel: |
388 self.set_next(int(sel[0])) | 419 self.set_next(int(sel[0])) |
389 | 420 |
421 class CueEditron(Tk.Frame): | |
422 def __init__(self, master, changed_callback=None, cue=None): | |
423 Tk.Frame.__init__(self, master, bg='black') | |
424 self.master = master | |
425 self.cue = cue | |
426 self.changed_callback = changed_callback | |
427 self.enable_callbacks = 1 | |
428 | |
429 self.setup_editing_forms() | |
430 self.set_cue_to_edit(cue) | |
431 def set_cue_to_edit(self, cue): | |
432 if cue != self.cue: | |
433 self.cue = cue | |
434 self.fill_in_cue_info() | |
435 self.set_title() | |
436 def set_title(self): | |
437 try: | |
438 self.master.title("Editing '%s'" % self.cue.name) | |
439 except AttributeError: | |
440 pass | |
441 def setup_editing_forms(self): | |
442 self.variables = {} | |
443 for row, field in enumerate(('name', 'time', 'page', 'desc')): | |
444 lab = Tk.Label(self, text=field, fg='white', bg='black') | |
445 lab.grid(row=row, column=0, sticky='nsew') | |
446 | |
447 entryvar = Tk.StringVar() | |
448 entry = Tk.Entry(self, fg='white', bg='black', | |
449 textvariable=entryvar) | |
450 entry.grid(row=row, column=1, sticky='nsew') | |
451 | |
452 self.variables[field] = entryvar | |
453 | |
454 def field_changed(x, y, z, field=field, entryvar=entryvar): | |
455 if self.cue: | |
456 setattr(self.cue, field, entryvar.get()) | |
457 if self.enable_callbacks and self.changed_callback: | |
458 self.changed_callback(self.cue) | |
459 if field == 'name': | |
460 self.set_title() | |
461 | |
462 entryvar.trace('w', field_changed) | |
463 self.columnconfigure(1, weight=1) | |
464 def fill_in_cue_info(self): | |
465 self.enable_callbacks = 0 | |
466 for row, field in enumerate(('name', 'time', 'page', 'desc')): | |
467 text = '' | |
468 if self.cue: | |
469 try: | |
470 text = getattr(self.cue, field) | |
471 except AttributeError: | |
472 pass | |
473 self.variables[field].set(text) | |
474 self.enable_callbacks = 1 | |
475 | |
390 if __name__ == "__main__": | 476 if __name__ == "__main__": |
391 root = Tk.Tk() | 477 root = Tk.Tk() |
478 root.title("ShowMaster 9000") | |
392 cl = TkCueList(root, 'cues/cuelist1') | 479 cl = TkCueList(root, 'cues/cuelist1') |
393 cl.pack(fill='both', expand=1) | 480 cl.pack(fill='both', expand=1) |
394 | 481 |
395 # to populate cue list | |
396 if 0: | |
397 for x in range(20): | |
398 cl.add_cue(Cue('cue %d' % x, time=x, some_attribute=3)) | |
399 | |
400 fader = CueFader(root, cl) | 482 fader = CueFader(root, cl) |
401 fader.pack(fill='both', expand=1) | 483 fader.pack(fill='both', expand=1) |
402 Tk.mainloop() | 484 try: |
485 Tk.mainloop() | |
486 except KeyboardInterrupt: | |
487 root.destroy() |