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()