Mercurial > code > home > repos > light9
annotate flax/CueFaders.py @ 161:0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
we now have TkCueList, which is really cool. it doesn't provide editing
yet, but you could almost nearly probably maybe run a show with it.
heck, i hope so.
some of the shifting/drawing problems were probably fixed.
cuelist1 got more bogus data to help populate the TkCueList.
author | dmcc |
---|---|
date | Mon, 07 Jul 2003 17:18:26 +0000 |
parents | 5c7ac46e33d3 |
children | 6c5753bad783 |
rev | line source |
---|---|
0 | 1 from __future__ import division, nested_scopes |
2 import Tix as Tk | |
3 import time | |
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 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
6 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
7 cue_state_indicator_colors = { |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
8 # bg fg |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
9 'prev' : ('blue', 'white'), |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
10 'cur' : ('yellow', 'black'), |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
11 'next' : ('red', 'white'), |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
12 } |
0 | 13 |
14 class LabelledScale(Tk.Frame): | |
15 """Scale with two labels: a name and current value""" | |
16 def __init__(self, master, label, **opts): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
17 Tk.Frame.__init__(self, master, bd=2, relief='raised') |
0 | 18 opts.setdefault('variable', Tk.DoubleVar()) |
19 opts.setdefault('showvalue', 0) | |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
20 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
21 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
|
22 self.flashtrough = opts.get('flashtroughcolor', 'red') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
23 del opts['flashtroughcolor'] |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
24 |
0 | 25 self.scale_var = opts['variable'] |
26 self.scale = Tk.Scale(self, **opts) | |
27 self.scale.pack(side='top', expand=1, fill='both') | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
28 self.name = Tk.Label(self, text=label) |
0 | 29 self.name.pack(side='bottom') |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
30 self.scale_value = Tk.Label(self, width=6) |
0 | 31 self.scale_value.pack(side='bottom') |
32 self.scale_var.trace('w', self.update_value_label) | |
33 self.update_value_label() | |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
34 self.disabled = (self.scale['state'] == 'disabled') |
0 | 35 def set_label(self, label): |
36 self.name['text'] = label | |
37 def update_value_label(self, *args): | |
38 val = self.scale_var.get() * 100 | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
39 self.scale_value['text'] = "%0.2f" % val |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
40 if val != 0: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
41 self.scale['troughcolor'] = self.flashtrough |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
42 else: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
43 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
|
44 def disable(self): |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
45 if not self.disabled: |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
46 self.scale['state'] = 'disabled' |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
47 self.scale_var.set(0) |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
48 self.disabled = 1 |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
49 def enable(self): |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
50 if self.disabled: |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
51 self.scale['state'] = 'normal' |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
52 self.disabled = 0 |
0 | 53 |
54 class TimedGoButton(Tk.Frame): | |
55 """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
|
56 def __init__(self, master, name, scale_to_fade, **kw): |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
57 Tk.Frame.__init__(self, master) |
0 | 58 self.name = name |
59 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
|
60 self.button = Tk.Button(self, text=name, command=self.start_fade, **kw) |
0 | 61 self.button.pack(fill='both', expand=1, side='left') |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
62 self.timer_var = Tk.StringVar() |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
63 self.timer_entry = Tk.Entry(self, textvariable=self.timer_var, width=5) |
0 | 64 self.timer_entry.pack(fill='y', side='left') |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
65 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
|
66 self.disabled = (self.button['state'] == 'disabled') |
0 | 67 def start_fade(self, end_level=1): |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
68 try: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
69 fade_time = float(self.timer_var.get()) |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
70 except ValueError: |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
71 # TODO figure out how to handle this |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
72 print "can't fade -- bad time" |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
73 return |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
74 |
0 | 75 self.start_time = time.time() |
76 self.start_level = self.scale_to_fade.scale_var.get() | |
77 self.end_level = end_level | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
78 self.fade_length = fade_time |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
79 self.do_fade() |
0 | 80 def do_fade(self): |
81 diff = time.time() - self.start_time | |
82 if diff < self.fade_length: | |
83 percent = diff / self.fade_length | |
84 newlevel = self.start_level + \ | |
85 (percent * (self.end_level - self.start_level)) | |
86 self.scale_to_fade.scale_var.set(newlevel) | |
87 | |
88 if newlevel != self.end_level: | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
89 self.after(10, self.do_fade) |
0 | 90 else: |
91 self.scale_to_fade.scale_var.set(self.end_level) | |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
92 def disable(self): |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
93 if not self.disabled: |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
94 self.button['state'] = 'disabled' |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
95 self.disabled = 1 |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
96 def enable(self): |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
97 if self.disabled: |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
98 self.button['state'] = 'normal' |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
99 self.disabled = 0 |
0 | 100 |
101 class CueFader(Tk.Frame): | |
102 def __init__(self, master, cuelist): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
103 Tk.Frame.__init__(self, master) |
0 | 104 self.cuelist = cuelist |
155 | 105 self.auto_shift = Tk.IntVar() |
106 self.auto_shift.set(1) | |
0 | 107 |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
108 # 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
|
109 # 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
|
110 # 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
|
111 # 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
|
112 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
|
113 |
0 | 114 self.scales = {} |
115 self.shift_buttons = {} | |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
116 self.go_buttons = {} |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
117 |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
118 topframe = Tk.Frame(self) |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
119 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
120 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
|
121 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
|
122 fg='white', bg='blue') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
123 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
|
124 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
125 self.auto_shift_checkbutton = Tk.Checkbutton(topframe, |
155 | 126 variable=self.auto_shift, text='Autoshift', |
127 command=self.toggle_autoshift) | |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
128 self.auto_shift_checkbutton.pack(side='left') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
129 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
130 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
|
131 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
|
132 fg='white', bg='red') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
133 self.set_next_button.pack(side='left') |
155 | 134 |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
135 topframe.pack(side='top') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
136 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
137 faderframe = Tk.Frame(self) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
138 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
|
139 ('Next', 0, 1, 'right', 'red')) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
140 for name, start, end, side, color in self.direction_info: |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
141 frame = Tk.Frame(self) |
0 | 142 scale = LabelledScale(frame, name, from_=start, to_=end, |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
143 res=0.0001, orient='horiz', flashtroughcolor=color) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
144 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
|
145 go = TimedGoButton(frame, 'Go %s' % name, scale, bg=color, |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
146 fg='white') |
0 | 147 go.pack(fill='both', expand=1) |
148 frame.pack(side=side, fill='both', expand=1) | |
149 | |
155 | 150 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
|
151 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
|
152 bg='black') |
155 | 153 |
0 | 154 self.scales[name] = scale |
155 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
|
156 self.go_buttons[name] = go |
0 | 157 |
158 scale.scale_var.trace('w', \ | |
159 lambda x, y, z, name=name, scale=scale: self.xfade(name, scale)) | |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
160 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
161 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
|
162 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
|
163 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
|
164 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
|
165 self.autoshift(name, scale) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
166 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
167 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
|
168 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
|
169 faderframe.pack(side='bottom', fill='both', expand=1) |
155 | 170 def toggle_autoshift(self): |
171 for name, button in self.shift_buttons.items(): | |
172 if not self.auto_shift.get(): | |
173 button.pack(side='bottom', fill='both', expand=1) | |
174 else: | |
175 button.pack_forget() | |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
176 def shift(self, name): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
177 # to prevent overshifting |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
178 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
|
179 return |
155 | 180 |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
181 for scale_name, scale in self.scales.items(): |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
182 scale.scale.set(0) |
0 | 183 self.cuelist.shift((-1, 1)[name == 'Next']) |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
184 def autoshift(self, name, scale): |
0 | 185 scale_val = scale.scale_var.get() |
186 | |
187 if scale_val == 1: | |
155 | 188 if self.auto_shift.get(): |
0 | 189 self.shift(name) |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
190 def xfade(self, name, scale): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
191 if self.auto_shift.get(): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
192 self.autoshift(name, scale) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
193 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
|
194 else: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
195 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
|
196 if scale_val == 1: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
197 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
|
198 else: |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
199 # disable any dangerous shifting |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
200 self.shift_buttons[name]['state'] = 'disabled' |
0 | 201 |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
202 d = self.opposite_direction(name) |
0 | 203 if scale_val != 0: |
204 # 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
|
205 self.scales[d].disable() |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
206 self.go_buttons[d].disable() |
0 | 207 else: |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
208 # undo above work |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
209 self.scales[d].enable() |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
210 self.go_buttons[d].enable() |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
211 def opposite_direction(self, d): |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
212 if d == 'Next': |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
213 return 'Prev' |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
214 else: |
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
215 return 'Next' |
0 | 216 |
217 class Cue: | |
218 """A Cue has a name, a time, and any number of other attributes.""" | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
219 def __init__(self, name, time=3, **attrs): |
0 | 220 self.name = name |
221 self.time = time | |
222 self.__dict__.update(attrs) | |
223 def __repr__(self): | |
224 return "<Cue %s, length %s>" % (self.name, self.time) | |
225 | |
226 empty_cue = Cue('empty') | |
227 | |
228 allow_class_to_be_pickled(Cue) | |
229 | |
230 class CueList: | |
231 """Persistent list of Cues""" | |
232 def __init__(self, filename): | |
233 self.filename = filename | |
234 self.treedict = TreeDict() | |
235 try: | |
236 self.treedict.load(filename) | |
237 except IOError: | |
238 self.treedict.cues = [] | |
239 self.cues = self.treedict.cues | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
240 self.current_cue_index = 0 |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
241 self.next_pointer = None |
0 | 242 self.prev_pointer = None |
243 | |
244 import atexit | |
245 atexit.register(self.save) | |
246 def add_cue(self, cue, index=None): | |
247 """Adds a Cue object to the list. If no index is specified, | |
248 the cue will be added to the end.""" | |
249 index = index or len(self.cues) | |
250 self.cues.insert(index, cue) | |
251 def shift(self, diff): | |
252 """Shift through cue history""" | |
253 old_index = self.current_cue_index | |
254 self.current_cue_index = None | |
255 if diff < 0: # if going backwards | |
256 if self.prev_pointer: # use a prev pointer if we have one | |
257 self.current_cue_index = self.prev_pointer | |
258 self.next_pointer = old_index | |
259 self.prev_pointer = None | |
260 else: | |
261 if self.next_pointer: # use a next pointer if we have one | |
262 self.current_cue_index = self.next_pointer | |
263 self.next_pointer = None | |
264 self.prev_pointer = old_index | |
265 if not self.current_cue_index: | |
266 self.current_cue_index = old_index + diff | |
267 def set_next(self, index): | |
268 self.next_pointer = index | |
269 def set_prev(self, index): | |
270 self.prev_pointer = index | |
271 def bound_index(self, index): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
272 if not self.cues: |
0 | 273 return None |
274 else: | |
158
5c7ac46e33d3
more disabling of stuff that make no sense at certain times and some
dmcc
parents:
157
diff
changeset
|
275 return max(0, min(index, len(self.cues) - 1)) |
0 | 276 def get_current_cue_indices(self): |
277 cur = self.current_cue_index | |
278 return [self.bound_index(index) for index in | |
279 (self.prev_pointer or cur - 1, | |
280 cur, | |
281 self.next_pointer or cur + 1)] | |
282 def get_current_cues(self): | |
283 return [self.get_cue_by_index(index) | |
284 for index in self.get_current_cue_indices()] | |
285 def get_cue_by_index(self, index): | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
286 if index: |
0 | 287 return self.cues[self.bound_index(index)] |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
288 else: |
0 | 289 return empty_cue |
290 def __del__(self): | |
291 self.save() | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
292 def save(self): |
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
293 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
|
294 def reload(self): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
295 # 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
|
296 # sense, etc. |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
297 self.treedict.load(self.filename) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
298 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
299 class TkCueList(CueList, Tk.Frame): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
300 def __init__(self, master, filename): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
301 CueList.__init__(self, filename) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
302 Tk.Frame.__init__(self, master) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
303 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
304 self.columns = ('name', 'time', 'page', 'desc') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
305 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
306 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
|
307 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
|
308 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
|
309 self.hlist.configure(fg='white', bg='black', |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
310 command=self.select_callback) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
311 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
|
312 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
313 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
|
314 'bold_font') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
315 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
|
316 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
|
317 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
318 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
|
319 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
|
320 text=header, style=header_style) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
321 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
322 self.cue_label_windows = {} |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
323 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
|
324 self.display_cue(count, cue) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
325 self.update_cue_indicators() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
326 def display_cue(self, cue_count, cue): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
327 # cue_count is the path in the hlist -- this probably isn't ideal |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
328 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
|
329 try: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
330 text = getattr(cue, header) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
331 except AttributeError: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
332 text = '' |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
333 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
334 if col == 0: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
335 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
|
336 def select_and_highlight(event): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
337 self.select_callback(cue_count) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
338 self.hlist.selection_clear() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
339 self.hlist.selection_set(cue_count) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
340 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
341 lab.bind("<Double-1>", select_and_highlight) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
342 self.hlist.add(cue_count, itemtype='window', window=lab) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
343 self.cue_label_windows[cue_count] = lab |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
344 else: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
345 self.hlist.item_create(cue_count, col, text=text) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
346 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
|
347 """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
|
348 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
|
349 for key in cue_indices: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
350 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
|
351 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
|
352 def update_cue_indicators(self): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
353 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
|
354 ('prev', 'cur', 'next'))) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
355 |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
356 for count, state in states.items(): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
357 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
|
358 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
|
359 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
|
360 def shift(self, diff): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
361 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
|
362 CueList.shift(self, diff) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
363 self.update_cue_indicators() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
364 # 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
|
365 # over prev |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
366 for index in self.get_current_cue_indices(): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
367 self.hlist.see(index) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
368 def select_callback(self, index): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
369 new_next = int(index) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
370 self.set_next(new_next) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
371 def set_next(self, index): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
372 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
|
373 self.reset_cue_indicators((next,)) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
374 CueList.set_next(self, index) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
375 self.update_cue_indicators() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
376 def set_prev(self, index): |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
377 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
|
378 self.reset_cue_indicators((prev,)) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
379 CueList.set_prev(self, index) |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
380 self.update_cue_indicators() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
381 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
|
382 sel = self.hlist.info_selection() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
383 if sel: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
384 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
|
385 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
|
386 sel = self.hlist.info_selection() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
387 if sel: |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
388 self.set_next(int(sel[0])) |
0 | 389 |
390 if __name__ == "__main__": | |
161
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
391 root = Tk.Tk() |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
392 cl = TkCueList(root, 'cues/cuelist1') |
0803fb42109d
we now have TkCueList, which is really cool. it doesn't provide editing
dmcc
parents:
158
diff
changeset
|
393 cl.pack(fill='both', expand=1) |
0 | 394 |
157 | 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)) | |
151
990a9474d0e7
early cue stuff. the CueList will supply the CueFader with the cues to
dmcc
parents:
0
diff
changeset
|
399 |
157 | 400 fader = CueFader(root, cl) |
401 fader.pack(fill='both', expand=1) | |
402 Tk.mainloop() |