annotate flax/CueFaders.py @ 271:97c08a1c4351

gyrocontroller: remap buttons, fix keep mode Also, solo mode is now default, colors are brighter, numeric names for subs are converted to subs with only that channel up, send zeroes when exiting
author David McClosky <dmcc@bigasterisk.com>
date Fri, 17 Jun 2005 04:23:07 +0000
parents 74a34c677588
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
1 from __future__ import division, nested_scopes
45b12307c695 Initial revision
drewp
parents:
diff changeset
2 import Tix as Tk
45b12307c695 Initial revision
drewp
parents:
diff changeset
3 import time
45b12307c695 Initial revision
drewp
parents:
diff changeset
4 from TreeDict import TreeDict, allow_class_to_be_pickled
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
5 from TLUtility import enumerate
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
6 import Submaster, dmxclient
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
7
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
8 cue_state_indicator_colors = {
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
9 # bg fg
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
10 'prev' : ('blue', 'white'),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
11 'cur' : ('yellow', 'black'),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
12 'next' : ('red', 'white'),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
13 }
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
14
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
15 # TODO
181
ccd635df77a9 - commit latest cue and sub changes
dmcc
parents: 179
diff changeset
16 # FIXE pause fades, set new time to be remaining about of time in the fade so
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
17 # fade can continue properly
181
ccd635df77a9 - commit latest cue and sub changes
dmcc
parents: 179
diff changeset
18 # FIXE make fades work properly: the set_next / prev bug
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
19 # WONT find cue by page ("not necessawy!")
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
20 # WONT CueFader controls KeyboardController? unlikely
185
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
21 # FIXE AutoSave loop
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
22
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
23 class LabelledScale(Tk.Frame):
45b12307c695 Initial revision
drewp
parents:
diff changeset
24 """Scale with two labels: a name and current value"""
45b12307c695 Initial revision
drewp
parents:
diff changeset
25 def __init__(self, master, label, **opts):
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
26 Tk.Frame.__init__(self, master, bd=2, relief='raised', bg='black')
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
27 self.labelformatter = opts.get('labelformatter')
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
28 try:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
29 del opts['labelformatter']
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
30 except KeyError:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
31 pass
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
32
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
33 opts.setdefault('variable', Tk.DoubleVar())
45b12307c695 Initial revision
drewp
parents:
diff changeset
34 opts.setdefault('showvalue', 0)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
35
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
36 self.normaltrough = opts.get('troughcolor', 'black')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
37 self.flashtrough = opts.get('flashtroughcolor', 'red')
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
38 try:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
39 del opts['flashtroughcolor']
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
40 except KeyError:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
41 pass
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
42
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
43 self.scale_var = opts['variable']
45b12307c695 Initial revision
drewp
parents:
diff changeset
44 self.scale = Tk.Scale(self, **opts)
45b12307c695 Initial revision
drewp
parents:
diff changeset
45 self.scale.pack(side='top', expand=1, fill='both')
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
46 self.name = Tk.Label(self, text=label, bg='black', fg='white')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
47 self.name.pack(side='bottom')
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
48 self.scale_value = Tk.Label(self, bg='black', fg='white')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
49 self.scale_value.pack(side='bottom')
45b12307c695 Initial revision
drewp
parents:
diff changeset
50 self.scale_var.trace('w', self.update_value_label)
45b12307c695 Initial revision
drewp
parents:
diff changeset
51 self.update_value_label()
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
52 self.disabled = (self.scale['state'] == 'disabled')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
53 def set_label(self, label):
45b12307c695 Initial revision
drewp
parents:
diff changeset
54 self.name['text'] = label
45b12307c695 Initial revision
drewp
parents:
diff changeset
55 def update_value_label(self, *args):
45b12307c695 Initial revision
drewp
parents:
diff changeset
56 val = self.scale_var.get() * 100
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
57 if self.labelformatter:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
58 format = self.labelformatter(val)
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
59 else:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
60 format = "%0.2f" % val
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
61 self.scale_value['text'] = format
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
62 if val != 0:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
63 self.scale['troughcolor'] = self.flashtrough
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
64 else:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
65 self.scale['troughcolor'] = self.normaltrough
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
66 def disable(self):
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
67 if not self.disabled:
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
68 self.scale['state'] = 'disabled'
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
69 self.scale_var.set(0)
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
70 self.disabled = 1
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
71 def enable(self):
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
72 if self.disabled:
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
73 self.scale['state'] = 'normal'
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
74 self.disabled = 0
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
75
45b12307c695 Initial revision
drewp
parents:
diff changeset
76 class TimedGoButton(Tk.Frame):
45b12307c695 Initial revision
drewp
parents:
diff changeset
77 """Go button, fade time entry, and time fader"""
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
78 def __init__(self, master, name, scale_to_fade, **kw):
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
79 Tk.Frame.__init__(self, master, bg='black')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
80 self.name = name
45b12307c695 Initial revision
drewp
parents:
diff changeset
81 self.scale_to_fade = scale_to_fade
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
82 self.button = Tk.Button(self, text=name, command=self.start_fade, **kw)
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
83 self.button.pack(fill='both', expand=1, side='left')
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
84
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
85 self.timer_var = Tk.DoubleVar()
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
86 self.timer_entry = Tk.Control(self, step=0.5, min=0, integer=0,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
87 variable=self.timer_var, selectmode='immediate')
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
88 for widget in (self.timer_entry, self.timer_entry.entry,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
89 self.timer_entry.incr, self.timer_entry.decr, self.button, self):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
90 widget.bind("<4>", self.wheelscroll)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
91 widget.bind("<5>", self.wheelscroll)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
92 self.timer_entry.entry.configure(width=5, bg='black', fg='white')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
93 self.timer_entry.pack(fill='y', side='left')
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
94 self.timer_var.set(2)
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
95 self.disabled = (self.button['state'] == 'disabled')
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
96 self.start_time = 0
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
97 self.fading = 0
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
98 self.last_after_key = 0
179
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
99 def manual_override(self, *args):
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
100 self.end_fade()
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
101 def wheelscroll(self, event):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
102 """Mouse wheel increments or decrements timer."""
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
103 if event.num == 4: # scroll up
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
104 self.timer_entry.increment()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
105 else: # scroll down
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
106 self.timer_entry.decrement()
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
107 def start_fade(self, end_level=1):
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
108 self.last_start_time = self.start_time
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
109 self.start_time = time.time()
45b12307c695 Initial revision
drewp
parents:
diff changeset
110 self.start_level = self.scale_to_fade.scale_var.get()
45b12307c695 Initial revision
drewp
parents:
diff changeset
111 self.end_level = end_level
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
112
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
113 if self.fading == 1: # if we're already fading
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
114 self.fading = 'paused'
179
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
115 # new fade should be as long as however much was left
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
116 self.fade_length = self.fade_length - \
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
117 (time.time() - self.last_start_time)
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
118 self.button['text'] = 'Unpause'
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
119 self.after_cancel(self.last_after_key)
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
120 else:
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
121 try:
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
122 fade_time = float(self.timer_var.get())
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
123 except ValueError:
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
124 # since we use a TixControl now, i don't think we need to worry
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
125 # about validation any more.
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
126 print ">>> Can't fade -- bad time", self.timer_var.get()
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
127 return
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
128
179
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
129 # if we're not already fading, we get our time from the entry
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
130 if self.fading != 'paused':
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
131 self.fade_length = fade_time
179
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
132
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
133 self.button['text'] = 'Pause'
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
134 self.fading = 1
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
135 self.do_fade()
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
136 def do_fade(self):
45b12307c695 Initial revision
drewp
parents:
diff changeset
137 diff = time.time() - self.start_time
45b12307c695 Initial revision
drewp
parents:
diff changeset
138 if diff < self.fade_length:
45b12307c695 Initial revision
drewp
parents:
diff changeset
139 percent = diff / self.fade_length
45b12307c695 Initial revision
drewp
parents:
diff changeset
140 newlevel = self.start_level + \
45b12307c695 Initial revision
drewp
parents:
diff changeset
141 (percent * (self.end_level - self.start_level))
45b12307c695 Initial revision
drewp
parents:
diff changeset
142 self.scale_to_fade.scale_var.set(newlevel)
45b12307c695 Initial revision
drewp
parents:
diff changeset
143
45b12307c695 Initial revision
drewp
parents:
diff changeset
144 if newlevel != self.end_level:
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
145 self.last_after_key = self.after(10, self.do_fade)
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
146 else:
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
147 self.end_fade()
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
148 else:
45b12307c695 Initial revision
drewp
parents:
diff changeset
149 self.scale_to_fade.scale_var.set(self.end_level)
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
150 self.end_fade()
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
151 def end_fade(self):
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
152 self.button['text'] = self.name
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
153 self.fading = 0
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
154 self.after_cancel(self.last_after_key)
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
155 def disable(self):
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
156 if not self.disabled:
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
157 self.button['state'] = 'disabled'
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
158 self.disabled = 1
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
159 def enable(self):
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
160 if self.disabled:
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
161 self.button['state'] = 'normal'
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
162 self.disabled = 0
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
163 def set_time(self, time):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
164 self.timer_var.set(time)
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
165 def get_time(self):
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
166 return self.timer_var.get()
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
167 def is_fading(self):
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
168 return self.fading
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
169
45b12307c695 Initial revision
drewp
parents:
diff changeset
170 class CueFader(Tk.Frame):
45b12307c695 Initial revision
drewp
parents:
diff changeset
171 def __init__(self, master, cuelist):
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
172 Tk.Frame.__init__(self, master, bg='black')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
173 self.cuelist = cuelist
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
174 self.cuelist.set_fader(self)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
175
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
176 self.last_levels_sent = 0
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
177 self.current_dmx_levels = [0] * 68
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
178 self.after(0, self.send_dmx_levels_loop) # start DMX sending loop
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
179
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
180 # this is a mechanism to stop Tk from autoshifting too much.
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
181 # if this variable is true, the mouse button is down. we don't want
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
182 # to shift until they release it. when it is released, we will
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
183 # set it to false and then call autoshift.
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
184 self.no_shifts_until_release = 0
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
185
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
186 self.scales = {}
45b12307c695 Initial revision
drewp
parents:
diff changeset
187 self.shift_buttons = {}
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
188 self.go_buttons = {}
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
189
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
190 topframe = Tk.Frame(self, bg='black')
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
191
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
192 self.set_prev_button = Tk.Button(topframe, text='Set Prev',
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
193 command=lambda: cuelist.set_selection_as_prev(),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
194 fg='white', bg='blue')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
195 self.set_prev_button.pack(side='left')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
196
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
197 self.auto_shift = Tk.IntVar()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
198 self.auto_shift.set(1)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
199
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
200 self.auto_shift_checkbutton = Tk.Checkbutton(topframe,
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
201 variable=self.auto_shift, text='Autoshift',
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
202 command=self.toggle_autoshift, bg='black', fg='white',
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
203 highlightbackground='black')
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
204 self.auto_shift_checkbutton.pack(fill='both', side='left')
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
205
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
206 self.auto_load_times = Tk.IntVar()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
207 self.auto_load_times.set(1)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
208
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
209 self.auto_load_times_checkbutton = Tk.Checkbutton(topframe,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
210 variable=self.auto_load_times, text='Autoload Times',
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
211 bg='black', fg='white',
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
212 highlightbackground='black')
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
213 self.auto_load_times_checkbutton.pack(fill='both', side='left')
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
214
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
215 self.mute = Tk.IntVar()
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
216 self.mute.set(0)
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
217
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
218 self.mutebutton = Tk.Checkbutton(topframe,
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
219 variable=self.mute, text='Mute',
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
220 bg='black', fg='white',
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
221 highlightbackground='black',
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
222 command=self.send_dmx_levels)
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
223 self.mutebutton.pack(fill='both', side='left')
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
224
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
225 self.set_next_button = Tk.Button(topframe, text='Set Next',
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
226 command=lambda: cuelist.set_selection_as_next(),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
227 fg='white', bg='red')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
228 self.set_next_button.pack(side='left')
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
229
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
230 topframe.pack(side='top')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
231
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
232 faderframe = Tk.Frame(self, bg='black')
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
233 self.direction_info = (('Prev', 1, 0, 'left', 'blue'),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
234 ('Next', 0, 1, 'right', 'red'))
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
235 for name, start, end, side, color in self.direction_info:
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
236 frame = Tk.Frame(self, bg='black')
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
237 scale = LabelledScale(frame, name, from_=start, to_=end,
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
238 res=0.0001, orient='horiz', flashtroughcolor=color,
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
239 labelformatter=lambda val, name=name: self.get_scale_desc(val,
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
240 name))
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
241 scale.pack(fill='x', expand=0)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
242 go = TimedGoButton(frame, 'Go %s' % name, scale, bg=color,
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
243 fg='white', width=10)
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
244 go.pack(fill='both', expand=1)
45b12307c695 Initial revision
drewp
parents:
diff changeset
245 frame.pack(side=side, fill='both', expand=1)
45b12307c695 Initial revision
drewp
parents:
diff changeset
246
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
247 shift = Tk.Button(frame, text="Shift %s" % name, state='disabled',
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
248 command=lambda name=name: self.shift(name), fg=color,
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
249 bg='black')
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
250
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
251 self.scales[name] = scale
45b12307c695 Initial revision
drewp
parents:
diff changeset
252 self.shift_buttons[name] = shift
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
253 self.go_buttons[name] = go
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
254
45b12307c695 Initial revision
drewp
parents:
diff changeset
255 scale.scale_var.trace('w', \
45b12307c695 Initial revision
drewp
parents:
diff changeset
256 lambda x, y, z, name=name, scale=scale: self.xfade(name, scale))
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
257 go.timer_var.trace('w',
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
258 lambda x, y, z, scale=scale: scale.update_value_label())
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
259
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
260 def button_press(event, name=name, scale=scale):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
261 self.no_shifts_until_release = 1 # prevent shifts until release
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
262 def button_release(event, name=name, scale=scale):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
263 self.no_shifts_until_release = 0
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
264 self.autoshift(name, scale)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
265
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
266 scale.scale.bind("<ButtonPress>", button_press)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
267 scale.scale.bind("<ButtonRelease>", button_release)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
268 faderframe.pack(side='bottom', fill='both', expand=1)
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
269
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
270 self.current_dir = 'Next'
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
271 self.cues_as_subs = {}
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
272 self.update_cue_cache()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
273 def reload_cue_times(self):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
274 prev, cur, next = self.cuelist.get_current_cues()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
275 self.go_buttons['Next'].set_time(next.time)
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
276 def update_cue_cache(self, compute_dmx_levels=1):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
277 """Rebuilds subs from the current cues. As this is expensive, we don't
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
278 do it unless necessary (i.e. whenever we shift or a cue is edited)"""
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
279 # print "update_cue_cache"
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
280 # load the subs to fade between
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
281 for cue, name in zip(self.cuelist.get_current_cues(),
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
282 ('Prev', 'Cur', 'Next')):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
283 self.cues_as_subs[name] = cue.get_levels_as_sub()
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
284 if compute_dmx_levels:
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
285 self.compute_dmx_levels()
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
286 def compute_dmx_levels(self):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
287 """Compute the DMX levels to send. This should get called whenever the
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
288 DMX levels could change: either during a crossfade or when a cue is
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
289 edited. Since this is called when we know that a change might occur,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
290 we will send the new levels too."""
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
291 cur_sub = self.cues_as_subs.get('Cur')
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
292 if cur_sub:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
293 scale = self.scales[self.current_dir]
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
294 scale_val = scale.scale_var.get()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
295
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
296 other_sub = self.cues_as_subs[self.current_dir]
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
297 current_levels_as_sub = cur_sub.crossfade(other_sub, scale_val)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
298 self.current_dmx_levels = current_levels_as_sub.get_dmx_list()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
299 self.send_dmx_levels()
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
300
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
301 # print "compute_dmx_levels: fade at", scale_val
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
302 # print "between", cur_sub.name,
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
303 # print "and", other_sub.name
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
304 # print
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
305 def send_dmx_levels(self, *args):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
306 # print "send_dmx_levels", self.current_dmx_levels
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
307 if self.mute.get():
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
308 dmxclient.outputlevels([0] * 68)
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
309 else:
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
310 dmxclient.outputlevels(self.current_dmx_levels)
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
311 self.last_levels_sent = time.time()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
312 def send_dmx_levels_loop(self):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
313 diff = time.time() - self.last_levels_sent
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
314 if diff >= 2: # too long since last send
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
315 self.send_dmx_levels()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
316 self.after(200, self.send_dmx_levels_loop)
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
317 else:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
318 self.after(int((2 - diff) * 100), self.send_dmx_levels_loop)
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
319 def get_scale_desc(self, val, name):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
320 """Returns a description to the TimedGoButton"""
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
321 go_button = self.go_buttons.get(name)
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
322 if go_button:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
323 time = go_button.get_time()
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
324 return "%0.2f%%, %0.1fs left" % (val, time - ((val / 100.0) * time))
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
325 else:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
326 return "%0.2f%%" % val
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
327 def toggle_autoshift(self):
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
328 for name, button in self.shift_buttons.items():
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
329 if not self.auto_shift.get():
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
330 button.pack(side='bottom', fill='both', expand=1)
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
331 else:
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
332 button.pack_forget()
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
333 def shift(self, name):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
334 # to prevent overshifting
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
335 if self.no_shifts_until_release:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
336 return
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
337 # print "shift", name
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
338
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
339 self.cuelist.shift((-1, 1)[name == 'Next'])
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
340 self.update_cue_cache(compute_dmx_levels=0)
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
341 for scale_name, scale in self.scales.items():
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
342 # print "shift: setting scale to 0", scale_name
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
343 scale.scale.set(0)
179
ce362534d133 - maybe more fixes to CueFaders
dmcc
parents: 178
diff changeset
344 self.go_buttons[scale_name].manual_override()
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
345 self.update_cue_cache(compute_dmx_levels=1)
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
346
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
347 if self.auto_load_times.get():
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
348 self.reload_cue_times()
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
349 def autoshift(self, name, scale):
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
350 scale_val = scale.scale_var.get()
45b12307c695 Initial revision
drewp
parents:
diff changeset
351
45b12307c695 Initial revision
drewp
parents:
diff changeset
352 if scale_val == 1:
155
4c3060ceddcc autoshifting is controllable now
dmcc
parents: 151
diff changeset
353 if self.auto_shift.get():
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
354 self.shift(name)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
355 def xfade(self, name, scale):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
356 if self.auto_shift.get():
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
357 self.autoshift(name, scale)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
358 scale_val = scale.scale_var.get()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
359 else:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
360 scale_val = scale.scale_var.get()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
361 if scale_val == 1:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
362 self.shift_buttons[name]['state'] = 'normal'
151
990a9474d0e7 early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents: 0
diff changeset
363 else:
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
364 # disable any dangerous shifting
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
365 self.shift_buttons[name]['state'] = 'disabled'
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
366
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
367 d = self.opposite_direction(name)
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
368 if scale_val != 0:
45b12307c695 Initial revision
drewp
parents:
diff changeset
369 # disable illegal three part crossfades
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
370 self.scales[d].disable()
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
371 self.go_buttons[d].disable()
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
372 else:
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
373 # undo above work
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
374 self.scales[d].enable()
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
375 self.go_buttons[d].enable()
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
376
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
377 self.current_dir = name
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
378 self.compute_dmx_levels()
158
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
379 def opposite_direction(self, d):
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
380 if d == 'Next':
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
381 return 'Prev'
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
382 else:
5c7ac46e33d3 more disabling of stuff that make no sense at certain times and some
dmcc
parents: 157
diff changeset
383 return 'Next'
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
384
45b12307c695 Initial revision
drewp
parents:
diff changeset
385 class Cue:
45b12307c695 Initial revision
drewp
parents:
diff changeset
386 """A Cue has a name, a time, and any number of other attributes."""
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
387 def __init__(self, name, time=3, sub_levels='', **attrs):
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
388 self.name = name
45b12307c695 Initial revision
drewp
parents:
diff changeset
389 self.time = time
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
390 self.sub_levels = sub_levels
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
391 self.__dict__.update(attrs)
45b12307c695 Initial revision
drewp
parents:
diff changeset
392 def __repr__(self):
45b12307c695 Initial revision
drewp
parents:
diff changeset
393 return "<Cue %s, length %s>" % (self.name, self.time)
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
394 def get_levels_as_sub(self):
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
395 """Get this Cue as a combined Submaster, normalized. This method
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
396 should not be called constantly, since it is somewhat expensive. It
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
397 will reload the submasters from disk, combine all subs together, and
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
398 then compute the normalized form."""
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
399 subdict = {}
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
400 for line in self.sub_levels.split(','):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
401 try:
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
402 line = line.strip()
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
403 if not line:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
404 continue
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
405 sub, scale = line.split(':')
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
406 sub = sub.strip()
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
407 scale = float(scale)
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
408 subdict[sub] = scale
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
409 except ValueError:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
410 print "Parsing error for '%s' in %s" % (self.sub_levels, self)
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
411
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
412 s = Submaster.Submasters()
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
413 newsub = Submaster.sub_maxes(*[s[sub] * scale
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
414 for sub, scale in subdict.items()])
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
415 return newsub.get_normalized_copy()
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
416
45b12307c695 Initial revision
drewp
parents:
diff changeset
417 empty_cue = Cue('empty')
45b12307c695 Initial revision
drewp
parents:
diff changeset
418
45b12307c695 Initial revision
drewp
parents:
diff changeset
419 allow_class_to_be_pickled(Cue)
45b12307c695 Initial revision
drewp
parents:
diff changeset
420
45b12307c695 Initial revision
drewp
parents:
diff changeset
421 class CueList:
45b12307c695 Initial revision
drewp
parents:
diff changeset
422 """Persistent list of Cues"""
45b12307c695 Initial revision
drewp
parents:
diff changeset
423 def __init__(self, filename):
45b12307c695 Initial revision
drewp
parents:
diff changeset
424 self.filename = filename
45b12307c695 Initial revision
drewp
parents:
diff changeset
425 self.treedict = TreeDict()
45b12307c695 Initial revision
drewp
parents:
diff changeset
426 try:
45b12307c695 Initial revision
drewp
parents:
diff changeset
427 self.treedict.load(filename)
45b12307c695 Initial revision
drewp
parents:
diff changeset
428 except IOError:
45b12307c695 Initial revision
drewp
parents:
diff changeset
429 self.treedict.cues = []
45b12307c695 Initial revision
drewp
parents:
diff changeset
430 self.cues = self.treedict.cues
167
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
431 self.current_cue_index = -1
79bc84310e80 changes from tonight's rehearsal:
dmcc
parents: 163
diff changeset
432 self.next_pointer = 0
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
433 self.prev_pointer = None
45b12307c695 Initial revision
drewp
parents:
diff changeset
434
45b12307c695 Initial revision
drewp
parents:
diff changeset
435 import atexit
45b12307c695 Initial revision
drewp
parents:
diff changeset
436 atexit.register(self.save)
45b12307c695 Initial revision
drewp
parents:
diff changeset
437 def add_cue(self, cue, index=None):
45b12307c695 Initial revision
drewp
parents:
diff changeset
438 """Adds a Cue object to the list. If no index is specified,
45b12307c695 Initial revision
drewp
parents:
diff changeset
439 the cue will be added to the end."""
45b12307c695 Initial revision
drewp
parents:
diff changeset
440 index = index or len(self.cues)
45b12307c695 Initial revision
drewp
parents:
diff changeset
441 self.cues.insert(index, cue)
45b12307c695 Initial revision
drewp
parents:
diff changeset
442 def shift(self, diff):
45b12307c695 Initial revision
drewp
parents:
diff changeset
443 """Shift through cue history"""
45b12307c695 Initial revision
drewp
parents:
diff changeset
444 old_index = self.current_cue_index
45b12307c695 Initial revision
drewp
parents:
diff changeset
445 self.current_cue_index = None
45b12307c695 Initial revision
drewp
parents:
diff changeset
446 if diff < 0: # if going backwards
45b12307c695 Initial revision
drewp
parents:
diff changeset
447 if self.prev_pointer: # use a prev pointer if we have one
45b12307c695 Initial revision
drewp
parents:
diff changeset
448 self.current_cue_index = self.prev_pointer
45b12307c695 Initial revision
drewp
parents:
diff changeset
449 self.next_pointer = old_index
45b12307c695 Initial revision
drewp
parents:
diff changeset
450 self.prev_pointer = None
45b12307c695 Initial revision
drewp
parents:
diff changeset
451 else:
45b12307c695 Initial revision
drewp
parents:
diff changeset
452 if self.next_pointer: # use a next pointer if we have one
45b12307c695 Initial revision
drewp
parents:
diff changeset
453 self.current_cue_index = self.next_pointer
45b12307c695 Initial revision
drewp
parents:
diff changeset
454 self.next_pointer = None
45b12307c695 Initial revision
drewp
parents:
diff changeset
455 self.prev_pointer = old_index
45b12307c695 Initial revision
drewp
parents:
diff changeset
456 if not self.current_cue_index:
45b12307c695 Initial revision
drewp
parents:
diff changeset
457 self.current_cue_index = old_index + diff
45b12307c695 Initial revision
drewp
parents:
diff changeset
458 def set_next(self, index):
45b12307c695 Initial revision
drewp
parents:
diff changeset
459 self.next_pointer = index
45b12307c695 Initial revision
drewp
parents:
diff changeset
460 def set_prev(self, index):
45b12307c695 Initial revision
drewp
parents:
diff changeset
461 self.prev_pointer = index
45b12307c695 Initial revision
drewp
parents:
diff changeset
462 def bound_index(self, index):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
463 if not self.cues or index < 0:
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
464 return None
45b12307c695 Initial revision
drewp
parents:
diff changeset
465 else:
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
466 return min(index, len(self.cues) - 1)
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
467 def get_current_cue_indices(self):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
468 """Returns a list of the indices of three cues: the previous cue,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
469 the current cue, and the next cue."""
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
470 cur = self.current_cue_index
45b12307c695 Initial revision
drewp
parents:
diff changeset
471 return [self.bound_index(index) for index in
45b12307c695 Initial revision
drewp
parents:
diff changeset
472 (self.prev_pointer or cur - 1,
45b12307c695 Initial revision
drewp
parents:
diff changeset
473 cur,
45b12307c695 Initial revision
drewp
parents:
diff changeset
474 self.next_pointer or cur + 1)]
45b12307c695 Initial revision
drewp
parents:
diff changeset
475 def get_current_cues(self):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
476 """Returns a list of three cues: the previous cue, the current cue,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
477 and the next cue."""
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
478 return [self.get_cue_by_index(index)
45b12307c695 Initial revision
drewp
parents:
diff changeset
479 for index in self.get_current_cue_indices()]
45b12307c695 Initial revision
drewp
parents:
diff changeset
480 def get_cue_by_index(self, index):
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
481 try:
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
482 return self.cues[self.bound_index(index)]
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
483 except TypeError:
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
484 return empty_cue
45b12307c695 Initial revision
drewp
parents:
diff changeset
485 def __del__(self):
45b12307c695 Initial revision
drewp
parents:
diff changeset
486 self.save()
185
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
487 def save(self, backup=0):
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
488 if backup:
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
489
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
490 backupfilename = "%s-backup" % self.filename
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
491 print time.asctime(), "Saving backup version of cues to", \
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
492 backupfilename
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
493 self.treedict.save(backupfilename)
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
494 else:
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
495 print time.asctime(), "Saving cues to", self.filename
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
496 self.treedict.save(self.filename)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
497 def reload(self):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
498 # TODO: we probably will need to make sure that indices still make
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
499 # sense, etc.
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
500 self.treedict.load(self.filename)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
501
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
502 class TkCueList(CueList, Tk.Frame):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
503 def __init__(self, master, filename):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
504 CueList.__init__(self, filename)
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
505 Tk.Frame.__init__(self, master, bg='black')
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
506 self.fader = None
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
507
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
508 self.edit_tl = Tk.Toplevel()
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
509 self.editor = CueEditron(self.edit_tl,
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
510 changed_callback=self.cue_changed)
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
511 self.editor.pack(fill='both', expand=1)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
512
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
513 def edit_cue(index):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
514 index = int(index)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
515 self.editor.set_cue_to_edit(self.cues[index])
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
516
181
ccd635df77a9 - commit latest cue and sub changes
dmcc
parents: 179
diff changeset
517 self.columns = ('name', 'time', 'page', 'cuenum', 'desc', 'sub_levels')
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
518 self.scrolled_hlist = Tk.ScrolledHList(self,
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
519 options='hlist.columns %d hlist.header 1' % len(self.columns))
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
520 self.hlist = self.scrolled_hlist.hlist
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
521 self.hlist.configure(fg='white', bg='black',
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
522 command=self.select_callback, browsecmd=edit_cue)
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
523 self.hlist.bind("<4>", self.wheelscroll)
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
524 self.hlist.bind("<5>", self.wheelscroll)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
525 self.scrolled_hlist.pack(fill='both', expand=1)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
526
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
527 boldfont = self.tk.call('tix', 'option', 'get',
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
528 'bold_font')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
529 header_style = Tk.DisplayStyle('text', refwindow=self,
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
530 anchor='center', padx=8, pady=2, font=boldfont)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
531
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
532 for count, header in enumerate(self.columns):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
533 self.hlist.header_create(count, itemtype='text',
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
534 text=header, style=header_style)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
535
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
536 self.cue_label_windows = {}
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
537 for count, cue in enumerate(self.cues):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
538 self.display_cue(count, cue)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
539 self.update_cue_indicators()
185
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
540 self.save_loop()
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
541 def set_fader(self, fader):
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
542 self.fader = fader
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
543 def wheelscroll(self, evt):
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
544 """Perform mouse wheel scrolling"""
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
545 if evt.num == 4: # scroll down
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
546 amount = -2
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
547 else: # scroll up
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
548 amount = 2
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
549 self.hlist.yview('scroll', amount, 'units')
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
550 def cue_changed(self, cue):
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
551 path = self.cues.index(cue)
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
552 for col, header in enumerate(self.columns):
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
553 try:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
554 text = getattr(cue, header)
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
555 except AttributeError:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
556 text = ''
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
557
163
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
558 if col == 0:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
559 self.cue_label_windows[path]['text'] = text
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
560 else:
e0c227168519 - LabelledScales allow for optional formatters
dmcc
parents: 162
diff changeset
561 self.hlist.item_configure(path, col, text=text)
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
562
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
563 if cue in self.get_current_cues() and self.fader:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
564 self.fader.update_cue_cache()
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
565 self.fader.reload_cue_times()
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
566 def display_cue(self, path, cue):
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
567 for col, header in enumerate(self.columns):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
568 try:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
569 text = getattr(cue, header)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
570 except AttributeError:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
571 text = ''
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
572
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
573 if col == 0:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
574 lab = Tk.Label(self.hlist, text=text, fg='white', bg='black')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
575 def select_and_highlight(event):
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
576 self.select_callback(path)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
577 self.hlist.selection_clear()
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
578 self.hlist.selection_set(path)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
579
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
580 lab.bind("<Double-1>", select_and_highlight)
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
581 self.hlist.add(path, itemtype='window', window=lab)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
582 self.cue_label_windows[path] = lab
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
583 else:
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
584 self.hlist.item_create(path, col, text=text)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
585 def reset_cue_indicators(self, cue_indices=None):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
586 """If cue_indices is None, we'll reset all of them."""
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
587 cue_indices = cue_indices or self.cue_label_windows.keys()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
588 for key in cue_indices:
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
589 if key is None:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
590 continue
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
591 window = self.cue_label_windows[key]
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
592 window.configure(fg='white', bg='black')
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
593 def update_cue_indicators(self):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
594 states = dict(zip(self.get_current_cue_indices(),
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
595 ('prev', 'cur', 'next')))
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
596
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
597 for count, state in states.items():
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
598 if count is None:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
599 continue
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
600 window = self.cue_label_windows[count]
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
601 bg, fg = cue_state_indicator_colors[state]
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
602 window.configure(bg=bg, fg=fg)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
603 def shift(self, diff):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
604 self.reset_cue_indicators(self.get_current_cue_indices())
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
605 CueList.shift(self, diff)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
606 self.update_cue_indicators()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
607 # try to see all indices, but next takes priority over all, and cur
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
608 # over prev
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
609 for index in self.get_current_cue_indices():
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
610 if index is not None:
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
611 self.hlist.see(index)
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
612 def select_callback(self, index):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
613 new_next = int(index)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
614 self.set_next(new_next)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
615 def set_next(self, index):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
616 prev, cur, next = self.get_current_cue_indices()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
617 self.reset_cue_indicators((next,))
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
618 CueList.set_next(self, index)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
619 self.update_cue_indicators()
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
620
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
621 if self.fader: # XXX this is untested
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
622 self.fader.update_cue_cache()
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
623 def set_prev(self, index):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
624 prev, cur, next = self.get_current_cue_indices()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
625 self.reset_cue_indicators((prev,))
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
626 CueList.set_prev(self, index)
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
627 self.update_cue_indicators()
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
628
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
629 if self.fader: # XXX this is untested
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
630 self.fader.update_cue_cache()
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
631 def set_selection_as_prev(self):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
632 sel = self.hlist.info_selection()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
633 if sel:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
634 self.set_prev(int(sel[0]))
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
635 def set_selection_as_next(self):
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
636 sel = self.hlist.info_selection()
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
637 if sel:
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
638 self.set_next(int(sel[0]))
185
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
639 def save_loop(self):
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
640 """This saves the CueList every minute."""
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
641 self.save(backup=1)
74a34c677588 now with autosave
dmcc
parents: 181
diff changeset
642 self.after(60000, self.save_loop)
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
643
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
644 class CueEditron(Tk.Frame):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
645 def __init__(self, master, changed_callback=None, cue=None):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
646 Tk.Frame.__init__(self, master, bg='black')
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
647 self.master = master
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
648 self.cue = cue
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
649 self.changed_callback = changed_callback
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
650 self.enable_callbacks = 1
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
651
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
652 self.setup_editing_forms()
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
653 self.set_cue_to_edit(cue)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
654 def set_cue_to_edit(self, cue):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
655 if cue != self.cue:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
656 self.cue = cue
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
657 self.fill_in_cue_info()
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
658 self.set_title()
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
659 def set_title(self):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
660 try:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
661 self.master.title("Editing '%s'" % self.cue.name)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
662 except AttributeError:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
663 pass
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
664 def setup_editing_forms(self):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
665 self.variables = {}
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
666 for row, field in enumerate(('name', 'time', 'page', 'cuenum', 'desc',
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
667 'sub_levels')):
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
668 lab = Tk.Label(self, text=field, fg='white', bg='black')
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
669 lab.grid(row=row, column=0, sticky='nsew')
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
670
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
671 entryvar = Tk.StringVar()
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
672 entry = Tk.Entry(self, fg='white', bg='black',
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
673 textvariable=entryvar, insertbackground='white',
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
674 highlightcolor='red') # TODO this red/black is backwards
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
675 entry.grid(row=row, column=1, sticky='nsew')
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
676
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
677 self.variables[field] = entryvar
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
678
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
679 def field_changed(x, y, z, field=field, entryvar=entryvar):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
680 if self.cue:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
681 setattr(self.cue, field, entryvar.get())
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
682 if self.enable_callbacks and self.changed_callback:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
683 self.changed_callback(self.cue)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
684 if field == 'name':
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
685 self.set_title()
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
686
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
687 entryvar.trace('w', field_changed)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
688 self.columnconfigure(1, weight=1)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
689 def fill_in_cue_info(self):
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
690 self.enable_callbacks = 0
176
c8d24bd2a99e CueFaders: autoload/shifting bug fixed
dmcc
parents: 171
diff changeset
691 for row, field in enumerate(('name', 'time', 'page', 'cuenum', 'desc',
168
f8b5cb5fbeed - CueFader is hopefully done:
dmcc
parents: 167
diff changeset
692 'sub_levels')):
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
693 text = ''
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
694 if self.cue:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
695 try:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
696 text = getattr(self.cue, field)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
697 except AttributeError:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
698 pass
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
699 self.variables[field].set(text)
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
700 self.enable_callbacks = 1
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
701
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
702 if __name__ == "__main__":
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
703 root = Tk.Tk()
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
704 root.title("ShowMaster 9000")
178
e9c06be9b26b more updates, some bugfixes (hopefully!)
dmcc
parents: 176
diff changeset
705 root.geometry("600x670")
171
ba83a312d8b1 use the new dolly cuelist
dmcc
parents: 168
diff changeset
706 cl = TkCueList(root, 'cues/dolly')
161
0803fb42109d we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents: 158
diff changeset
707 cl.pack(fill='both', expand=1)
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
708
157
7d3a0f9107a8 try to resolve version conflict problems
dmcc
parents: 155
diff changeset
709 fader = CueFader(root, cl)
7d3a0f9107a8 try to resolve version conflict problems
dmcc
parents: 155
diff changeset
710 fader.pack(fill='both', expand=1)
162
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
711 try:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
712 Tk.mainloop()
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
713 except KeyboardInterrupt:
6c5753bad783 basic cue editing, darker colors, fade time selector is now a "TixControl"
dmcc
parents: 161
diff changeset
714 root.destroy()