0
|
1 from Tix import *
|
52
|
2 from time import time # time is on my side
|
|
3 from util import subsetdict
|
53
|
4 from FlyingFader import FlyingFader
|
52
|
5
|
|
6 # statuses are:
|
53
|
7 # stopped - no cue is loaded or cue is stopped
|
52
|
8 # running - cue is running, not complete
|
|
9 # finished - cue is finished, next is loaded
|
0
|
10
|
|
11 stdfont = ('Arial', 10)
|
|
12
|
54
|
13 def get_selection(listbox):
|
|
14 'Given a listbox, returns first selection as integer'
|
|
15 selection = int(listbox.curselection()[0]) # blech
|
|
16 return selection
|
|
17
|
0
|
18 class Fader(Frame):
|
|
19 'User interface for cue fader'
|
|
20 def __init__(self, master, cues, scalelevels):
|
|
21 self.master = master
|
|
22 self.cues = cues
|
|
23 self.scalelevels = scalelevels
|
53
|
24 self.time_start = 0
|
0
|
25 self.init_layout()
|
53
|
26 self.stop()
|
0
|
27 def init_layout(self):
|
|
28 Frame.__init__(self, self.master)
|
|
29
|
52
|
30 # info variables
|
0
|
31 self.cuename = StringVar()
|
|
32 self.cuelength = DoubleVar()
|
52
|
33 self.cuetarget = StringVar()
|
|
34
|
|
35 # info about a running cue
|
|
36 self.cuestatus = StringVar() # text description
|
|
37 self.cuestatus.set("stopped")
|
|
38
|
|
39 self.cuepercent = DoubleVar() # percent complete
|
|
40 self.cuepercent.set(0)
|
53
|
41 self.cuepercent.trace('w', self.update_percent)
|
|
42 self.cuetimeelapse = StringVar() # time elapsed
|
|
43 self.cuetimeelapse.set('0s')
|
|
44 self.cuetimeleft = StringVar() # time left
|
|
45 self.cuetimeleft.set('0s')
|
0
|
46
|
|
47 buttonframe = Frame(self)
|
54
|
48 topframe = Frame(self) # to contain cue list and infoframe
|
|
49 infoframe = Frame(topframe)
|
|
50 topframe.pack()
|
0
|
51
|
54
|
52 self.listbox = ScrolledListBox(topframe,
|
53
|
53 command=self.update_selection)
|
|
54 self.listbox.listbox.configure({'exportselection' : 0,
|
|
55 'selectmode' : EXTENDED})
|
0
|
56 for c in self.cues:
|
|
57 self.listbox.listbox.insert(END, c.name)
|
54
|
58 self.listbox.pack(side=LEFT)
|
53
|
59 self.listbox.listbox.bind("<<ListboxSelect>>", self.update_selection,
|
|
60 add=1)
|
|
61 Button(buttonframe, text="Go", command=self.go, font=stdfont,
|
|
62 bg='green').pack(side=LEFT)
|
|
63 Button(buttonframe, text="Stop", command=self.stop, font=stdfont,
|
|
64 bg='red').pack(side=LEFT)
|
|
65 Button(buttonframe, text="Prev", command=self.prev,
|
|
66 font=stdfont).pack(side=LEFT)
|
54
|
67 nextbutton = Button(buttonframe, text="Next", command=self.next,
|
|
68 font=stdfont)
|
|
69 # Button(buttonframe, text="Load", command=self.mark_start, bg='grey80',
|
|
70 # font=stdfont).pack(side=LEFT)
|
0
|
71
|
|
72 Label(infoframe, textvariable=self.cuename,
|
53
|
73 font=('Arial', 12), bg='lightBlue').grid(columnspan=4, sticky=NE+SW)
|
52
|
74
|
0
|
75 Label(infoframe, text="Length", font=stdfont,
|
|
76 bg='lightPink').grid(row=1, sticky=NE+SW)
|
|
77 Label(infoframe, textvariable=self.cuelength,
|
53
|
78 font=stdfont).grid(row=1, column=1, columnspan=3, sticky=NE+SW)
|
52
|
79
|
0
|
80 Label(infoframe, text="Target", font=stdfont,
|
54
|
81 bg='lightPink').grid(row=2, sticky=NE+SW)
|
52
|
82 Label(infoframe, textvariable=self.cuetarget,
|
54
|
83 font=stdfont, wraplength=250).grid(row=2, column=1, columnspan=3,
|
|
84 sticky=NE+SW)
|
52
|
85
|
|
86 Label(infoframe, text="Status", font=stdfont,
|
|
87 bg='lightPink').grid(row=3, sticky=NE+SW)
|
|
88 Label(infoframe, textvariable=self.cuestatus,
|
53
|
89 font=stdfont).grid(row=3, column=1, columnspan=3, sticky=NE+SW)
|
52
|
90
|
53
|
91 Label(infoframe, text="Time Elapsed", font=stdfont,
|
52
|
92 bg='lightPink').grid(row=4, sticky=NE+SW)
|
53
|
93 Label(infoframe, textvariable=self.cuetimeelapse,
|
52
|
94 font=stdfont).grid(row=4, column=1, sticky=NE+SW)
|
|
95
|
53
|
96 Label(infoframe, text="Time Remain", font=stdfont,
|
|
97 bg='lightPink').grid(row=4, column=2, sticky=NE+SW)
|
|
98 Label(infoframe, textvariable=self.cuetimeleft,
|
|
99 font=stdfont).grid(row=4, column=3, sticky=NE+SW)
|
|
100
|
52
|
101 Label(infoframe, text="Percent Complete", font=stdfont,
|
53
|
102 bg='lightPink').grid(row=5, column=0, sticky=NE+SW)
|
|
103 self.percentlabel = Label(infoframe,
|
|
104 font=stdfont)
|
|
105 self.percentlabel.grid(row=5, column=1, columnspan=3, sticky=NE+SW)
|
|
106
|
54
|
107 # s = Scale(infoframe, variable=self.cuepercent,
|
|
108 s = Scale(buttonframe, variable=self.cuepercent,
|
53
|
109 showvalue=0, length=220,
|
|
110 width=18, sliderlength=30,
|
|
111 to=100,res=.1,from_=0,bd=1, font=stdfont,
|
|
112 orient='horiz')
|
54
|
113 # s.grid(row=6, columnspan=4, sticky='ew')
|
|
114 nextbutton.pack(side=RIGHT)
|
|
115 s.pack(side=RIGHT, expand=1, fill=X)
|
52
|
116
|
0
|
117 infoframe.pack(side=RIGHT, fill=BOTH, expand=1)
|
54
|
118 buttonframe.pack(side=BOTTOM, expand=1, fill=X)
|
0
|
119
|
|
120 self.listbox.listbox.select_set(0)
|
|
121 self.update_selection()
|
54
|
122 def mark_start(self):
|
|
123 self.time_start = time()
|
|
124 startlevels = dict([(k, v.get()) for k, v in self.scalelevels.items()])
|
|
125 # print "going to mark with", startlevels
|
|
126 self.current.start(startlevels, self.time_start)
|
53
|
127 def update_percent(self, *args):
|
|
128 if self.cuestatus.get() != 'running':
|
|
129 self.cuestatus.set("running")
|
54
|
130 self.mark_start()
|
53
|
131
|
|
132 percent = self.cuepercent.get()
|
|
133 self.percentlabel.config(text='%.1f%%' % percent)
|
|
134 percent /= 100
|
|
135
|
|
136 elapsed = percent * self.current.dur
|
|
137 self.cuetimeelapse.set('%.1fs' % elapsed)
|
|
138 self.cuetimeleft.set('%.1fs' % (self.current.dur - elapsed))
|
54
|
139
|
53
|
140 newlevels = self.current.get_levels(self.time_start + elapsed)
|
54
|
141 # print "newlevels", newlevels
|
53
|
142 for ch, lev in newlevels.items():
|
|
143 try:
|
54
|
144 self.scalelevels[ch].set(lev)
|
53
|
145 except KeyError:
|
|
146 pass
|
|
147
|
|
148 def update_selection(self, *args):
|
54
|
149 self.cuestatus.set('stopped')
|
|
150 selection = get_selection(self.listbox.listbox)
|
0
|
151 self.current = self.cues[selection]
|
|
152 self.cuename.set(self.current.name)
|
|
153 self.cuelength.set(self.current.dur)
|
54
|
154 target = ', '.join(['%s -> %.2f' % (n, lev)
|
53
|
155 for n, lev in self.current.get_end_levels().items()])
|
|
156 self.cuetarget.set(target)
|
|
157 self.cuetimeelapse.set('0s')
|
|
158 self.cuetimeleft.set('%.1fs' % self.current.dur)
|
|
159 self.cuepercent.set(0)
|
0
|
160 def go(self):
|
53
|
161 self.update_selection()
|
52
|
162 self.cuestatus.set("running")
|
54
|
163 self.mark_start()
|
52
|
164 self.running_loop()
|
53
|
165 def stop(self):
|
|
166 self.cuestatus.set('stopped')
|
|
167 def prev(self):
|
54
|
168 self.stop()
|
|
169 selection = get_selection(self.listbox.listbox)
|
53
|
170 if selection != 0:
|
|
171 self.listbox.listbox.select_clear(selection)
|
|
172 self.listbox.listbox.select_set(selection - 1)
|
|
173 self.update_selection()
|
54
|
174 self.mark_start()
|
53
|
175 def next(self):
|
54
|
176 self.stop()
|
|
177 selection = get_selection(self.listbox.listbox)
|
53
|
178 if selection != self.listbox.listbox.size() - 1:
|
|
179 self.listbox.listbox.select_clear(selection)
|
|
180 self.listbox.listbox.select_set(selection + 1)
|
|
181 self.update_selection()
|
54
|
182 self.mark_start()
|
52
|
183 def running_loop(self):
|
53
|
184 if self.cuestatus.get() == 'stopped':
|
52
|
185 return
|
53
|
186 curtime = time()
|
|
187 elapsed = (curtime - self.time_start)
|
54
|
188
|
53
|
189 if elapsed > self.current.dur:
|
54
|
190 self.cuestatus.set('stopped')
|
53
|
191 self.cuepercent.set(100)
|
|
192
|
|
193 # advance cues if okay
|
|
194 self.next()
|
|
195 return
|
|
196
|
|
197 self.cuepercent.set(100 * elapsed / self.current.dur)
|
52
|
198 self.after(30, self.running_loop)
|